Loading...
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 <linux/delay.h>
28
29#include <drm/drm.h>
30#include <drm/drm_crtc_helper.h>
31#include <drm/drm_edid.h>
32#include <drm/drm_modeset_helper_vtables.h>
33#include <drm/drm_simple_kms_helper.h>
34
35#include "psb_drv.h"
36#include "psb_intel_drv.h"
37#include "psb_intel_reg.h"
38
39#define HDMI_READ(reg) readl(hdmi_dev->regs + (reg))
40#define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg))
41
42#define HDMI_HCR 0x1000
43#define HCR_ENABLE_HDCP (1 << 5)
44#define HCR_ENABLE_AUDIO (1 << 2)
45#define HCR_ENABLE_PIXEL (1 << 1)
46#define HCR_ENABLE_TMDS (1 << 0)
47
48#define HDMI_HICR 0x1004
49#define HDMI_HSR 0x1008
50#define HDMI_HISR 0x100C
51#define HDMI_DETECT_HDP (1 << 0)
52
53#define HDMI_VIDEO_REG 0x3000
54#define HDMI_UNIT_EN (1 << 7)
55#define HDMI_MODE_OUTPUT (1 << 0)
56#define HDMI_HBLANK_A 0x3100
57
58#define HDMI_AUDIO_CTRL 0x4000
59#define HDMI_ENABLE_AUDIO (1 << 0)
60
61#define PCH_HTOTAL_B 0x3100
62#define PCH_HBLANK_B 0x3104
63#define PCH_HSYNC_B 0x3108
64#define PCH_VTOTAL_B 0x310C
65#define PCH_VBLANK_B 0x3110
66#define PCH_VSYNC_B 0x3114
67#define PCH_PIPEBSRC 0x311C
68
69#define PCH_PIPEB_DSL 0x3800
70#define PCH_PIPEB_SLC 0x3804
71#define PCH_PIPEBCONF 0x3808
72#define PCH_PIPEBSTAT 0x3824
73
74#define CDVO_DFT 0x5000
75#define CDVO_SLEWRATE 0x5004
76#define CDVO_STRENGTH 0x5008
77#define CDVO_RCOMP 0x500C
78
79#define DPLL_CTRL 0x6000
80#define DPLL_PDIV_SHIFT 16
81#define DPLL_PDIV_MASK (0xf << 16)
82#define DPLL_PWRDN (1 << 4)
83#define DPLL_RESET (1 << 3)
84#define DPLL_FASTEN (1 << 2)
85#define DPLL_ENSTAT (1 << 1)
86#define DPLL_DITHEN (1 << 0)
87
88#define DPLL_DIV_CTRL 0x6004
89#define DPLL_CLKF_MASK 0xffffffc0
90#define DPLL_CLKR_MASK (0x3f)
91
92#define DPLL_CLK_ENABLE 0x6008
93#define DPLL_EN_DISP (1 << 31)
94#define DPLL_SEL_HDMI (1 << 8)
95#define DPLL_EN_HDMI (1 << 1)
96#define DPLL_EN_VGA (1 << 0)
97
98#define DPLL_ADJUST 0x600C
99#define DPLL_STATUS 0x6010
100#define DPLL_UPDATE 0x6014
101#define DPLL_DFT 0x6020
102
103struct intel_range {
104 int min, max;
105};
106
107struct oaktrail_hdmi_limit {
108 struct intel_range vco, np, nr, nf;
109};
110
111struct oaktrail_hdmi_clock {
112 int np;
113 int nr;
114 int nf;
115 int dot;
116};
117
118#define VCO_MIN 320000
119#define VCO_MAX 1650000
120#define NP_MIN 1
121#define NP_MAX 15
122#define NR_MIN 1
123#define NR_MAX 64
124#define NF_MIN 2
125#define NF_MAX 4095
126
127static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
128 .vco = { .min = VCO_MIN, .max = VCO_MAX },
129 .np = { .min = NP_MIN, .max = NP_MAX },
130 .nr = { .min = NR_MIN, .max = NR_MAX },
131 .nf = { .min = NF_MIN, .max = NF_MAX },
132};
133
134static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
135{
136 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
137 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
138
139 HDMI_WRITE(HDMI_HCR, 0x67);
140 HDMI_READ(HDMI_HCR);
141
142 HDMI_WRITE(0x51a8, 0x10);
143 HDMI_READ(0x51a8);
144
145 HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
146 HDMI_READ(HDMI_AUDIO_CTRL);
147}
148
149static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
150{
151 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
152 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
153
154 HDMI_WRITE(0x51a8, 0x0);
155 HDMI_READ(0x51a8);
156
157 HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
158 HDMI_READ(HDMI_AUDIO_CTRL);
159
160 HDMI_WRITE(HDMI_HCR, 0x47);
161 HDMI_READ(HDMI_HCR);
162}
163
164static unsigned int htotal_calculate(struct drm_display_mode *mode)
165{
166 u32 new_crtc_htotal;
167
168 /*
169 * 1024 x 768 new_crtc_htotal = 0x1024;
170 * 1280 x 1024 new_crtc_htotal = 0x0c34;
171 */
172 new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
173
174 DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
175 return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
176}
177
178static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
179 int refclk, struct oaktrail_hdmi_clock *best_clock)
180{
181 int np_min, np_max, nr_min, nr_max;
182 int np, nr, nf;
183
184 np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
185 np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
186 if (np_min < oaktrail_hdmi_limit.np.min)
187 np_min = oaktrail_hdmi_limit.np.min;
188 if (np_max > oaktrail_hdmi_limit.np.max)
189 np_max = oaktrail_hdmi_limit.np.max;
190
191 nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
192 nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
193 if (nr_min < oaktrail_hdmi_limit.nr.min)
194 nr_min = oaktrail_hdmi_limit.nr.min;
195 if (nr_max > oaktrail_hdmi_limit.nr.max)
196 nr_max = oaktrail_hdmi_limit.nr.max;
197
198 np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
199 nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
200 nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
201 DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
202
203 /*
204 * 1024 x 768 np = 1; nr = 0x26; nf = 0x0fd8000;
205 * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
206 */
207 best_clock->np = np;
208 best_clock->nr = nr - 1;
209 best_clock->nf = (nf << 14);
210}
211
212static void scu_busy_loop(void __iomem *scu_base)
213{
214 u32 status = 0;
215 u32 loop_count = 0;
216
217 status = readl(scu_base + 0x04);
218 while (status & 1) {
219 udelay(1); /* scu processing time is in few u secods */
220 status = readl(scu_base + 0x04);
221 loop_count++;
222 /* break if scu doesn't reset busy bit after huge retry */
223 if (loop_count > 1000) {
224 DRM_DEBUG_KMS("SCU IPC timed out");
225 return;
226 }
227 }
228}
229
230/*
231 * You don't want to know, you really really don't want to know....
232 *
233 * This is magic. However it's safe magic because of the way the platform
234 * works and it is necessary magic.
235 */
236static void oaktrail_hdmi_reset(struct drm_device *dev)
237{
238 void __iomem *base;
239 unsigned long scu_ipc_mmio = 0xff11c000UL;
240 int scu_len = 1024;
241
242 base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
243 if (base == NULL) {
244 DRM_ERROR("failed to map scu mmio\n");
245 return;
246 }
247
248 /* scu ipc: assert hdmi controller reset */
249 writel(0xff11d118, base + 0x0c);
250 writel(0x7fffffdf, base + 0x80);
251 writel(0x42005, base + 0x0);
252 scu_busy_loop(base);
253
254 /* scu ipc: de-assert hdmi controller reset */
255 writel(0xff11d118, base + 0x0c);
256 writel(0x7fffffff, base + 0x80);
257 writel(0x42005, base + 0x0);
258 scu_busy_loop(base);
259
260 iounmap(base);
261}
262
263int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
264 struct drm_display_mode *mode,
265 struct drm_display_mode *adjusted_mode,
266 int x, int y,
267 struct drm_framebuffer *old_fb)
268{
269 struct drm_device *dev = crtc->dev;
270 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
271 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
272 int pipe = 1;
273 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
274 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
275 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
276 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
277 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
278 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
279 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
280 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
281 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
282 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
283 int refclk;
284 struct oaktrail_hdmi_clock clock;
285 u32 dspcntr, pipeconf, dpll, temp;
286 int dspcntr_reg = DSPBCNTR;
287
288 if (!gma_power_begin(dev, true))
289 return 0;
290
291 /* Disable the VGA plane that we never use */
292 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
293
294 /* Disable dpll if necessary */
295 dpll = REG_READ(DPLL_CTRL);
296 if ((dpll & DPLL_PWRDN) == 0) {
297 REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
298 REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
299 REG_WRITE(DPLL_STATUS, 0x1);
300 }
301 udelay(150);
302
303 /* Reset controller */
304 oaktrail_hdmi_reset(dev);
305
306 /* program and enable dpll */
307 refclk = 25000;
308 oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
309
310 /* Set the DPLL */
311 dpll = REG_READ(DPLL_CTRL);
312 dpll &= ~DPLL_PDIV_MASK;
313 dpll &= ~(DPLL_PWRDN | DPLL_RESET);
314 REG_WRITE(DPLL_CTRL, 0x00000008);
315 REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
316 REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
317 REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
318 REG_WRITE(DPLL_UPDATE, 0x80000000);
319 REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
320 udelay(150);
321
322 /* configure HDMI */
323 HDMI_WRITE(0x1004, 0x1fd);
324 HDMI_WRITE(0x2000, 0x1);
325 HDMI_WRITE(0x2008, 0x0);
326 HDMI_WRITE(0x3130, 0x8);
327 HDMI_WRITE(0x101c, 0x1800810);
328
329 temp = htotal_calculate(adjusted_mode);
330 REG_WRITE(htot_reg, temp);
331 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
332 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
333 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
334 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
335 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
336 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
337
338 REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
339 REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
340 REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
341 REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
342 REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
343 REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
344 REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
345
346 temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
347 HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) | temp);
348
349 REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
350 REG_WRITE(dsppos_reg, 0);
351
352 /* Flush the plane changes */
353 {
354 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
355 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
356 }
357
358 /* Set up the display plane register */
359 dspcntr = REG_READ(dspcntr_reg);
360 dspcntr |= DISPPLANE_GAMMA_ENABLE;
361 dspcntr |= DISPPLANE_SEL_PIPE_B;
362 dspcntr |= DISPLAY_PLANE_ENABLE;
363
364 /* setup pipeconf */
365 pipeconf = REG_READ(pipeconf_reg);
366 pipeconf |= PIPEACONF_ENABLE;
367
368 REG_WRITE(pipeconf_reg, pipeconf);
369 REG_READ(pipeconf_reg);
370
371 REG_WRITE(PCH_PIPEBCONF, pipeconf);
372 REG_READ(PCH_PIPEBCONF);
373 gma_wait_for_vblank(dev);
374
375 REG_WRITE(dspcntr_reg, dspcntr);
376 gma_wait_for_vblank(dev);
377
378 gma_power_end(dev);
379
380 return 0;
381}
382
383void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
384{
385 struct drm_device *dev = crtc->dev;
386 u32 temp;
387
388 DRM_DEBUG_KMS("%s %d\n", __func__, mode);
389
390 switch (mode) {
391 case DRM_MODE_DPMS_OFF:
392 REG_WRITE(VGACNTRL, 0x80000000);
393
394 /* Disable plane */
395 temp = REG_READ(DSPBCNTR);
396 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
397 REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
398 REG_READ(DSPBCNTR);
399 /* Flush the plane changes */
400 REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
401 REG_READ(DSPBSURF);
402 }
403
404 /* Disable pipe B */
405 temp = REG_READ(PIPEBCONF);
406 if ((temp & PIPEACONF_ENABLE) != 0) {
407 REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
408 REG_READ(PIPEBCONF);
409 }
410
411 /* Disable LNW Pipes, etc */
412 temp = REG_READ(PCH_PIPEBCONF);
413 if ((temp & PIPEACONF_ENABLE) != 0) {
414 REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
415 REG_READ(PCH_PIPEBCONF);
416 }
417
418 /* wait for pipe off */
419 udelay(150);
420
421 /* Disable dpll */
422 temp = REG_READ(DPLL_CTRL);
423 if ((temp & DPLL_PWRDN) == 0) {
424 REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
425 REG_WRITE(DPLL_STATUS, 0x1);
426 }
427
428 /* wait for dpll off */
429 udelay(150);
430
431 break;
432 case DRM_MODE_DPMS_ON:
433 case DRM_MODE_DPMS_STANDBY:
434 case DRM_MODE_DPMS_SUSPEND:
435 /* Enable dpll */
436 temp = REG_READ(DPLL_CTRL);
437 if ((temp & DPLL_PWRDN) != 0) {
438 REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
439 temp = REG_READ(DPLL_CLK_ENABLE);
440 REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
441 REG_READ(DPLL_CLK_ENABLE);
442 }
443 /* wait for dpll warm up */
444 udelay(150);
445
446 /* Enable pipe B */
447 temp = REG_READ(PIPEBCONF);
448 if ((temp & PIPEACONF_ENABLE) == 0) {
449 REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
450 REG_READ(PIPEBCONF);
451 }
452
453 /* Enable LNW Pipe B */
454 temp = REG_READ(PCH_PIPEBCONF);
455 if ((temp & PIPEACONF_ENABLE) == 0) {
456 REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
457 REG_READ(PCH_PIPEBCONF);
458 }
459
460 gma_wait_for_vblank(dev);
461
462 /* Enable plane */
463 temp = REG_READ(DSPBCNTR);
464 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
465 REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
466 /* Flush the plane changes */
467 REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
468 REG_READ(DSPBSURF);
469 }
470
471 gma_crtc_load_lut(crtc);
472 }
473
474 /* DSPARB */
475 REG_WRITE(DSPARB, 0x00003fbf);
476
477 /* FW1 */
478 REG_WRITE(0x70034, 0x3f880a0a);
479
480 /* FW2 */
481 REG_WRITE(0x70038, 0x0b060808);
482
483 /* FW4 */
484 REG_WRITE(0x70050, 0x08030404);
485
486 /* FW5 */
487 REG_WRITE(0x70054, 0x04040404);
488
489 /* LNC Chicken Bits - Squawk! */
490 REG_WRITE(0x70400, 0x4000);
491
492 return;
493}
494
495static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
496{
497 static int dpms_mode = -1;
498
499 struct drm_device *dev = encoder->dev;
500 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
501 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
502 u32 temp;
503
504 if (dpms_mode == mode)
505 return;
506
507 if (mode != DRM_MODE_DPMS_ON)
508 temp = 0x0;
509 else
510 temp = 0x99;
511
512 dpms_mode = mode;
513 HDMI_WRITE(HDMI_VIDEO_REG, temp);
514}
515
516static enum drm_mode_status oaktrail_hdmi_mode_valid(struct drm_connector *connector,
517 struct drm_display_mode *mode)
518{
519 if (mode->clock > 165000)
520 return MODE_CLOCK_HIGH;
521 if (mode->clock < 20000)
522 return MODE_CLOCK_LOW;
523
524 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
525 return MODE_NO_DBLESCAN;
526
527 return MODE_OK;
528}
529
530static enum drm_connector_status
531oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
532{
533 enum drm_connector_status status;
534 struct drm_device *dev = connector->dev;
535 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
536 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
537 u32 temp;
538
539 temp = HDMI_READ(HDMI_HSR);
540 DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
541
542 if ((temp & HDMI_DETECT_HDP) != 0)
543 status = connector_status_connected;
544 else
545 status = connector_status_disconnected;
546
547 return status;
548}
549
550static const unsigned char raw_edid[] = {
551 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
552 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
553 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
554 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
555 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
556 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
557 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
558 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
559 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
560 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
561 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
562};
563
564static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
565{
566 struct i2c_adapter *i2c_adap;
567 struct edid *edid;
568 int ret = 0;
569
570 /*
571 * FIXME: We need to figure this lot out. In theory we can
572 * read the EDID somehow but I've yet to find working reference
573 * code.
574 */
575 i2c_adap = i2c_get_adapter(3);
576 if (i2c_adap == NULL) {
577 DRM_ERROR("No ddc adapter available!\n");
578 edid = (struct edid *)raw_edid;
579 } else {
580 edid = (struct edid *)raw_edid;
581 /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
582 }
583
584 if (edid) {
585 drm_connector_update_edid_property(connector, edid);
586 ret = drm_add_edid_modes(connector, edid);
587 }
588 return ret;
589}
590
591static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
592 struct drm_display_mode *mode,
593 struct drm_display_mode *adjusted_mode)
594{
595 struct drm_device *dev = encoder->dev;
596
597 oaktrail_hdmi_audio_enable(dev);
598 return;
599}
600
601static void oaktrail_hdmi_destroy(struct drm_connector *connector)
602{
603 return;
604}
605
606static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
607 .dpms = oaktrail_hdmi_dpms,
608 .prepare = gma_encoder_prepare,
609 .mode_set = oaktrail_hdmi_mode_set,
610 .commit = gma_encoder_commit,
611};
612
613static const struct drm_connector_helper_funcs
614 oaktrail_hdmi_connector_helper_funcs = {
615 .get_modes = oaktrail_hdmi_get_modes,
616 .mode_valid = oaktrail_hdmi_mode_valid,
617 .best_encoder = gma_best_encoder,
618};
619
620static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
621 .dpms = drm_helper_connector_dpms,
622 .detect = oaktrail_hdmi_detect,
623 .fill_modes = drm_helper_probe_single_connector_modes,
624 .destroy = oaktrail_hdmi_destroy,
625};
626
627void oaktrail_hdmi_init(struct drm_device *dev,
628 struct psb_intel_mode_device *mode_dev)
629{
630 struct gma_encoder *gma_encoder;
631 struct gma_connector *gma_connector;
632 struct drm_connector *connector;
633 struct drm_encoder *encoder;
634
635 gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
636 if (!gma_encoder)
637 return;
638
639 gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
640 if (!gma_connector)
641 goto failed_connector;
642
643 connector = &gma_connector->base;
644 encoder = &gma_encoder->base;
645 drm_connector_init(dev, connector,
646 &oaktrail_hdmi_connector_funcs,
647 DRM_MODE_CONNECTOR_DVID);
648
649 drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
650
651 gma_connector_attach_encoder(gma_connector, gma_encoder);
652
653 gma_encoder->type = INTEL_OUTPUT_HDMI;
654 drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
655 drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
656
657 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
658 connector->interlace_allowed = false;
659 connector->doublescan_allowed = false;
660 dev_info(dev->dev, "HDMI initialised.\n");
661
662 return;
663
664failed_connector:
665 kfree(gma_encoder);
666}
667
668void oaktrail_hdmi_setup(struct drm_device *dev)
669{
670 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
671 struct pci_dev *pdev;
672 struct oaktrail_hdmi_dev *hdmi_dev;
673 int ret;
674
675 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
676 if (!pdev)
677 return;
678
679 hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
680 if (!hdmi_dev) {
681 dev_err(dev->dev, "failed to allocate memory\n");
682 goto out;
683 }
684
685
686 ret = pci_enable_device(pdev);
687 if (ret) {
688 dev_err(dev->dev, "failed to enable hdmi controller\n");
689 goto free;
690 }
691
692 hdmi_dev->mmio = pci_resource_start(pdev, 0);
693 hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
694 hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
695 if (!hdmi_dev->regs) {
696 dev_err(dev->dev, "failed to map hdmi mmio\n");
697 goto free;
698 }
699
700 hdmi_dev->dev = pdev;
701 pci_set_drvdata(pdev, hdmi_dev);
702
703 /* Initialize i2c controller */
704 ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
705 if (ret)
706 dev_err(dev->dev, "HDMI I2C initialization failed\n");
707
708 dev_priv->hdmi_priv = hdmi_dev;
709 oaktrail_hdmi_audio_disable(dev);
710
711 dev_info(dev->dev, "HDMI hardware present.\n");
712
713 return;
714
715free:
716 kfree(hdmi_dev);
717out:
718 return;
719}
720
721void oaktrail_hdmi_teardown(struct drm_device *dev)
722{
723 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
724 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
725 struct pci_dev *pdev;
726
727 if (hdmi_dev) {
728 pdev = hdmi_dev->dev;
729 pci_set_drvdata(pdev, NULL);
730 oaktrail_hdmi_i2c_exit(pdev);
731 iounmap(hdmi_dev->regs);
732 kfree(hdmi_dev);
733 pci_dev_put(pdev);
734 }
735}
736
737/* save HDMI register state */
738void oaktrail_hdmi_save(struct drm_device *dev)
739{
740 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
741 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
742 struct psb_state *regs = &dev_priv->regs.psb;
743 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
744 int i;
745
746 /* dpll */
747 hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
748 hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
749 hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
750 hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
751 hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
752
753 /* pipe B */
754 pipeb->conf = PSB_RVDC32(PIPEBCONF);
755 pipeb->src = PSB_RVDC32(PIPEBSRC);
756 pipeb->htotal = PSB_RVDC32(HTOTAL_B);
757 pipeb->hblank = PSB_RVDC32(HBLANK_B);
758 pipeb->hsync = PSB_RVDC32(HSYNC_B);
759 pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
760 pipeb->vblank = PSB_RVDC32(VBLANK_B);
761 pipeb->vsync = PSB_RVDC32(VSYNC_B);
762
763 hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
764 hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
765 hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
766 hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
767 hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B);
768 hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
769 hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
770 hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B);
771
772 /* plane */
773 pipeb->cntr = PSB_RVDC32(DSPBCNTR);
774 pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
775 pipeb->addr = PSB_RVDC32(DSPBBASE);
776 pipeb->surf = PSB_RVDC32(DSPBSURF);
777 pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
778 pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
779
780 /* cursor B */
781 regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
782 regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
783 regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
784
785 /* save palette */
786 for (i = 0; i < 256; i++)
787 pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
788}
789
790/* restore HDMI register state */
791void oaktrail_hdmi_restore(struct drm_device *dev)
792{
793 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
794 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
795 struct psb_state *regs = &dev_priv->regs.psb;
796 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
797 int i;
798
799 /* dpll */
800 PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
801 PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
802 PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
803 PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
804 PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
805 udelay(150);
806
807 /* pipe */
808 PSB_WVDC32(pipeb->src, PIPEBSRC);
809 PSB_WVDC32(pipeb->htotal, HTOTAL_B);
810 PSB_WVDC32(pipeb->hblank, HBLANK_B);
811 PSB_WVDC32(pipeb->hsync, HSYNC_B);
812 PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
813 PSB_WVDC32(pipeb->vblank, VBLANK_B);
814 PSB_WVDC32(pipeb->vsync, VSYNC_B);
815
816 PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
817 PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
818 PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
819 PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B);
820 PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
821 PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
822 PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B);
823
824 PSB_WVDC32(pipeb->conf, PIPEBCONF);
825 PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
826
827 /* plane */
828 PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
829 PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
830 PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
831 PSB_WVDC32(pipeb->cntr, DSPBCNTR);
832 PSB_WVDC32(pipeb->surf, DSPBSURF);
833
834 /* cursor B */
835 PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
836 PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
837 PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
838
839 /* restore palette */
840 for (i = 0; i < 256; i++)
841 PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
842}
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
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
128static 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
158static unsigned int htotal_calculate(struct drm_display_mode *mode)
159{
160 u32 htotal, new_crtc_htotal;
161
162 htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
163
164 /*
165 * 1024 x 768 new_crtc_htotal = 0x1024;
166 * 1280 x 1024 new_crtc_htotal = 0x0c34;
167 */
168 new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
169
170 DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
171 return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
172}
173
174static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
175 int refclk, struct oaktrail_hdmi_clock *best_clock)
176{
177 int np_min, np_max, nr_min, nr_max;
178 int np, nr, nf;
179
180 np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
181 np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
182 if (np_min < oaktrail_hdmi_limit.np.min)
183 np_min = oaktrail_hdmi_limit.np.min;
184 if (np_max > oaktrail_hdmi_limit.np.max)
185 np_max = oaktrail_hdmi_limit.np.max;
186
187 nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
188 nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
189 if (nr_min < oaktrail_hdmi_limit.nr.min)
190 nr_min = oaktrail_hdmi_limit.nr.min;
191 if (nr_max > oaktrail_hdmi_limit.nr.max)
192 nr_max = oaktrail_hdmi_limit.nr.max;
193
194 np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
195 nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
196 nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
197 DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
198
199 /*
200 * 1024 x 768 np = 1; nr = 0x26; nf = 0x0fd8000;
201 * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
202 */
203 best_clock->np = np;
204 best_clock->nr = nr - 1;
205 best_clock->nf = (nf << 14);
206}
207
208static void scu_busy_loop(void __iomem *scu_base)
209{
210 u32 status = 0;
211 u32 loop_count = 0;
212
213 status = readl(scu_base + 0x04);
214 while (status & 1) {
215 udelay(1); /* scu processing time is in few u secods */
216 status = readl(scu_base + 0x04);
217 loop_count++;
218 /* break if scu doesn't reset busy bit after huge retry */
219 if (loop_count > 1000) {
220 DRM_DEBUG_KMS("SCU IPC timed out");
221 return;
222 }
223 }
224}
225
226/*
227 * You don't want to know, you really really don't want to know....
228 *
229 * This is magic. However it's safe magic because of the way the platform
230 * works and it is necessary magic.
231 */
232static void oaktrail_hdmi_reset(struct drm_device *dev)
233{
234 void __iomem *base;
235 unsigned long scu_ipc_mmio = 0xff11c000UL;
236 int scu_len = 1024;
237
238 base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
239 if (base == NULL) {
240 DRM_ERROR("failed to map scu mmio\n");
241 return;
242 }
243
244 /* scu ipc: assert hdmi controller reset */
245 writel(0xff11d118, base + 0x0c);
246 writel(0x7fffffdf, base + 0x80);
247 writel(0x42005, base + 0x0);
248 scu_busy_loop(base);
249
250 /* scu ipc: de-assert hdmi controller reset */
251 writel(0xff11d118, base + 0x0c);
252 writel(0x7fffffff, base + 0x80);
253 writel(0x42005, base + 0x0);
254 scu_busy_loop(base);
255
256 iounmap(base);
257}
258
259int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
260 struct drm_display_mode *mode,
261 struct drm_display_mode *adjusted_mode,
262 int x, int y,
263 struct drm_framebuffer *old_fb)
264{
265 struct drm_device *dev = crtc->dev;
266 struct drm_psb_private *dev_priv = dev->dev_private;
267 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
268 int pipe = 1;
269 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
270 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
271 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
272 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
273 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
274 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
275 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
276 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
277 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
278 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
279 int refclk;
280 struct oaktrail_hdmi_clock clock;
281 u32 dspcntr, pipeconf, dpll, temp;
282 int dspcntr_reg = DSPBCNTR;
283
284 if (!gma_power_begin(dev, true))
285 return 0;
286
287 /* Disable the VGA plane that we never use */
288 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
289
290 /* Disable dpll if necessary */
291 dpll = REG_READ(DPLL_CTRL);
292 if ((dpll & DPLL_PWRDN) == 0) {
293 REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
294 REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
295 REG_WRITE(DPLL_STATUS, 0x1);
296 }
297 udelay(150);
298
299 /* Reset controller */
300 oaktrail_hdmi_reset(dev);
301
302 /* program and enable dpll */
303 refclk = 25000;
304 oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
305
306 /* Set the DPLL */
307 dpll = REG_READ(DPLL_CTRL);
308 dpll &= ~DPLL_PDIV_MASK;
309 dpll &= ~(DPLL_PWRDN | DPLL_RESET);
310 REG_WRITE(DPLL_CTRL, 0x00000008);
311 REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
312 REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
313 REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
314 REG_WRITE(DPLL_UPDATE, 0x80000000);
315 REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
316 udelay(150);
317
318 /* configure HDMI */
319 HDMI_WRITE(0x1004, 0x1fd);
320 HDMI_WRITE(0x2000, 0x1);
321 HDMI_WRITE(0x2008, 0x0);
322 HDMI_WRITE(0x3130, 0x8);
323 HDMI_WRITE(0x101c, 0x1800810);
324
325 temp = htotal_calculate(adjusted_mode);
326 REG_WRITE(htot_reg, temp);
327 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
328 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
329 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
330 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
331 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
332 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
333
334 REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
335 REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
336 REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
337 REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
338 REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
339 REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
340 REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
341
342 temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
343 HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) | temp);
344
345 REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
346 REG_WRITE(dsppos_reg, 0);
347
348 /* Flush the plane changes */
349 {
350 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
351 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
352 }
353
354 /* Set up the display plane register */
355 dspcntr = REG_READ(dspcntr_reg);
356 dspcntr |= DISPPLANE_GAMMA_ENABLE;
357 dspcntr |= DISPPLANE_SEL_PIPE_B;
358 dspcntr |= DISPLAY_PLANE_ENABLE;
359
360 /* setup pipeconf */
361 pipeconf = REG_READ(pipeconf_reg);
362 pipeconf |= PIPEACONF_ENABLE;
363
364 REG_WRITE(pipeconf_reg, pipeconf);
365 REG_READ(pipeconf_reg);
366
367 REG_WRITE(PCH_PIPEBCONF, pipeconf);
368 REG_READ(PCH_PIPEBCONF);
369 gma_wait_for_vblank(dev);
370
371 REG_WRITE(dspcntr_reg, dspcntr);
372 gma_wait_for_vblank(dev);
373
374 gma_power_end(dev);
375
376 return 0;
377}
378
379void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
380{
381 struct drm_device *dev = crtc->dev;
382 u32 temp;
383
384 DRM_DEBUG_KMS("%s %d\n", __func__, mode);
385
386 switch (mode) {
387 case DRM_MODE_DPMS_OFF:
388 REG_WRITE(VGACNTRL, 0x80000000);
389
390 /* Disable plane */
391 temp = REG_READ(DSPBCNTR);
392 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
393 REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
394 REG_READ(DSPBCNTR);
395 /* Flush the plane changes */
396 REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
397 REG_READ(DSPBSURF);
398 }
399
400 /* Disable pipe B */
401 temp = REG_READ(PIPEBCONF);
402 if ((temp & PIPEACONF_ENABLE) != 0) {
403 REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
404 REG_READ(PIPEBCONF);
405 }
406
407 /* Disable LNW Pipes, etc */
408 temp = REG_READ(PCH_PIPEBCONF);
409 if ((temp & PIPEACONF_ENABLE) != 0) {
410 REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
411 REG_READ(PCH_PIPEBCONF);
412 }
413
414 /* wait for pipe off */
415 udelay(150);
416
417 /* Disable dpll */
418 temp = REG_READ(DPLL_CTRL);
419 if ((temp & DPLL_PWRDN) == 0) {
420 REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
421 REG_WRITE(DPLL_STATUS, 0x1);
422 }
423
424 /* wait for dpll off */
425 udelay(150);
426
427 break;
428 case DRM_MODE_DPMS_ON:
429 case DRM_MODE_DPMS_STANDBY:
430 case DRM_MODE_DPMS_SUSPEND:
431 /* Enable dpll */
432 temp = REG_READ(DPLL_CTRL);
433 if ((temp & DPLL_PWRDN) != 0) {
434 REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
435 temp = REG_READ(DPLL_CLK_ENABLE);
436 REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
437 REG_READ(DPLL_CLK_ENABLE);
438 }
439 /* wait for dpll warm up */
440 udelay(150);
441
442 /* Enable pipe B */
443 temp = REG_READ(PIPEBCONF);
444 if ((temp & PIPEACONF_ENABLE) == 0) {
445 REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
446 REG_READ(PIPEBCONF);
447 }
448
449 /* Enable LNW Pipe B */
450 temp = REG_READ(PCH_PIPEBCONF);
451 if ((temp & PIPEACONF_ENABLE) == 0) {
452 REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
453 REG_READ(PCH_PIPEBCONF);
454 }
455
456 gma_wait_for_vblank(dev);
457
458 /* Enable plane */
459 temp = REG_READ(DSPBCNTR);
460 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
461 REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
462 /* Flush the plane changes */
463 REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
464 REG_READ(DSPBSURF);
465 }
466
467 gma_crtc_load_lut(crtc);
468 }
469
470 /* DSPARB */
471 REG_WRITE(DSPARB, 0x00003fbf);
472
473 /* FW1 */
474 REG_WRITE(0x70034, 0x3f880a0a);
475
476 /* FW2 */
477 REG_WRITE(0x70038, 0x0b060808);
478
479 /* FW4 */
480 REG_WRITE(0x70050, 0x08030404);
481
482 /* FW5 */
483 REG_WRITE(0x70054, 0x04040404);
484
485 /* LNC Chicken Bits - Squawk! */
486 REG_WRITE(0x70400, 0x4000);
487
488 return;
489}
490
491static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
492{
493 static int dpms_mode = -1;
494
495 struct drm_device *dev = encoder->dev;
496 struct drm_psb_private *dev_priv = dev->dev_private;
497 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
498 u32 temp;
499
500 if (dpms_mode == mode)
501 return;
502
503 if (mode != DRM_MODE_DPMS_ON)
504 temp = 0x0;
505 else
506 temp = 0x99;
507
508 dpms_mode = mode;
509 HDMI_WRITE(HDMI_VIDEO_REG, temp);
510}
511
512static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
513 struct drm_display_mode *mode)
514{
515 if (mode->clock > 165000)
516 return MODE_CLOCK_HIGH;
517 if (mode->clock < 20000)
518 return MODE_CLOCK_LOW;
519
520 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
521 return MODE_NO_DBLESCAN;
522
523 return MODE_OK;
524}
525
526static enum drm_connector_status
527oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
528{
529 enum drm_connector_status status;
530 struct drm_device *dev = connector->dev;
531 struct drm_psb_private *dev_priv = dev->dev_private;
532 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
533 u32 temp;
534
535 temp = HDMI_READ(HDMI_HSR);
536 DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
537
538 if ((temp & HDMI_DETECT_HDP) != 0)
539 status = connector_status_connected;
540 else
541 status = connector_status_disconnected;
542
543 return status;
544}
545
546static const unsigned char raw_edid[] = {
547 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
548 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
549 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
550 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
551 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
552 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
553 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
554 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
555 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
556 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
557 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
558};
559
560static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
561{
562 struct i2c_adapter *i2c_adap;
563 struct edid *edid;
564 int ret = 0;
565
566 /*
567 * FIXME: We need to figure this lot out. In theory we can
568 * read the EDID somehow but I've yet to find working reference
569 * code.
570 */
571 i2c_adap = i2c_get_adapter(3);
572 if (i2c_adap == NULL) {
573 DRM_ERROR("No ddc adapter available!\n");
574 edid = (struct edid *)raw_edid;
575 } else {
576 edid = (struct edid *)raw_edid;
577 /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
578 }
579
580 if (edid) {
581 drm_mode_connector_update_edid_property(connector, edid);
582 ret = drm_add_edid_modes(connector, edid);
583 }
584 return ret;
585}
586
587static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
588 struct drm_display_mode *mode,
589 struct drm_display_mode *adjusted_mode)
590{
591 struct drm_device *dev = encoder->dev;
592
593 oaktrail_hdmi_audio_enable(dev);
594 return;
595}
596
597static void oaktrail_hdmi_destroy(struct drm_connector *connector)
598{
599 return;
600}
601
602static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
603 .dpms = oaktrail_hdmi_dpms,
604 .prepare = gma_encoder_prepare,
605 .mode_set = oaktrail_hdmi_mode_set,
606 .commit = gma_encoder_commit,
607};
608
609static const struct drm_connector_helper_funcs
610 oaktrail_hdmi_connector_helper_funcs = {
611 .get_modes = oaktrail_hdmi_get_modes,
612 .mode_valid = oaktrail_hdmi_mode_valid,
613 .best_encoder = gma_best_encoder,
614};
615
616static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
617 .dpms = drm_helper_connector_dpms,
618 .detect = oaktrail_hdmi_detect,
619 .fill_modes = drm_helper_probe_single_connector_modes,
620 .destroy = oaktrail_hdmi_destroy,
621};
622
623static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
624{
625 drm_encoder_cleanup(encoder);
626}
627
628static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
629 .destroy = oaktrail_hdmi_enc_destroy,
630};
631
632void oaktrail_hdmi_init(struct drm_device *dev,
633 struct psb_intel_mode_device *mode_dev)
634{
635 struct gma_encoder *gma_encoder;
636 struct gma_connector *gma_connector;
637 struct drm_connector *connector;
638 struct drm_encoder *encoder;
639
640 gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
641 if (!gma_encoder)
642 return;
643
644 gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
645 if (!gma_connector)
646 goto failed_connector;
647
648 connector = &gma_connector->base;
649 encoder = &gma_encoder->base;
650 drm_connector_init(dev, connector,
651 &oaktrail_hdmi_connector_funcs,
652 DRM_MODE_CONNECTOR_DVID);
653
654 drm_encoder_init(dev, encoder,
655 &oaktrail_hdmi_enc_funcs,
656 DRM_MODE_ENCODER_TMDS, NULL);
657
658 gma_connector_attach_encoder(gma_connector, gma_encoder);
659
660 gma_encoder->type = INTEL_OUTPUT_HDMI;
661 drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
662 drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
663
664 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
665 connector->interlace_allowed = false;
666 connector->doublescan_allowed = false;
667 drm_connector_register(connector);
668 dev_info(dev->dev, "HDMI initialised.\n");
669
670 return;
671
672failed_connector:
673 kfree(gma_encoder);
674}
675
676static const struct pci_device_id hdmi_ids[] = {
677 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
678 { 0 }
679};
680
681void oaktrail_hdmi_setup(struct drm_device *dev)
682{
683 struct drm_psb_private *dev_priv = dev->dev_private;
684 struct pci_dev *pdev;
685 struct oaktrail_hdmi_dev *hdmi_dev;
686 int ret;
687
688 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
689 if (!pdev)
690 return;
691
692 hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
693 if (!hdmi_dev) {
694 dev_err(dev->dev, "failed to allocate memory\n");
695 goto out;
696 }
697
698
699 ret = pci_enable_device(pdev);
700 if (ret) {
701 dev_err(dev->dev, "failed to enable hdmi controller\n");
702 goto free;
703 }
704
705 hdmi_dev->mmio = pci_resource_start(pdev, 0);
706 hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
707 hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
708 if (!hdmi_dev->regs) {
709 dev_err(dev->dev, "failed to map hdmi mmio\n");
710 goto free;
711 }
712
713 hdmi_dev->dev = pdev;
714 pci_set_drvdata(pdev, hdmi_dev);
715
716 /* Initialize i2c controller */
717 ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
718 if (ret)
719 dev_err(dev->dev, "HDMI I2C initialization failed\n");
720
721 dev_priv->hdmi_priv = hdmi_dev;
722 oaktrail_hdmi_audio_disable(dev);
723
724 dev_info(dev->dev, "HDMI hardware present.\n");
725
726 return;
727
728free:
729 kfree(hdmi_dev);
730out:
731 return;
732}
733
734void oaktrail_hdmi_teardown(struct drm_device *dev)
735{
736 struct drm_psb_private *dev_priv = dev->dev_private;
737 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
738 struct pci_dev *pdev;
739
740 if (hdmi_dev) {
741 pdev = hdmi_dev->dev;
742 pci_set_drvdata(pdev, NULL);
743 oaktrail_hdmi_i2c_exit(pdev);
744 iounmap(hdmi_dev->regs);
745 kfree(hdmi_dev);
746 pci_dev_put(pdev);
747 }
748}
749
750/* save HDMI register state */
751void oaktrail_hdmi_save(struct drm_device *dev)
752{
753 struct drm_psb_private *dev_priv = dev->dev_private;
754 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
755 struct psb_state *regs = &dev_priv->regs.psb;
756 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
757 int i;
758
759 /* dpll */
760 hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
761 hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
762 hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
763 hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
764 hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
765
766 /* pipe B */
767 pipeb->conf = PSB_RVDC32(PIPEBCONF);
768 pipeb->src = PSB_RVDC32(PIPEBSRC);
769 pipeb->htotal = PSB_RVDC32(HTOTAL_B);
770 pipeb->hblank = PSB_RVDC32(HBLANK_B);
771 pipeb->hsync = PSB_RVDC32(HSYNC_B);
772 pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
773 pipeb->vblank = PSB_RVDC32(VBLANK_B);
774 pipeb->vsync = PSB_RVDC32(VSYNC_B);
775
776 hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
777 hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
778 hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
779 hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
780 hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B);
781 hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
782 hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
783 hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B);
784
785 /* plane */
786 pipeb->cntr = PSB_RVDC32(DSPBCNTR);
787 pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
788 pipeb->addr = PSB_RVDC32(DSPBBASE);
789 pipeb->surf = PSB_RVDC32(DSPBSURF);
790 pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
791 pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
792
793 /* cursor B */
794 regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
795 regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
796 regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
797
798 /* save palette */
799 for (i = 0; i < 256; i++)
800 pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
801}
802
803/* restore HDMI register state */
804void oaktrail_hdmi_restore(struct drm_device *dev)
805{
806 struct drm_psb_private *dev_priv = dev->dev_private;
807 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
808 struct psb_state *regs = &dev_priv->regs.psb;
809 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
810 int i;
811
812 /* dpll */
813 PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
814 PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
815 PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
816 PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
817 PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
818 DRM_UDELAY(150);
819
820 /* pipe */
821 PSB_WVDC32(pipeb->src, PIPEBSRC);
822 PSB_WVDC32(pipeb->htotal, HTOTAL_B);
823 PSB_WVDC32(pipeb->hblank, HBLANK_B);
824 PSB_WVDC32(pipeb->hsync, HSYNC_B);
825 PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
826 PSB_WVDC32(pipeb->vblank, VBLANK_B);
827 PSB_WVDC32(pipeb->vsync, VSYNC_B);
828
829 PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
830 PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
831 PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
832 PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B);
833 PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
834 PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
835 PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B);
836
837 PSB_WVDC32(pipeb->conf, PIPEBCONF);
838 PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
839
840 /* plane */
841 PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
842 PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
843 PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
844 PSB_WVDC32(pipeb->cntr, DSPBCNTR);
845 PSB_WVDC32(pipeb->surf, DSPBSURF);
846
847 /* cursor B */
848 PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
849 PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
850 PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
851
852 /* restore palette */
853 for (i = 0; i < 256; i++)
854 PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
855}