]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/gma500/oaktrail_hdmi.c
025d30970cc00e080b2140a5b2fe56540c57ee95
[karo-tx-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 wait_for_vblank(struct drm_device *dev)
129 {
130         /* FIXME: Can we do this as a sleep ? */
131         /* Wait for 20ms, i.e. one cycle at 50hz. */
132         mdelay(20);
133 }
134
135 static void scu_busy_loop(void *scu_base)
136 {
137         u32 status = 0;
138         u32 loop_count = 0;
139
140         status = readl(scu_base + 0x04);
141         while (status & 1) {
142                 udelay(1); /* scu processing time is in few u secods */
143                 status = readl(scu_base + 0x04);
144                 loop_count++;
145                 /* break if scu doesn't reset busy bit after huge retry */
146                 if (loop_count > 1000) {
147                         DRM_DEBUG_KMS("SCU IPC timed out");
148                         return;
149                 }
150         }
151 }
152
153 static void oaktrail_hdmi_reset(struct drm_device *dev)
154 {
155         void *base;
156         /* FIXME: at least make these defines */
157         unsigned int scu_ipc_mmio = 0xff11c000;
158         int scu_len = 1024;
159
160         base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
161         if (base == NULL) {
162                 DRM_ERROR("failed to map SCU mmio\n");
163                 return;
164         }
165
166         /* scu ipc: assert hdmi controller reset */
167         writel(0xff11d118, base + 0x0c);
168         writel(0x7fffffdf, base + 0x80);
169         writel(0x42005, base + 0x0);
170         scu_busy_loop(base);
171
172         /* scu ipc: de-assert hdmi controller reset */
173         writel(0xff11d118, base + 0x0c);
174         writel(0x7fffffff, base + 0x80);
175         writel(0x42005, base + 0x0);
176         scu_busy_loop(base);
177
178         iounmap(base);
179 }
180
181 static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
182 {
183         struct drm_psb_private *dev_priv = dev->dev_private;
184         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
185
186         HDMI_WRITE(HDMI_HCR, 0x67);
187         HDMI_READ(HDMI_HCR);
188
189         HDMI_WRITE(0x51a8, 0x10);
190         HDMI_READ(0x51a8);
191
192         HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
193         HDMI_READ(HDMI_AUDIO_CTRL);
194 }
195
196 static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
197 {
198         struct drm_psb_private *dev_priv = dev->dev_private;
199         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
200
201         HDMI_WRITE(0x51a8, 0x0);
202         HDMI_READ(0x51a8);
203
204         HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
205         HDMI_READ(HDMI_AUDIO_CTRL);
206
207         HDMI_WRITE(HDMI_HCR, 0x47);
208         HDMI_READ(HDMI_HCR);
209 }
210
211 void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
212 {
213         struct drm_device *dev = crtc->dev;
214         u32 temp;
215
216         switch (mode) {
217         case DRM_MODE_DPMS_OFF:
218                 /* Disable VGACNTRL */
219                 REG_WRITE(VGACNTRL, 0x80000000);
220
221                 /* Disable plane */
222                 temp = REG_READ(DSPBCNTR);
223                 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
224                         REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
225                         REG_READ(DSPBCNTR);
226                         /* Flush the plane changes */
227                         REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
228                         REG_READ(DSPBSURF);
229                 }
230
231                 /* Disable pipe B */
232                 temp = REG_READ(PIPEBCONF);
233                 if ((temp & PIPEACONF_ENABLE) != 0) {
234                         REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
235                         REG_READ(PIPEBCONF);
236                 }
237
238                 /* Disable LNW Pipes, etc */
239                 temp = REG_READ(PCH_PIPEBCONF);
240                 if ((temp & PIPEACONF_ENABLE) != 0) {
241                         REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
242                         REG_READ(PCH_PIPEBCONF);
243                 }
244                 /* wait for pipe off */
245                 udelay(150);
246                 /* Disable dpll */
247                 temp = REG_READ(DPLL_CTRL);
248                 if ((temp & DPLL_PWRDN) == 0) {
249                         REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
250                         REG_WRITE(DPLL_STATUS, 0x1);
251                 }
252                 /* wait for dpll off */
253                 udelay(150);
254                 break;
255         case DRM_MODE_DPMS_ON:
256         case DRM_MODE_DPMS_STANDBY:
257         case DRM_MODE_DPMS_SUSPEND:
258                 /* Enable dpll */
259                 temp = REG_READ(DPLL_CTRL);
260                 if ((temp & DPLL_PWRDN) != 0) {
261                         REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
262                         temp = REG_READ(DPLL_CLK_ENABLE);
263                         REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
264                         REG_READ(DPLL_CLK_ENABLE);
265                 }
266                 /* wait for dpll warm up */
267                 udelay(150);
268
269                 /* Enable pipe B */
270                 temp = REG_READ(PIPEBCONF);
271                 if ((temp & PIPEACONF_ENABLE) == 0) {
272                         REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
273                         REG_READ(PIPEBCONF);
274                 }
275
276                 /* Enable LNW Pipe B */
277                 temp = REG_READ(PCH_PIPEBCONF);
278                 if ((temp & PIPEACONF_ENABLE) == 0) {
279                         REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
280                         REG_READ(PCH_PIPEBCONF);
281                 }
282                 wait_for_vblank(dev);
283
284                 /* Enable plane */
285                 temp = REG_READ(DSPBCNTR);
286                 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
287                         REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
288                         /* Flush the plane changes */
289                         REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
290                         REG_READ(DSPBSURF);
291                 }
292                 psb_intel_crtc_load_lut(crtc);
293         }
294         /* DSPARB */
295         REG_WRITE(DSPARB, 0x00003fbf);
296         /* FW1 */
297         REG_WRITE(0x70034, 0x3f880a0a);
298         /* FW2 */
299         REG_WRITE(0x70038, 0x0b060808);
300         /* FW4 */
301         REG_WRITE(0x70050, 0x08030404);
302         /* FW5 */
303         REG_WRITE(0x70054, 0x04040404);
304         /* LNC Chicken Bits */
305         REG_WRITE(0x70400, 0x4000);
306 }
307
308
309 static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
310 {
311         static int dpms_mode = -1;
312
313         struct drm_device *dev = encoder->dev;
314         struct drm_psb_private *dev_priv = dev->dev_private;
315         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
316         u32 temp;
317
318         if (dpms_mode == mode)
319                 return;
320
321         if (mode != DRM_MODE_DPMS_ON)
322                 temp = 0x0;
323         else
324                 temp = 0x99;
325
326         dpms_mode = mode;
327         HDMI_WRITE(HDMI_VIDEO_REG, temp);
328 }
329
330 static unsigned int htotal_calculate(struct drm_display_mode *mode)
331 {
332         u32 htotal, new_crtc_htotal;
333
334         htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
335
336         /*
337          * 1024 x 768  new_crtc_htotal = 0x1024;
338          * 1280 x 1024 new_crtc_htotal = 0x0c34;
339          */
340         new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
341
342         return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
343 }
344
345 static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
346                                 int refclk, struct oaktrail_hdmi_clock *best_clock)
347 {
348         int np_min, np_max, nr_min, nr_max;
349         int np, nr, nf;
350
351         np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
352         np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
353         if (np_min < oaktrail_hdmi_limit.np.min)
354                 np_min = oaktrail_hdmi_limit.np.min;
355         if (np_max > oaktrail_hdmi_limit.np.max)
356                 np_max = oaktrail_hdmi_limit.np.max;
357
358         nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
359         nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
360         if (nr_min < oaktrail_hdmi_limit.nr.min)
361                 nr_min = oaktrail_hdmi_limit.nr.min;
362         if (nr_max > oaktrail_hdmi_limit.nr.max)
363                 nr_max = oaktrail_hdmi_limit.nr.max;
364
365         np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
366         nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
367         nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
368         DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
369
370         /*
371          * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
372          * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
373          */
374         best_clock->np = np;
375         best_clock->nr = nr - 1;
376         best_clock->nf = (nf << 14);
377 }
378
379 int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
380                             struct drm_display_mode *mode,
381                             struct drm_display_mode *adjusted_mode,
382                             int x, int y,
383                             struct drm_framebuffer *old_fb)
384 {
385         struct drm_device *dev = crtc->dev;
386         struct drm_psb_private *dev_priv = dev->dev_private;
387         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
388         int pipe = 1;
389         int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
390         int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
391         int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
392         int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
393         int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
394         int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
395         int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
396         int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
397         int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
398         int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
399         int refclk;
400         struct oaktrail_hdmi_clock clock;
401         u32 dspcntr, pipeconf, dpll, temp;
402         int dspcntr_reg = DSPBCNTR;
403
404         /* Disable the VGA plane that we never use */
405         REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
406
407         /* XXX: Disable the panel fitter if it was on our pipe */
408
409         /* Disable dpll if necessary */
410         dpll = REG_READ(DPLL_CTRL);
411         if ((dpll & DPLL_PWRDN) == 0) {
412                 REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
413                 REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
414                 REG_WRITE(DPLL_STATUS, 0x1);
415         }
416         udelay(150);
417
418         /* reset controller: FIXME - can we sort out the ioremap mess ? */
419         iounmap(hdmi_dev->regs);
420         oaktrail_hdmi_reset(dev);
421
422         /* program and enable dpll */
423         refclk = 25000;
424         oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
425
426         /* Setting DPLL */
427         dpll = REG_READ(DPLL_CTRL);
428         dpll &= ~DPLL_PDIV_MASK;
429         dpll &= ~(DPLL_PWRDN | DPLL_RESET);
430         REG_WRITE(DPLL_CTRL, 0x00000008);
431         REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
432         REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
433         REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
434         REG_WRITE(DPLL_UPDATE, 0x80000000);
435         REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
436         udelay(150);
437
438         hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
439         if (hdmi_dev->regs == NULL) {
440                 DRM_ERROR("failed to do hdmi mmio mapping\n");
441                 return -ENOMEM;
442         }
443
444         /* configure HDMI */
445         HDMI_WRITE(0x1004, 0x1fd);
446         HDMI_WRITE(0x2000, 0x1);
447         HDMI_WRITE(0x2008, 0x0);
448         HDMI_WRITE(0x3130, 0x8);
449         HDMI_WRITE(0x101c, 0x1800810);
450
451         temp = htotal_calculate(adjusted_mode);
452         REG_WRITE(htot_reg, temp);
453         REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
454         REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
455         REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
456         REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
457         REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
458         REG_WRITE(pipesrc_reg,
459                 ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
460
461         REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
462         REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
463         REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
464         REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
465         REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
466         REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
467         REG_WRITE(PCH_PIPEBSRC,
468                 ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
469
470         temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
471         HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
472
473         REG_WRITE(dspsize_reg,
474                         ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
475         REG_WRITE(dsppos_reg, 0);
476
477         /* Flush the plane changes */
478         {
479                 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
480                 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
481         }
482
483         /* Set up the display plane register */
484         dspcntr = REG_READ(dspcntr_reg);
485         dspcntr |= DISPPLANE_GAMMA_ENABLE;
486         dspcntr |= DISPPLANE_SEL_PIPE_B;
487         dspcntr |= DISPLAY_PLANE_ENABLE;
488
489         /* setup pipeconf */
490         pipeconf = REG_READ(pipeconf_reg);
491         pipeconf |= PIPEACONF_ENABLE;
492
493         REG_WRITE(pipeconf_reg, pipeconf);
494         REG_READ(pipeconf_reg);
495
496         REG_WRITE(PCH_PIPEBCONF, pipeconf);
497         REG_READ(PCH_PIPEBCONF);
498         wait_for_vblank(dev);
499
500         REG_WRITE(dspcntr_reg, dspcntr);
501         wait_for_vblank(dev);
502
503         return 0;
504 }
505
506 static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
507                                 struct drm_display_mode *mode)
508 {
509         struct drm_psb_private *dev_priv = connector->dev->dev_private;
510         if (mode->clock > 165000)
511                 return MODE_CLOCK_HIGH;
512         if (mode->clock < 20000)
513                 return MODE_CLOCK_LOW;
514
515         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
516                 return MODE_NO_DBLESCAN;
517
518         /* We assume worst case scenario of 32 bpp here, since we don't know */
519         if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
520             dev_priv->vram_stolen_size)
521                 return MODE_MEM;
522
523         return MODE_OK;
524 }
525
526 static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder,
527                                  struct drm_display_mode *mode,
528                                  struct drm_display_mode *adjusted_mode)
529 {
530         return true;
531 }
532
533 static enum drm_connector_status
534 oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
535 {
536         enum drm_connector_status status;
537         struct drm_device *dev = connector->dev;
538         struct drm_psb_private *dev_priv = dev->dev_private;
539         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
540         u32 temp;
541
542         temp = HDMI_READ(HDMI_HSR);
543         DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
544
545         if ((temp & HDMI_DETECT_HDP) != 0)
546                 status = connector_status_connected;
547         else
548                 status = connector_status_disconnected;
549
550         return status;
551 }
552
553 static const unsigned char raw_edid[] = {
554         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
555         0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
556         0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
557         0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
558         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
559         0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
560         0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
561         0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
562         0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
563         0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
564         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
565 };
566
567 static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
568 {
569         struct drm_device *dev = connector->dev;
570         struct drm_psb_private *dev_priv = dev->dev_private;
571         struct i2c_adapter *i2c_adap;
572         struct edid *edid;
573         struct drm_display_mode *mode, *t;
574         int i = 0, ret = 0;
575
576         i2c_adap = i2c_get_adapter(3);
577         if (i2c_adap == NULL) {
578                 DRM_ERROR("No ddc adapter available!\n");
579                 edid = (struct edid *)raw_edid;
580         } else {
581                 edid = (struct edid *)raw_edid;
582                 /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
583         }
584
585         if (edid) {
586                 drm_mode_connector_update_edid_property(connector, edid);
587                 ret = drm_add_edid_modes(connector, edid);
588                 connector->display_info.raw_edid = NULL;
589         }
590
591         /*
592          * prune modes that require frame buffer bigger than stolen mem
593          */
594         list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
595                 if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) {
596                         i++;
597                         drm_mode_remove(connector, mode);
598                 }
599         }
600         return ret - i;
601 }
602
603 static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
604                                struct drm_display_mode *mode,
605                                struct drm_display_mode *adjusted_mode)
606 {
607         struct drm_device *dev = encoder->dev;
608
609         oaktrail_hdmi_audio_enable(dev);
610         return;
611 }
612
613 static void oaktrail_hdmi_destroy(struct drm_connector *connector)
614 {
615         return;
616 }
617
618 static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
619         .dpms = oaktrail_hdmi_dpms,
620         .mode_fixup = oaktrail_hdmi_mode_fixup,
621         .prepare = psb_intel_encoder_prepare,
622         .mode_set = oaktrail_hdmi_mode_set,
623         .commit = psb_intel_encoder_commit,
624 };
625
626 static const struct drm_connector_helper_funcs
627                                         oaktrail_hdmi_connector_helper_funcs = {
628         .get_modes = oaktrail_hdmi_get_modes,
629         .mode_valid = oaktrail_hdmi_mode_valid,
630         .best_encoder = psb_intel_best_encoder,
631 };
632
633 static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
634         .dpms = drm_helper_connector_dpms,
635         .detect = oaktrail_hdmi_detect,
636         .fill_modes = drm_helper_probe_single_connector_modes,
637         .destroy = oaktrail_hdmi_destroy,
638 };
639
640 static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
641 {
642         drm_encoder_cleanup(encoder);
643 }
644
645 static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
646         .destroy = oaktrail_hdmi_enc_destroy,
647 };
648
649 void oaktrail_hdmi_init(struct drm_device *dev,
650                                         struct psb_intel_mode_device *mode_dev)
651 {
652         struct psb_intel_encoder *psb_intel_encoder;
653         struct psb_intel_connector *psb_intel_connector;
654         struct drm_connector *connector;
655         struct drm_encoder *encoder;
656
657         psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
658         if (!psb_intel_encoder)
659                 return;
660
661         psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
662         if (!psb_intel_connector)
663                 goto failed_connector;
664
665         connector = &psb_intel_connector->base;
666         encoder = &psb_intel_encoder->base;
667         drm_connector_init(dev, connector,
668                            &oaktrail_hdmi_connector_funcs,
669                            DRM_MODE_CONNECTOR_DVID);
670
671         drm_encoder_init(dev, encoder,
672                          &oaktrail_hdmi_enc_funcs,
673                          DRM_MODE_ENCODER_TMDS);
674
675         psb_intel_connector_attach_encoder(psb_intel_connector,
676                                            psb_intel_encoder);
677
678         psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
679         drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
680         drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
681
682         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
683         connector->interlace_allowed = false;
684         connector->doublescan_allowed = false;
685         drm_sysfs_connector_add(connector);
686
687         return;
688
689 failed_connector:
690         kfree(psb_intel_encoder);
691 }
692
693 static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
694         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
695         {}
696 };
697
698 void oaktrail_hdmi_setup(struct drm_device *dev)
699 {
700         struct drm_psb_private *dev_priv = dev->dev_private;
701         struct pci_dev *pdev;
702         struct oaktrail_hdmi_dev *hdmi_dev;
703         int ret;
704
705         pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
706         if (!pdev)
707                 return;
708
709         hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
710         if (!hdmi_dev) {
711                 dev_err(dev->dev, "failed to allocate memory\n");
712                 goto out;
713         }
714
715
716         ret = pci_enable_device(pdev);
717         if (ret) {
718                 dev_err(dev->dev, "failed to enable hdmi controller\n");
719                 goto free;
720         }
721
722         hdmi_dev->mmio = pci_resource_start(pdev, 0);
723         hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
724         hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
725         if (!hdmi_dev->regs) {
726                 dev_err(dev->dev, "failed to map hdmi mmio\n");
727                 goto free;
728         }
729
730         hdmi_dev->dev = pdev;
731         pci_set_drvdata(pdev, hdmi_dev);
732
733         /* Initialize i2c controller */
734         ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
735         if (ret)
736                 dev_err(dev->dev, "HDMI I2C initialization failed\n");
737
738         dev_priv->hdmi_priv = hdmi_dev;
739         oaktrail_hdmi_audio_disable(dev);
740         return;
741
742 free:
743         kfree(hdmi_dev);
744 out:
745         return;
746 }
747
748 void oaktrail_hdmi_teardown(struct drm_device *dev)
749 {
750         struct drm_psb_private *dev_priv = dev->dev_private;
751         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
752         struct pci_dev *pdev;
753
754         if (hdmi_dev) {
755                 pdev = hdmi_dev->dev;
756                 pci_set_drvdata(pdev, NULL);
757                 oaktrail_hdmi_i2c_exit(pdev);
758                 iounmap(hdmi_dev->regs);
759                 kfree(hdmi_dev);
760                 pci_dev_put(pdev);
761         }
762 }
763
764 /* save HDMI register state */
765 void oaktrail_hdmi_save(struct drm_device *dev)
766 {
767         struct drm_psb_private *dev_priv = dev->dev_private;
768         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
769         int i;
770
771         /* dpll */
772         hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
773         hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
774         hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
775         hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
776         hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
777
778         /* pipe B */
779         dev_priv->savePIPEBCONF = PSB_RVDC32(PIPEBCONF);
780         dev_priv->savePIPEBSRC  = PSB_RVDC32(PIPEBSRC);
781         dev_priv->saveHTOTAL_B  = PSB_RVDC32(HTOTAL_B);
782         dev_priv->saveHBLANK_B  = PSB_RVDC32(HBLANK_B);
783         dev_priv->saveHSYNC_B   = PSB_RVDC32(HSYNC_B);
784         dev_priv->saveVTOTAL_B  = PSB_RVDC32(VTOTAL_B);
785         dev_priv->saveVBLANK_B  = PSB_RVDC32(VBLANK_B);
786         dev_priv->saveVSYNC_B   = PSB_RVDC32(VSYNC_B);
787
788         hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
789         hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
790         hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
791         hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
792         hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
793         hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
794         hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
795         hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
796
797         /* plane */
798         dev_priv->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR);
799         dev_priv->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE);
800         dev_priv->saveDSPBADDR = PSB_RVDC32(DSPBBASE);
801         dev_priv->saveDSPBSURF = PSB_RVDC32(DSPBSURF);
802         dev_priv->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF);
803         dev_priv->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF);
804
805         /* cursor B */
806         dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
807         dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
808         dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
809
810         /* save palette */
811         for (i = 0; i < 256; i++)
812                 dev_priv->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2));
813 }
814
815 /* restore HDMI register state */
816 void oaktrail_hdmi_restore(struct drm_device *dev)
817 {
818         struct drm_psb_private *dev_priv = dev->dev_private;
819         struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
820         int i;
821
822         /* dpll */
823         PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
824         PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
825         PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
826         PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
827         PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
828         DRM_UDELAY(150);
829
830         /* pipe */
831         PSB_WVDC32(dev_priv->savePIPEBSRC, PIPEBSRC);
832         PSB_WVDC32(dev_priv->saveHTOTAL_B, HTOTAL_B);
833         PSB_WVDC32(dev_priv->saveHBLANK_B, HBLANK_B);
834         PSB_WVDC32(dev_priv->saveHSYNC_B,  HSYNC_B);
835         PSB_WVDC32(dev_priv->saveVTOTAL_B, VTOTAL_B);
836         PSB_WVDC32(dev_priv->saveVBLANK_B, VBLANK_B);
837         PSB_WVDC32(dev_priv->saveVSYNC_B,  VSYNC_B);
838
839         PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
840         PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
841         PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
842         PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
843         PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
844         PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
845         PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
846
847         PSB_WVDC32(dev_priv->savePIPEBCONF, PIPEBCONF);
848         PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
849
850         /* plane */
851         PSB_WVDC32(dev_priv->saveDSPBLINOFF, DSPBLINOFF);
852         PSB_WVDC32(dev_priv->saveDSPBSTRIDE, DSPBSTRIDE);
853         PSB_WVDC32(dev_priv->saveDSPBTILEOFF, DSPBTILEOFF);
854         PSB_WVDC32(dev_priv->saveDSPBCNTR, DSPBCNTR);
855         PSB_WVDC32(dev_priv->saveDSPBSURF, DSPBSURF);
856
857         /* cursor B */
858         PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
859         PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
860         PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
861
862         /* restore palette */
863         for (i = 0; i < 256; i++)
864                 PSB_WVDC32(dev_priv->save_palette_b[i], PALETTE_B + (i << 2));
865 }