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 }
537