Skip to content

Commit

Permalink
drm/i915: Fix LVDS stability issue on Ironlake
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Zhenyu Wang authored and Eric Anholt committed Nov 25, 2009
1 parent 4215866 commit 1b3c7a4
Showing 1 changed file with 41 additions and 19 deletions.
60 changes: 41 additions & 19 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
DRM_DEBUG_KMS("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);
Expand Down Expand Up @@ -1674,8 +1683,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_OFF:
DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);

i915_disable_vga(dev);

/* Disable display plane */
temp = I915_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
Expand All @@ -1685,6 +1692,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) {
Expand All @@ -1706,9 +1715,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
} else
DRM_DEBUG_KMS("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);
Expand All @@ -1734,6 +1749,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) {
Expand All @@ -1754,21 +1776,29 @@ 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) {
I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE);
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) {
Expand All @@ -1777,16 +1807,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;
}
}
Expand Down

0 comments on commit 1b3c7a4

Please sign in to comment.