Merge remote-tracking branch 'upstream' into next
[cascardo/linux.git] / drivers / gpu / drm / gma500 / oaktrail_hdmi.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *      Li Peng <peng.li@intel.com>
25  */
26
27 #include <drm/drmP.h>
28 #include <drm/drm.h>
29 #include "psb_intel_drv.h"
30 #include "psb_intel_reg.h"
31 #include "psb_drv.h"
32
33 #define HDMI_READ(reg)          readl(hdmi_dev->regs + (reg))
34 #define HDMI_WRITE(reg, val)    writel(val, hdmi_dev->regs + (reg))
35
36 #define HDMI_HCR        0x1000
37 #define HCR_ENABLE_HDCP         (1 << 5)
38 #define HCR_ENABLE_AUDIO        (1 << 2)
39 #define HCR_ENABLE_PIXEL        (1 << 1)
40 #define HCR_ENABLE_TMDS         (1 << 0)
41
42 #define HDMI_HICR       0x1004
43 #define HDMI_HSR        0x1008
44 #define HDMI_HISR       0x100C
45 #define HDMI_DETECT_HDP         (1 << 0)
46
47 #define HDMI_VIDEO_REG  0x3000
48 #define HDMI_UNIT_EN            (1 << 7)
49 #define HDMI_MODE_OUTPUT        (1 << 0)
50 #define HDMI_HBLANK_A   0x3100
51
52 #define HDMI_AUDIO_CTRL 0x4000
53 #define HDMI_ENABLE_AUDIO       (1 << 0)
54
55 #define PCH_HTOTAL_B    0x3100
56 #define PCH_HBLANK_B    0x3104
57 #define PCH_HSYNC_B     0x3108
58 #define PCH_VTOTAL_B    0x310C
59 #define PCH_VBLANK_B    0x3110
60 #define PCH_VSYNC_B     0x3114
61 #define PCH_PIPEBSRC    0x311C
62
63 #define PCH_PIPEB_DSL   0x3800
64 #define PCH_PIPEB_SLC   0x3804
65 #define PCH_PIPEBCONF   0x3808
66 #define PCH_PIPEBSTAT   0x3824
67
68 #define CDVO_DFT        0x5000
69 #define CDVO_SLEWRATE   0x5004
70 #define CDVO_STRENGTH   0x5008
71 #define CDVO_RCOMP      0x500C
72
73 #define DPLL_CTRL       0x6000
74 #define DPLL_PDIV_SHIFT         16
75 #define DPLL_PDIV_MASK          (0xf << 16)
76 #define DPLL_PWRDN              (1 << 4)
77 #define DPLL_RESET              (1 << 3)
78 #define DPLL_FASTEN             (1 << 2)
79 #define DPLL_ENSTAT             (1 << 1)
80 #define DPLL_DITHEN             (1 << 0)
81
82 #define DPLL_DIV_CTRL   0x6004
83 #define DPLL_CLKF_MASK          0xffffffc0
84 #define DPLL_CLKR_MASK          (0x3f)
85
86 #define DPLL_CLK_ENABLE 0x6008
87 #define DPLL_EN_DISP            (1 << 31)
88 #define DPLL_SEL_HDMI           (1 << 8)
89 #define DPLL_EN_HDMI            (1 << 1)
90 #define DPLL_EN_VGA             (1 << 0)
91
92 #define DPLL_ADJUST     0x600C
93 #define DPLL_STATUS     0x6010
94 #define DPLL_UPDATE     0x6014
95 #define DPLL_DFT        0x6020
96
97 struct intel_range {
98         int     min, max;
99 };
100
101 struct oaktrail_hdmi_limit {
102         struct intel_range vco, np, nr, nf;
103 };
104
105 struct oaktrail_hdmi_clock {
106         int np;
107         int nr;
108         int nf;
109         int dot;
110 };
111
112 #define VCO_MIN         320000
113 #define VCO_MAX         1650000
114 #define NP_MIN          1
115 #define NP_MAX          15
116 #define NR_MIN          1
117 #define NR_MAX          64
118 #define NF_MIN          2
119 #define NF_MAX          4095
120
121 static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
122         .vco = { .min = VCO_MIN,                .max = VCO_MAX },
123         .np  = { .min = NP_MIN,                 .max = NP_MAX  },
124         .nr  = { .min = NR_MIN,                 .max = NR_MAX  },
125         .nf  = { .min = NF_MIN,                 .max = NF_MAX  },
126 };
127
128 static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
129 {
130         struct drm_psb_private *dev_priv = dev->dev_private;
131         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
132
133         HDMI_WRITE(HDMI_HCR, 0x67);
134         HDMI_READ(HDMI_HCR);
135
136         HDMI_WRITE(0x51a8, 0x10);
137         HDMI_READ(0x51a8);
138
139         HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
140         HDMI_READ(HDMI_AUDIO_CTRL);
141 }
142
143 static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
144 {
145         struct drm_psb_private *dev_priv = dev->dev_private;
146         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
147
148         HDMI_WRITE(0x51a8, 0x0);
149         HDMI_READ(0x51a8);
150
151         HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
152         HDMI_READ(HDMI_AUDIO_CTRL);
153
154         HDMI_WRITE(HDMI_HCR, 0x47);
155         HDMI_READ(HDMI_HCR);
156 }
157
158 static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
159 {
160         static int dpms_mode = -1;
161
162         struct drm_device *dev = encoder->dev;
163         struct drm_psb_private *dev_priv = dev->dev_private;
164         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
165         u32 temp;
166
167         if (dpms_mode == mode)
168                 return;
169
170         if (mode != DRM_MODE_DPMS_ON)
171                 temp = 0x0;
172         else
173                 temp = 0x99;
174
175         dpms_mode = mode;
176         HDMI_WRITE(HDMI_VIDEO_REG, temp);
177 }
178
179 static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
180                                 struct drm_display_mode *mode)
181 {
182         if (mode->clock > 165000)
183                 return MODE_CLOCK_HIGH;
184         if (mode->clock < 20000)
185                 return MODE_CLOCK_LOW;
186
187         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
188                 return MODE_NO_DBLESCAN;
189
190         return MODE_OK;
191 }
192
193 static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder,
194                                  const struct drm_display_mode *mode,
195                                  struct drm_display_mode *adjusted_mode)
196 {
197         return true;
198 }
199
200 static enum drm_connector_status
201 oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
202 {
203         enum drm_connector_status status;
204         struct drm_device *dev = connector->dev;
205         struct drm_psb_private *dev_priv = dev->dev_private;
206         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
207         u32 temp;
208
209         temp = HDMI_READ(HDMI_HSR);
210         DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
211
212         if ((temp & HDMI_DETECT_HDP) != 0)
213                 status = connector_status_connected;
214         else
215                 status = connector_status_disconnected;
216
217         return status;
218 }
219
220 static const unsigned char raw_edid[] = {
221         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
222         0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
223         0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
224         0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
225         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
226         0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
227         0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
228         0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
229         0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
230         0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
231         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
232 };
233
234 static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
235 {
236         struct drm_device *dev = connector->dev;
237         struct drm_psb_private *dev_priv = dev->dev_private;
238         struct i2c_adapter *i2c_adap;
239         struct edid *edid;
240         struct drm_display_mode *mode, *t;
241         int i = 0, ret = 0;
242
243         i2c_adap = i2c_get_adapter(3);
244         if (i2c_adap == NULL) {
245                 DRM_ERROR("No ddc adapter available!\n");
246                 edid = (struct edid *)raw_edid;
247         } else {
248                 edid = (struct edid *)raw_edid;
249                 /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
250         }
251
252         if (edid) {
253                 drm_mode_connector_update_edid_property(connector, edid);
254                 ret = drm_add_edid_modes(connector, edid);
255                 connector->display_info.raw_edid = NULL;
256         }
257
258         /*
259          * prune modes that require frame buffer bigger than stolen mem
260          */
261         list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
262                 if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) {
263                         i++;
264                         drm_mode_remove(connector, mode);
265                 }
266         }
267         return ret - i;
268 }
269
270 static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
271                                struct drm_display_mode *mode,
272                                struct drm_display_mode *adjusted_mode)
273 {
274         struct drm_device *dev = encoder->dev;
275
276         oaktrail_hdmi_audio_enable(dev);
277         return;
278 }
279
280 static void oaktrail_hdmi_destroy(struct drm_connector *connector)
281 {
282         return;
283 }
284
285 static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
286         .dpms = oaktrail_hdmi_dpms,
287         .mode_fixup = oaktrail_hdmi_mode_fixup,
288         .prepare = psb_intel_encoder_prepare,
289         .mode_set = oaktrail_hdmi_mode_set,
290         .commit = psb_intel_encoder_commit,
291 };
292
293 static const struct drm_connector_helper_funcs
294                                         oaktrail_hdmi_connector_helper_funcs = {
295         .get_modes = oaktrail_hdmi_get_modes,
296         .mode_valid = oaktrail_hdmi_mode_valid,
297         .best_encoder = psb_intel_best_encoder,
298 };
299
300 static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
301         .dpms = drm_helper_connector_dpms,
302         .detect = oaktrail_hdmi_detect,
303         .fill_modes = drm_helper_probe_single_connector_modes,
304         .destroy = oaktrail_hdmi_destroy,
305 };
306
307 static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
308 {
309         drm_encoder_cleanup(encoder);
310 }
311
312 static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
313         .destroy = oaktrail_hdmi_enc_destroy,
314 };
315
316 void oaktrail_hdmi_init(struct drm_device *dev,
317                                         struct psb_intel_mode_device *mode_dev)
318 {
319         struct psb_intel_encoder *psb_intel_encoder;
320         struct psb_intel_connector *psb_intel_connector;
321         struct drm_connector *connector;
322         struct drm_encoder *encoder;
323
324         psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
325         if (!psb_intel_encoder)
326                 return;
327
328         psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
329         if (!psb_intel_connector)
330                 goto failed_connector;
331
332         connector = &psb_intel_connector->base;
333         encoder = &psb_intel_encoder->base;
334         drm_connector_init(dev, connector,
335                            &oaktrail_hdmi_connector_funcs,
336                            DRM_MODE_CONNECTOR_DVID);
337
338         drm_encoder_init(dev, encoder,
339                          &oaktrail_hdmi_enc_funcs,
340                          DRM_MODE_ENCODER_TMDS);
341
342         psb_intel_connector_attach_encoder(psb_intel_connector,
343                                            psb_intel_encoder);
344
345         psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
346         drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
347         drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
348
349         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
350         connector->interlace_allowed = false;
351         connector->doublescan_allowed = false;
352         drm_sysfs_connector_add(connector);
353
354         return;
355
356 failed_connector:
357         kfree(psb_intel_encoder);
358 }
359
360 static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
361         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
362         { 0 }
363 };
364
365 void oaktrail_hdmi_setup(struct drm_device *dev)
366 {
367         struct drm_psb_private *dev_priv = dev->dev_private;
368         struct pci_dev *pdev;
369         struct oaktrail_hdmi_dev *hdmi_dev;
370         int ret;
371
372         pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
373         if (!pdev)
374                 return;
375
376         hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
377         if (!hdmi_dev) {
378                 dev_err(dev->dev, "failed to allocate memory\n");
379                 goto out;
380         }
381
382
383         ret = pci_enable_device(pdev);
384         if (ret) {
385                 dev_err(dev->dev, "failed to enable hdmi controller\n");
386                 goto free;
387         }
388
389         hdmi_dev->mmio = pci_resource_start(pdev, 0);
390         hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
391         hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
392         if (!hdmi_dev->regs) {
393                 dev_err(dev->dev, "failed to map hdmi mmio\n");
394                 goto free;
395         }
396
397         hdmi_dev->dev = pdev;
398         pci_set_drvdata(pdev, hdmi_dev);
399
400         /* Initialize i2c controller */
401         ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
402         if (ret)
403                 dev_err(dev->dev, "HDMI I2C initialization failed\n");
404
405         dev_priv->hdmi_priv = hdmi_dev;
406         oaktrail_hdmi_audio_disable(dev);
407         return;
408
409 free:
410         kfree(hdmi_dev);
411 out:
412         return;
413 }
414
415 void oaktrail_hdmi_teardown(struct drm_device *dev)
416 {
417         struct drm_psb_private *dev_priv = dev->dev_private;
418         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
419         struct pci_dev *pdev;
420
421         if (hdmi_dev) {
422                 pdev = hdmi_dev->dev;
423                 pci_set_drvdata(pdev, NULL);
424                 oaktrail_hdmi_i2c_exit(pdev);
425                 iounmap(hdmi_dev->regs);
426                 kfree(hdmi_dev);
427                 pci_dev_put(pdev);
428         }
429 }
430
431 /* save HDMI register state */
432 void oaktrail_hdmi_save(struct drm_device *dev)
433 {
434         struct drm_psb_private *dev_priv = dev->dev_private;
435         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
436         struct psb_state *regs = &dev_priv->regs.psb;
437         struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
438         int i;
439
440         /* dpll */
441         hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
442         hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
443         hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
444         hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
445         hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
446
447         /* pipe B */
448         pipeb->conf = PSB_RVDC32(PIPEBCONF);
449         pipeb->src = PSB_RVDC32(PIPEBSRC);
450         pipeb->htotal = PSB_RVDC32(HTOTAL_B);
451         pipeb->hblank = PSB_RVDC32(HBLANK_B);
452         pipeb->hsync = PSB_RVDC32(HSYNC_B);
453         pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
454         pipeb->vblank = PSB_RVDC32(VBLANK_B);
455         pipeb->vsync = PSB_RVDC32(VSYNC_B);
456
457         hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
458         hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
459         hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
460         hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
461         hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
462         hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
463         hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
464         hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
465
466         /* plane */
467         pipeb->cntr = PSB_RVDC32(DSPBCNTR);
468         pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
469         pipeb->addr = PSB_RVDC32(DSPBBASE);
470         pipeb->surf = PSB_RVDC32(DSPBSURF);
471         pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
472         pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
473
474         /* cursor B */
475         regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
476         regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
477         regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
478
479         /* save palette */
480         for (i = 0; i < 256; i++)
481                 pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
482 }
483
484 /* restore HDMI register state */
485 void oaktrail_hdmi_restore(struct drm_device *dev)
486 {
487         struct drm_psb_private *dev_priv = dev->dev_private;
488         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
489         struct psb_state *regs = &dev_priv->regs.psb;
490         struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
491         int i;
492
493         /* dpll */
494         PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
495         PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
496         PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
497         PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
498         PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
499         DRM_UDELAY(150);
500
501         /* pipe */
502         PSB_WVDC32(pipeb->src, PIPEBSRC);
503         PSB_WVDC32(pipeb->htotal, HTOTAL_B);
504         PSB_WVDC32(pipeb->hblank, HBLANK_B);
505         PSB_WVDC32(pipeb->hsync,  HSYNC_B);
506         PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
507         PSB_WVDC32(pipeb->vblank, VBLANK_B);
508         PSB_WVDC32(pipeb->vsync,  VSYNC_B);
509
510         PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
511         PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
512         PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
513         PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
514         PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
515         PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
516         PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
517
518         PSB_WVDC32(pipeb->conf, PIPEBCONF);
519         PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
520
521         /* plane */
522         PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
523         PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
524         PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
525         PSB_WVDC32(pipeb->cntr, DSPBCNTR);
526         PSB_WVDC32(pipeb->surf, DSPBSURF);
527
528         /* cursor B */
529         PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
530         PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
531         PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
532
533         /* restore palette */
534         for (i = 0; i < 256; i++)
535                 PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
536 }