Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright © 2010 Intel Corporation
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0021  * DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors:
0024  *  Li Peng <peng.li@intel.com>
0025  */
0026 
0027 #include <linux/delay.h>
0028 
0029 #include <drm/drm.h>
0030 #include <drm/drm_edid.h>
0031 #include <drm/drm_simple_kms_helper.h>
0032 
0033 #include "psb_drv.h"
0034 #include "psb_intel_drv.h"
0035 #include "psb_intel_reg.h"
0036 
0037 #define HDMI_READ(reg)      readl(hdmi_dev->regs + (reg))
0038 #define HDMI_WRITE(reg, val)    writel(val, hdmi_dev->regs + (reg))
0039 
0040 #define HDMI_HCR    0x1000
0041 #define HCR_ENABLE_HDCP     (1 << 5)
0042 #define HCR_ENABLE_AUDIO    (1 << 2)
0043 #define HCR_ENABLE_PIXEL    (1 << 1)
0044 #define HCR_ENABLE_TMDS     (1 << 0)
0045 
0046 #define HDMI_HICR   0x1004
0047 #define HDMI_HSR    0x1008
0048 #define HDMI_HISR   0x100C
0049 #define HDMI_DETECT_HDP     (1 << 0)
0050 
0051 #define HDMI_VIDEO_REG  0x3000
0052 #define HDMI_UNIT_EN        (1 << 7)
0053 #define HDMI_MODE_OUTPUT    (1 << 0)
0054 #define HDMI_HBLANK_A   0x3100
0055 
0056 #define HDMI_AUDIO_CTRL 0x4000
0057 #define HDMI_ENABLE_AUDIO   (1 << 0)
0058 
0059 #define PCH_HTOTAL_B    0x3100
0060 #define PCH_HBLANK_B    0x3104
0061 #define PCH_HSYNC_B 0x3108
0062 #define PCH_VTOTAL_B    0x310C
0063 #define PCH_VBLANK_B    0x3110
0064 #define PCH_VSYNC_B 0x3114
0065 #define PCH_PIPEBSRC    0x311C
0066 
0067 #define PCH_PIPEB_DSL   0x3800
0068 #define PCH_PIPEB_SLC   0x3804
0069 #define PCH_PIPEBCONF   0x3808
0070 #define PCH_PIPEBSTAT   0x3824
0071 
0072 #define CDVO_DFT    0x5000
0073 #define CDVO_SLEWRATE   0x5004
0074 #define CDVO_STRENGTH   0x5008
0075 #define CDVO_RCOMP  0x500C
0076 
0077 #define DPLL_CTRL       0x6000
0078 #define DPLL_PDIV_SHIFT     16
0079 #define DPLL_PDIV_MASK      (0xf << 16)
0080 #define DPLL_PWRDN      (1 << 4)
0081 #define DPLL_RESET      (1 << 3)
0082 #define DPLL_FASTEN     (1 << 2)
0083 #define DPLL_ENSTAT     (1 << 1)
0084 #define DPLL_DITHEN     (1 << 0)
0085 
0086 #define DPLL_DIV_CTRL   0x6004
0087 #define DPLL_CLKF_MASK      0xffffffc0
0088 #define DPLL_CLKR_MASK      (0x3f)
0089 
0090 #define DPLL_CLK_ENABLE 0x6008
0091 #define DPLL_EN_DISP        (1 << 31)
0092 #define DPLL_SEL_HDMI       (1 << 8)
0093 #define DPLL_EN_HDMI        (1 << 1)
0094 #define DPLL_EN_VGA     (1 << 0)
0095 
0096 #define DPLL_ADJUST     0x600C
0097 #define DPLL_STATUS     0x6010
0098 #define DPLL_UPDATE     0x6014
0099 #define DPLL_DFT        0x6020
0100 
0101 struct intel_range {
0102     int min, max;
0103 };
0104 
0105 struct oaktrail_hdmi_limit {
0106     struct intel_range vco, np, nr, nf;
0107 };
0108 
0109 struct oaktrail_hdmi_clock {
0110     int np;
0111     int nr;
0112     int nf;
0113     int dot;
0114 };
0115 
0116 #define VCO_MIN     320000
0117 #define VCO_MAX     1650000
0118 #define NP_MIN      1
0119 #define NP_MAX      15
0120 #define NR_MIN      1
0121 #define NR_MAX      64
0122 #define NF_MIN      2
0123 #define NF_MAX      4095
0124 
0125 static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
0126     .vco = { .min = VCO_MIN,        .max = VCO_MAX },
0127     .np  = { .min = NP_MIN,         .max = NP_MAX  },
0128     .nr  = { .min = NR_MIN,         .max = NR_MAX  },
0129     .nf  = { .min = NF_MIN,         .max = NF_MAX  },
0130 };
0131 
0132 static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
0133 {
0134     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0135     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0136 
0137     HDMI_WRITE(HDMI_HCR, 0x67);
0138     HDMI_READ(HDMI_HCR);
0139 
0140     HDMI_WRITE(0x51a8, 0x10);
0141     HDMI_READ(0x51a8);
0142 
0143     HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
0144     HDMI_READ(HDMI_AUDIO_CTRL);
0145 }
0146 
0147 static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
0148 {
0149     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0150     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0151 
0152     HDMI_WRITE(0x51a8, 0x0);
0153     HDMI_READ(0x51a8);
0154 
0155     HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
0156     HDMI_READ(HDMI_AUDIO_CTRL);
0157 
0158     HDMI_WRITE(HDMI_HCR, 0x47);
0159     HDMI_READ(HDMI_HCR);
0160 }
0161 
0162 static unsigned int htotal_calculate(struct drm_display_mode *mode)
0163 {
0164     u32 new_crtc_htotal;
0165 
0166     /*
0167      * 1024 x 768  new_crtc_htotal = 0x1024;
0168      * 1280 x 1024 new_crtc_htotal = 0x0c34;
0169      */
0170     new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
0171 
0172     DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
0173     return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
0174 }
0175 
0176 static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
0177                 int refclk, struct oaktrail_hdmi_clock *best_clock)
0178 {
0179     int np_min, np_max, nr_min, nr_max;
0180     int np, nr, nf;
0181 
0182     np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
0183     np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
0184     if (np_min < oaktrail_hdmi_limit.np.min)
0185         np_min = oaktrail_hdmi_limit.np.min;
0186     if (np_max > oaktrail_hdmi_limit.np.max)
0187         np_max = oaktrail_hdmi_limit.np.max;
0188 
0189     nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
0190     nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
0191     if (nr_min < oaktrail_hdmi_limit.nr.min)
0192         nr_min = oaktrail_hdmi_limit.nr.min;
0193     if (nr_max > oaktrail_hdmi_limit.nr.max)
0194         nr_max = oaktrail_hdmi_limit.nr.max;
0195 
0196     np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
0197     nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
0198     nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
0199     DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
0200 
0201     /*
0202      * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
0203      * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
0204      */
0205     best_clock->np = np;
0206     best_clock->nr = nr - 1;
0207     best_clock->nf = (nf << 14);
0208 }
0209 
0210 static void scu_busy_loop(void __iomem *scu_base)
0211 {
0212     u32 status = 0;
0213     u32 loop_count = 0;
0214 
0215     status = readl(scu_base + 0x04);
0216     while (status & 1) {
0217         udelay(1); /* scu processing time is in few u secods */
0218         status = readl(scu_base + 0x04);
0219         loop_count++;
0220         /* break if scu doesn't reset busy bit after huge retry */
0221         if (loop_count > 1000) {
0222             DRM_DEBUG_KMS("SCU IPC timed out");
0223             return;
0224         }
0225     }
0226 }
0227 
0228 /*
0229  *  You don't want to know, you really really don't want to know....
0230  *
0231  *  This is magic. However it's safe magic because of the way the platform
0232  *  works and it is necessary magic.
0233  */
0234 static void oaktrail_hdmi_reset(struct drm_device *dev)
0235 {
0236     void __iomem *base;
0237     unsigned long scu_ipc_mmio = 0xff11c000UL;
0238     int scu_len = 1024;
0239 
0240     base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
0241     if (base == NULL) {
0242         DRM_ERROR("failed to map scu mmio\n");
0243         return;
0244     }
0245 
0246     /* scu ipc: assert hdmi controller reset */
0247     writel(0xff11d118, base + 0x0c);
0248     writel(0x7fffffdf, base + 0x80);
0249     writel(0x42005, base + 0x0);
0250     scu_busy_loop(base);
0251 
0252     /* scu ipc: de-assert hdmi controller reset */
0253     writel(0xff11d118, base + 0x0c);
0254     writel(0x7fffffff, base + 0x80);
0255     writel(0x42005, base + 0x0);
0256     scu_busy_loop(base);
0257 
0258     iounmap(base);
0259 }
0260 
0261 int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
0262                 struct drm_display_mode *mode,
0263                 struct drm_display_mode *adjusted_mode,
0264                 int x, int y,
0265                 struct drm_framebuffer *old_fb)
0266 {
0267     struct drm_device *dev = crtc->dev;
0268     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0269     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0270     int pipe = 1;
0271     int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
0272     int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
0273     int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
0274     int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
0275     int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
0276     int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
0277     int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
0278     int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
0279     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
0280     int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
0281     int refclk;
0282     struct oaktrail_hdmi_clock clock;
0283     u32 dspcntr, pipeconf, dpll, temp;
0284     int dspcntr_reg = DSPBCNTR;
0285 
0286     if (!gma_power_begin(dev, true))
0287         return 0;
0288 
0289     /* Disable the VGA plane that we never use */
0290     REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
0291 
0292     /* Disable dpll if necessary */
0293     dpll = REG_READ(DPLL_CTRL);
0294     if ((dpll & DPLL_PWRDN) == 0) {
0295         REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
0296         REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
0297         REG_WRITE(DPLL_STATUS, 0x1);
0298     }
0299     udelay(150);
0300 
0301     /* Reset controller */
0302     oaktrail_hdmi_reset(dev);
0303 
0304     /* program and enable dpll */
0305     refclk = 25000;
0306     oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
0307 
0308     /* Set the DPLL */
0309     dpll = REG_READ(DPLL_CTRL);
0310     dpll &= ~DPLL_PDIV_MASK;
0311     dpll &= ~(DPLL_PWRDN | DPLL_RESET);
0312     REG_WRITE(DPLL_CTRL, 0x00000008);
0313     REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
0314     REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
0315     REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
0316     REG_WRITE(DPLL_UPDATE, 0x80000000);
0317     REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
0318     udelay(150);
0319 
0320     /* configure HDMI */
0321     HDMI_WRITE(0x1004, 0x1fd);
0322     HDMI_WRITE(0x2000, 0x1);
0323     HDMI_WRITE(0x2008, 0x0);
0324     HDMI_WRITE(0x3130, 0x8);
0325     HDMI_WRITE(0x101c, 0x1800810);
0326 
0327     temp = htotal_calculate(adjusted_mode);
0328     REG_WRITE(htot_reg, temp);
0329     REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
0330     REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
0331     REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
0332     REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
0333     REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
0334     REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
0335 
0336     REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
0337     REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
0338     REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
0339     REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
0340     REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
0341     REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
0342     REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
0343 
0344     temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
0345     HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
0346 
0347     REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
0348     REG_WRITE(dsppos_reg, 0);
0349 
0350     /* Flush the plane changes */
0351     {
0352         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0353         crtc_funcs->mode_set_base(crtc, x, y, old_fb);
0354     }
0355 
0356     /* Set up the display plane register */
0357     dspcntr = REG_READ(dspcntr_reg);
0358     dspcntr |= DISPPLANE_GAMMA_ENABLE;
0359     dspcntr |= DISPPLANE_SEL_PIPE_B;
0360     dspcntr |= DISPLAY_PLANE_ENABLE;
0361 
0362     /* setup pipeconf */
0363     pipeconf = REG_READ(pipeconf_reg);
0364     pipeconf |= PIPEACONF_ENABLE;
0365 
0366     REG_WRITE(pipeconf_reg, pipeconf);
0367     REG_READ(pipeconf_reg);
0368 
0369     REG_WRITE(PCH_PIPEBCONF, pipeconf);
0370     REG_READ(PCH_PIPEBCONF);
0371     gma_wait_for_vblank(dev);
0372 
0373     REG_WRITE(dspcntr_reg, dspcntr);
0374     gma_wait_for_vblank(dev);
0375 
0376     gma_power_end(dev);
0377 
0378     return 0;
0379 }
0380 
0381 void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
0382 {
0383     struct drm_device *dev = crtc->dev;
0384     u32 temp;
0385 
0386     DRM_DEBUG_KMS("%s %d\n", __func__, mode);
0387 
0388     switch (mode) {
0389     case DRM_MODE_DPMS_OFF:
0390         REG_WRITE(VGACNTRL, 0x80000000);
0391 
0392         /* Disable plane */
0393         temp = REG_READ(DSPBCNTR);
0394         if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
0395             REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
0396             REG_READ(DSPBCNTR);
0397             /* Flush the plane changes */
0398             REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
0399             REG_READ(DSPBSURF);
0400         }
0401 
0402         /* Disable pipe B */
0403         temp = REG_READ(PIPEBCONF);
0404         if ((temp & PIPEACONF_ENABLE) != 0) {
0405             REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
0406             REG_READ(PIPEBCONF);
0407         }
0408 
0409         /* Disable LNW Pipes, etc */
0410         temp = REG_READ(PCH_PIPEBCONF);
0411         if ((temp & PIPEACONF_ENABLE) != 0) {
0412             REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
0413             REG_READ(PCH_PIPEBCONF);
0414         }
0415 
0416         /* wait for pipe off */
0417         udelay(150);
0418 
0419         /* Disable dpll */
0420         temp = REG_READ(DPLL_CTRL);
0421         if ((temp & DPLL_PWRDN) == 0) {
0422             REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
0423             REG_WRITE(DPLL_STATUS, 0x1);
0424         }
0425 
0426         /* wait for dpll off */
0427         udelay(150);
0428 
0429         break;
0430     case DRM_MODE_DPMS_ON:
0431     case DRM_MODE_DPMS_STANDBY:
0432     case DRM_MODE_DPMS_SUSPEND:
0433         /* Enable dpll */
0434         temp = REG_READ(DPLL_CTRL);
0435         if ((temp & DPLL_PWRDN) != 0) {
0436             REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
0437             temp = REG_READ(DPLL_CLK_ENABLE);
0438             REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
0439             REG_READ(DPLL_CLK_ENABLE);
0440         }
0441         /* wait for dpll warm up */
0442         udelay(150);
0443 
0444         /* Enable pipe B */
0445         temp = REG_READ(PIPEBCONF);
0446         if ((temp & PIPEACONF_ENABLE) == 0) {
0447             REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
0448             REG_READ(PIPEBCONF);
0449         }
0450 
0451         /* Enable LNW Pipe B */
0452         temp = REG_READ(PCH_PIPEBCONF);
0453         if ((temp & PIPEACONF_ENABLE) == 0) {
0454             REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
0455             REG_READ(PCH_PIPEBCONF);
0456         }
0457 
0458         gma_wait_for_vblank(dev);
0459 
0460         /* Enable plane */
0461         temp = REG_READ(DSPBCNTR);
0462         if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
0463             REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
0464             /* Flush the plane changes */
0465             REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
0466             REG_READ(DSPBSURF);
0467         }
0468 
0469         gma_crtc_load_lut(crtc);
0470     }
0471 
0472     /* DSPARB */
0473     REG_WRITE(DSPARB, 0x00003fbf);
0474 
0475     /* FW1 */
0476     REG_WRITE(0x70034, 0x3f880a0a);
0477 
0478     /* FW2 */
0479     REG_WRITE(0x70038, 0x0b060808);
0480 
0481     /* FW4 */
0482     REG_WRITE(0x70050, 0x08030404);
0483 
0484     /* FW5 */
0485     REG_WRITE(0x70054, 0x04040404);
0486 
0487     /* LNC Chicken Bits - Squawk! */
0488     REG_WRITE(0x70400, 0x4000);
0489 
0490     return;
0491 }
0492 
0493 static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
0494 {
0495     static int dpms_mode = -1;
0496 
0497     struct drm_device *dev = encoder->dev;
0498     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0499     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0500     u32 temp;
0501 
0502     if (dpms_mode == mode)
0503         return;
0504 
0505     if (mode != DRM_MODE_DPMS_ON)
0506         temp = 0x0;
0507     else
0508         temp = 0x99;
0509 
0510     dpms_mode = mode;
0511     HDMI_WRITE(HDMI_VIDEO_REG, temp);
0512 }
0513 
0514 static enum drm_mode_status oaktrail_hdmi_mode_valid(struct drm_connector *connector,
0515                 struct drm_display_mode *mode)
0516 {
0517     if (mode->clock > 165000)
0518         return MODE_CLOCK_HIGH;
0519     if (mode->clock < 20000)
0520         return MODE_CLOCK_LOW;
0521 
0522     if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
0523         return MODE_NO_DBLESCAN;
0524 
0525     return MODE_OK;
0526 }
0527 
0528 static enum drm_connector_status
0529 oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
0530 {
0531     enum drm_connector_status status;
0532     struct drm_device *dev = connector->dev;
0533     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0534     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0535     u32 temp;
0536 
0537     temp = HDMI_READ(HDMI_HSR);
0538     DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
0539 
0540     if ((temp & HDMI_DETECT_HDP) != 0)
0541         status = connector_status_connected;
0542     else
0543         status = connector_status_disconnected;
0544 
0545     return status;
0546 }
0547 
0548 static const unsigned char raw_edid[] = {
0549     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
0550     0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
0551     0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
0552     0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
0553     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
0554     0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
0555     0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
0556     0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
0557     0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
0558     0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
0559     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
0560 };
0561 
0562 static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
0563 {
0564     struct i2c_adapter *i2c_adap;
0565     struct edid *edid;
0566     int ret = 0;
0567 
0568     /*
0569      *  FIXME: We need to figure this lot out. In theory we can
0570      *  read the EDID somehow but I've yet to find working reference
0571      *  code.
0572      */
0573     i2c_adap = i2c_get_adapter(3);
0574     if (i2c_adap == NULL) {
0575         DRM_ERROR("No ddc adapter available!\n");
0576         edid = (struct edid *)raw_edid;
0577     } else {
0578         edid = (struct edid *)raw_edid;
0579         /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
0580     }
0581 
0582     if (edid) {
0583         drm_connector_update_edid_property(connector, edid);
0584         ret = drm_add_edid_modes(connector, edid);
0585     }
0586     return ret;
0587 }
0588 
0589 static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
0590                    struct drm_display_mode *mode,
0591                    struct drm_display_mode *adjusted_mode)
0592 {
0593     struct drm_device *dev = encoder->dev;
0594 
0595     oaktrail_hdmi_audio_enable(dev);
0596     return;
0597 }
0598 
0599 static void oaktrail_hdmi_destroy(struct drm_connector *connector)
0600 {
0601     return;
0602 }
0603 
0604 static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
0605     .dpms = oaktrail_hdmi_dpms,
0606     .prepare = gma_encoder_prepare,
0607     .mode_set = oaktrail_hdmi_mode_set,
0608     .commit = gma_encoder_commit,
0609 };
0610 
0611 static const struct drm_connector_helper_funcs
0612                     oaktrail_hdmi_connector_helper_funcs = {
0613     .get_modes = oaktrail_hdmi_get_modes,
0614     .mode_valid = oaktrail_hdmi_mode_valid,
0615     .best_encoder = gma_best_encoder,
0616 };
0617 
0618 static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
0619     .dpms = drm_helper_connector_dpms,
0620     .detect = oaktrail_hdmi_detect,
0621     .fill_modes = drm_helper_probe_single_connector_modes,
0622     .destroy = oaktrail_hdmi_destroy,
0623 };
0624 
0625 void oaktrail_hdmi_init(struct drm_device *dev,
0626                     struct psb_intel_mode_device *mode_dev)
0627 {
0628     struct gma_encoder *gma_encoder;
0629     struct gma_connector *gma_connector;
0630     struct drm_connector *connector;
0631     struct drm_encoder *encoder;
0632 
0633     gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
0634     if (!gma_encoder)
0635         return;
0636 
0637     gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
0638     if (!gma_connector)
0639         goto failed_connector;
0640 
0641     connector = &gma_connector->base;
0642     encoder = &gma_encoder->base;
0643     drm_connector_init(dev, connector,
0644                &oaktrail_hdmi_connector_funcs,
0645                DRM_MODE_CONNECTOR_DVID);
0646 
0647     drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
0648 
0649     gma_connector_attach_encoder(gma_connector, gma_encoder);
0650 
0651     gma_encoder->type = INTEL_OUTPUT_HDMI;
0652     drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
0653     drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
0654 
0655     connector->display_info.subpixel_order = SubPixelHorizontalRGB;
0656     connector->interlace_allowed = false;
0657     connector->doublescan_allowed = false;
0658     dev_info(dev->dev, "HDMI initialised.\n");
0659 
0660     return;
0661 
0662 failed_connector:
0663     kfree(gma_encoder);
0664 }
0665 
0666 void oaktrail_hdmi_setup(struct drm_device *dev)
0667 {
0668     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0669     struct pci_dev *pdev;
0670     struct oaktrail_hdmi_dev *hdmi_dev;
0671     int ret;
0672 
0673     pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
0674     if (!pdev)
0675         return;
0676 
0677     hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
0678     if (!hdmi_dev) {
0679         dev_err(dev->dev, "failed to allocate memory\n");
0680         goto out;
0681     }
0682 
0683 
0684     ret = pci_enable_device(pdev);
0685     if (ret) {
0686         dev_err(dev->dev, "failed to enable hdmi controller\n");
0687         goto free;
0688     }
0689 
0690     hdmi_dev->mmio = pci_resource_start(pdev, 0);
0691     hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
0692     hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
0693     if (!hdmi_dev->regs) {
0694         dev_err(dev->dev, "failed to map hdmi mmio\n");
0695         goto free;
0696     }
0697 
0698     hdmi_dev->dev = pdev;
0699     pci_set_drvdata(pdev, hdmi_dev);
0700 
0701     /* Initialize i2c controller */
0702     ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
0703     if (ret)
0704         dev_err(dev->dev, "HDMI I2C initialization failed\n");
0705 
0706     dev_priv->hdmi_priv = hdmi_dev;
0707     oaktrail_hdmi_audio_disable(dev);
0708 
0709     dev_info(dev->dev, "HDMI hardware present.\n");
0710 
0711     return;
0712 
0713 free:
0714     kfree(hdmi_dev);
0715 out:
0716     return;
0717 }
0718 
0719 void oaktrail_hdmi_teardown(struct drm_device *dev)
0720 {
0721     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0722     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0723     struct pci_dev *pdev;
0724 
0725     if (hdmi_dev) {
0726         pdev = hdmi_dev->dev;
0727         pci_set_drvdata(pdev, NULL);
0728         oaktrail_hdmi_i2c_exit(pdev);
0729         iounmap(hdmi_dev->regs);
0730         kfree(hdmi_dev);
0731         pci_dev_put(pdev);
0732     }
0733 }
0734 
0735 /* save HDMI register state */
0736 void oaktrail_hdmi_save(struct drm_device *dev)
0737 {
0738     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0739     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0740     struct psb_state *regs = &dev_priv->regs.psb;
0741     struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
0742     int i;
0743 
0744     /* dpll */
0745     hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
0746     hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
0747     hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
0748     hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
0749     hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
0750 
0751     /* pipe B */
0752     pipeb->conf = PSB_RVDC32(PIPEBCONF);
0753     pipeb->src = PSB_RVDC32(PIPEBSRC);
0754     pipeb->htotal = PSB_RVDC32(HTOTAL_B);
0755     pipeb->hblank = PSB_RVDC32(HBLANK_B);
0756     pipeb->hsync = PSB_RVDC32(HSYNC_B);
0757     pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
0758     pipeb->vblank = PSB_RVDC32(VBLANK_B);
0759     pipeb->vsync = PSB_RVDC32(VSYNC_B);
0760 
0761     hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
0762     hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
0763     hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
0764     hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
0765     hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
0766     hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
0767     hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
0768     hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
0769 
0770     /* plane */
0771     pipeb->cntr = PSB_RVDC32(DSPBCNTR);
0772     pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
0773     pipeb->addr = PSB_RVDC32(DSPBBASE);
0774     pipeb->surf = PSB_RVDC32(DSPBSURF);
0775     pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
0776     pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
0777 
0778     /* cursor B */
0779     regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
0780     regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
0781     regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
0782 
0783     /* save palette */
0784     for (i = 0; i < 256; i++)
0785         pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
0786 }
0787 
0788 /* restore HDMI register state */
0789 void oaktrail_hdmi_restore(struct drm_device *dev)
0790 {
0791     struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0792     struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
0793     struct psb_state *regs = &dev_priv->regs.psb;
0794     struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
0795     int i;
0796 
0797     /* dpll */
0798     PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
0799     PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
0800     PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
0801     PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
0802     PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
0803     udelay(150);
0804 
0805     /* pipe */
0806     PSB_WVDC32(pipeb->src, PIPEBSRC);
0807     PSB_WVDC32(pipeb->htotal, HTOTAL_B);
0808     PSB_WVDC32(pipeb->hblank, HBLANK_B);
0809     PSB_WVDC32(pipeb->hsync,  HSYNC_B);
0810     PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
0811     PSB_WVDC32(pipeb->vblank, VBLANK_B);
0812     PSB_WVDC32(pipeb->vsync,  VSYNC_B);
0813 
0814     PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
0815     PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
0816     PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
0817     PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
0818     PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
0819     PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
0820     PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
0821 
0822     PSB_WVDC32(pipeb->conf, PIPEBCONF);
0823     PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
0824 
0825     /* plane */
0826     PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
0827     PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
0828     PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
0829     PSB_WVDC32(pipeb->cntr, DSPBCNTR);
0830     PSB_WVDC32(pipeb->surf, DSPBSURF);
0831 
0832     /* cursor B */
0833     PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
0834     PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
0835     PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
0836 
0837     /* restore palette */
0838     for (i = 0; i < 256; i++)
0839         PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
0840 }