Commit 1b3c7a47 authored by Zhenyu Wang's avatar Zhenyu Wang Committed by Eric Anholt

drm/i915: Fix LVDS stability issue on Ironlake

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: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 42158660
...@@ -1488,6 +1488,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1488,6 +1488,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
DRM_DEBUG_KMS("crtc %d dpms on\n", pipe); 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) { if (HAS_eDP) {
/* enable eDP PLL */ /* enable eDP PLL */
igdng_enable_pll_edp(crtc); igdng_enable_pll_edp(crtc);
...@@ -1674,8 +1683,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1674,8 +1683,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
i915_disable_vga(dev);
/* Disable display plane */ /* Disable display plane */
temp = I915_READ(dspcntr_reg); temp = I915_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) { if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
...@@ -1685,6 +1692,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1685,6 +1692,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_READ(dspbase_reg); I915_READ(dspbase_reg);
} }
i915_disable_vga(dev);
/* disable cpu pipe, disable after all planes disabled */ /* disable cpu pipe, disable after all planes disabled */
temp = I915_READ(pipeconf_reg); temp = I915_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) { if ((temp & PIPEACONF_ENABLE) != 0) {
...@@ -1706,9 +1715,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1706,9 +1715,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
} else } else
DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
if (HAS_eDP) { udelay(100);
igdng_disable_pll_edp(crtc);
/* 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 */ /* disable CPU FDI tx and PCH FDI rx */
temp = I915_READ(fdi_tx_reg); temp = I915_READ(fdi_tx_reg);
...@@ -1734,6 +1749,13 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1734,6 +1749,13 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
udelay(100); 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 */ /* disable PCH transcoder */
temp = I915_READ(transconf_reg); temp = I915_READ(transconf_reg);
if ((temp & TRANS_ENABLE) != 0) { if ((temp & TRANS_ENABLE) != 0) {
...@@ -1754,6 +1776,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1754,6 +1776,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
} }
} }
udelay(100);
/* disable PCH DPLL */ /* disable PCH DPLL */
temp = I915_READ(pch_dpll_reg); temp = I915_READ(pch_dpll_reg);
if ((temp & DPLL_VCO_ENABLE) != 0) { if ((temp & DPLL_VCO_ENABLE) != 0) {
...@@ -1761,13 +1785,19 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1761,13 +1785,19 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_READ(pch_dpll_reg); I915_READ(pch_dpll_reg);
} }
if (HAS_eDP) {
igdng_disable_pll_edp(crtc);
}
temp = I915_READ(fdi_rx_reg); temp = I915_READ(fdi_rx_reg);
if ((temp & FDI_RX_PLL_ENABLE) != 0) {
temp &= ~FDI_SEL_PCDCLK; 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; temp &= ~FDI_RX_PLL_ENABLE;
I915_WRITE(fdi_rx_reg, temp); I915_WRITE(fdi_rx_reg, temp);
I915_READ(fdi_rx_reg); I915_READ(fdi_rx_reg);
}
/* Disable CPU FDI TX PLL */ /* Disable CPU FDI TX PLL */
temp = I915_READ(fdi_tx_reg); temp = I915_READ(fdi_tx_reg);
...@@ -1777,16 +1807,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1777,16 +1807,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
udelay(100); 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. */ /* Wait for the clocks to turn off. */
udelay(150); udelay(100);
break; break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment