blob: c10899c953b9f9d9fb7ef84bb17335465c032cea [file] [log] [blame]
Alan Cox1b082cc2011-11-03 18:22:26 +00001/*
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
97struct intel_range {
98 int min, max;
99};
100
101struct oaktrail_hdmi_limit {
102 struct intel_range vco, np, nr, nf;
103};
104
105struct 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
121static 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
Alan Cox1b082cc2011-11-03 18:22:26 +0000128static 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
143static 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
Alan Cox1b082cc2011-11-03 18:22:26 +0000158static 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
Alan Cox1b082cc2011-11-03 18:22:26 +0000179static 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
193static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder,
194 struct drm_display_mode *mode,
195 struct drm_display_mode *adjusted_mode)
196{
197 return true;
198}
199
200static enum drm_connector_status
201oaktrail_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
220static 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
234static 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
270static 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
280static void oaktrail_hdmi_destroy(struct drm_connector *connector)
281{
282 return;
283}
284
285static 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
293static 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
300static 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
307static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
308{
309 drm_encoder_cleanup(encoder);
310}
311
312static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
313 .destroy = oaktrail_hdmi_enc_destroy,
314};
315
316void oaktrail_hdmi_init(struct drm_device *dev,
317 struct psb_intel_mode_device *mode_dev)
318{
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000319 struct psb_intel_encoder *psb_intel_encoder;
320 struct psb_intel_connector *psb_intel_connector;
Alan Cox1b082cc2011-11-03 18:22:26 +0000321 struct drm_connector *connector;
322 struct drm_encoder *encoder;
323
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000324 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
325 if (!psb_intel_encoder)
Alan Cox1b082cc2011-11-03 18:22:26 +0000326 return;
327
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000328 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,
Alan Cox1b082cc2011-11-03 18:22:26 +0000335 &oaktrail_hdmi_connector_funcs,
336 DRM_MODE_CONNECTOR_DVID);
337
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000338 drm_encoder_init(dev, encoder,
Alan Cox1b082cc2011-11-03 18:22:26 +0000339 &oaktrail_hdmi_enc_funcs,
340 DRM_MODE_ENCODER_TMDS);
341
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000342 psb_intel_connector_attach_encoder(psb_intel_connector,
343 psb_intel_encoder);
Alan Cox1b082cc2011-11-03 18:22:26 +0000344
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000345 psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
Alan Cox1b082cc2011-11-03 18:22:26 +0000346 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;
Patrik Jakobsson9bd81ac2011-12-19 21:41:33 +0000355
356failed_connector:
357 kfree(psb_intel_encoder);
Alan Cox1b082cc2011-11-03 18:22:26 +0000358}
359
360static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
361 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
Kirill A. Shutemov6e7f45732012-03-08 16:12:56 +0000362 { 0 }
Alan Cox1b082cc2011-11-03 18:22:26 +0000363};
364
365void 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
409free:
410 kfree(hdmi_dev);
411out:
412 return;
413}
414
415void 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 */
432void 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;
Alan Coxc6265ff2012-03-08 16:02:05 +0000436 struct psb_state *regs = &dev_priv->regs.psb;
Alan Cox62563042012-05-11 11:30:16 +0100437 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
Alan Cox1b082cc2011-11-03 18:22:26 +0000438 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 */
Alan Cox62563042012-05-11 11:30:16 +0100448 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);
Alan Cox1b082cc2011-11-03 18:22:26 +0000456
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 */
Alan Cox62563042012-05-11 11:30:16 +0100467 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);
Alan Cox1b082cc2011-11-03 18:22:26 +0000473
474 /* cursor B */
Alan Cox648a8e32012-03-08 16:00:31 +0000475 regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
476 regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
477 regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
Alan Cox1b082cc2011-11-03 18:22:26 +0000478
479 /* save palette */
480 for (i = 0; i < 256; i++)
Alan Cox62563042012-05-11 11:30:16 +0100481 pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
Alan Cox1b082cc2011-11-03 18:22:26 +0000482}
483
484/* restore HDMI register state */
485void 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;
Alan Coxc6265ff2012-03-08 16:02:05 +0000489 struct psb_state *regs = &dev_priv->regs.psb;
Alan Cox62563042012-05-11 11:30:16 +0100490 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
Alan Cox1b082cc2011-11-03 18:22:26 +0000491 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 */
Alan Cox62563042012-05-11 11:30:16 +0100502 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);
Alan Cox1b082cc2011-11-03 18:22:26 +0000509
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
Alan Cox62563042012-05-11 11:30:16 +0100518 PSB_WVDC32(pipeb->conf, PIPEBCONF);
Alan Cox1b082cc2011-11-03 18:22:26 +0000519 PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
520
521 /* plane */
Alan Cox62563042012-05-11 11:30:16 +0100522 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);
Alan Cox1b082cc2011-11-03 18:22:26 +0000527
528 /* cursor B */
Alan Cox648a8e32012-03-08 16:00:31 +0000529 PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
530 PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
531 PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
Alan Cox1b082cc2011-11-03 18:22:26 +0000532
533 /* restore palette */
534 for (i = 0; i < 256; i++)
Alan Cox62563042012-05-11 11:30:16 +0100535 PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
Alan Cox1b082cc2011-11-03 18:22:26 +0000536}