]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/i915: Fix LVDS stability issue on Ironlake
authorZhenyu Wang <zhenyuw@linux.intel.com>
Wed, 25 Nov 2009 05:09:38 +0000 (13:09 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 18 Dec 2009 21:44:16 +0000 (13:44 -0800)
commit 1b3c7a47f993bf9ab6c4c7cc3bbf5588052b58f4 upstream.

In disable sequence, all output ports on PCH have to be disabled
before PCH transcoder, but LVDS port was left always enabled. This
one fixes that by disable LVDS port properly during pipe disable
process, and resolved stability issue seen on Ironlake. Also move
panel fitting disable time just after pipe disable to align with
the spec.

Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/gpu/drm/i915/intel_display.c

index 318ba47724460cceb2d21094a4f9b389d7944e66..d49c9980a4e7957a7478210963a4ba955557caf0 100644 (file)
@@ -1182,6 +1182,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
                DRM_DEBUG("crtc %d dpms on\n", pipe);
+
+               if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+                       temp = I915_READ(PCH_LVDS);
+                       if ((temp & LVDS_PORT_EN) == 0) {
+                               I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
+                               POSTING_READ(PCH_LVDS);
+                       }
+               }
+
                if (HAS_eDP) {
                        /* enable eDP PLL */
                        igdng_enable_pll_edp(crtc);
@@ -1366,8 +1375,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
        case DRM_MODE_DPMS_OFF:
                DRM_DEBUG("crtc %d dpms off\n", pipe);
 
-               i915_disable_vga(dev);
-
                /* Disable display plane */
                temp = I915_READ(dspcntr_reg);
                if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
@@ -1377,6 +1384,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
                        I915_READ(dspbase_reg);
                }
 
+               i915_disable_vga(dev);
+
                /* disable cpu pipe, disable after all planes disabled */
                temp = I915_READ(pipeconf_reg);
                if ((temp & PIPEACONF_ENABLE) != 0) {
@@ -1397,9 +1406,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
                } else
                        DRM_DEBUG("crtc %d is disabled\n", pipe);
 
-               if (HAS_eDP) {
-                       igdng_disable_pll_edp(crtc);
+               udelay(100);
+
+               /* Disable PF */
+               temp = I915_READ(pf_ctl_reg);
+               if ((temp & PF_ENABLE) != 0) {
+                       I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+                       I915_READ(pf_ctl_reg);
                }
+               I915_WRITE(pf_win_size, 0);
 
                /* disable CPU FDI tx and PCH FDI rx */
                temp = I915_READ(fdi_tx_reg);
@@ -1425,6 +1440,13 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
 
                udelay(100);
 
+               if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+                       temp = I915_READ(PCH_LVDS);
+                       I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN);
+                       I915_READ(PCH_LVDS);
+                       udelay(100);
+               }
+
                /* disable PCH transcoder */
                temp = I915_READ(transconf_reg);
                if ((temp & TRANS_ENABLE) != 0) {
@@ -1444,6 +1466,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
                        }
                }
 
+               udelay(100);
+
                /* disable PCH DPLL */
                temp = I915_READ(pch_dpll_reg);
                if ((temp & DPLL_VCO_ENABLE) != 0) {
@@ -1451,14 +1475,20 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
                        I915_READ(pch_dpll_reg);
                }
 
-               temp = I915_READ(fdi_rx_reg);
-               if ((temp & FDI_RX_PLL_ENABLE) != 0) {
-                       temp &= ~FDI_SEL_PCDCLK;
-                       temp &= ~FDI_RX_PLL_ENABLE;
-                       I915_WRITE(fdi_rx_reg, temp);
-                       I915_READ(fdi_rx_reg);
+               if (HAS_eDP) {
+                       igdng_disable_pll_edp(crtc);
                }
 
+               temp = I915_READ(fdi_rx_reg);
+               temp &= ~FDI_SEL_PCDCLK;
+               I915_WRITE(fdi_rx_reg, temp);
+               I915_READ(fdi_rx_reg);
+
+               temp = I915_READ(fdi_rx_reg);
+               temp &= ~FDI_RX_PLL_ENABLE;
+               I915_WRITE(fdi_rx_reg, temp);
+               I915_READ(fdi_rx_reg);
+
                /* Disable CPU FDI TX PLL */
                temp = I915_READ(fdi_tx_reg);
                if ((temp & FDI_TX_PLL_ENABLE) != 0) {
@@ -1467,16 +1497,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
                        udelay(100);
                }
 
-               /* Disable PF */
-               temp = I915_READ(pf_ctl_reg);
-               if ((temp & PF_ENABLE) != 0) {
-                       I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
-                       I915_READ(pf_ctl_reg);
-               }
-               I915_WRITE(pf_win_size, 0);
-
                /* Wait for the clocks to turn off. */
-               udelay(150);
+               udelay(100);
                break;
        }
 }