We should enable FDI normal training on Sandybridge/CPT system as well. Also restore back some original register posting read that got removed. LVDS/VGA/HDMI seems back to life but DP still fails.
Signed-off-by: Zhenyu Wang <zhen...@linux.intel.com> --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 80 +++++++++++++++++++++++----------- 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5948e05..228c571 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1322,6 +1322,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) +#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a413db6..b6f977b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1685,6 +1685,37 @@ static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) udelay(500); } +static void intel_fdi_normal_train(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + u32 reg, temp; + + /* enable normal train */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; + I915_WRITE(reg, temp); + + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); + if (HAS_PCH_CPT(dev)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_NORMAL_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE; + } + I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); + + /* wait one idle pattern time */ + POSTING_READ(reg); + udelay(1000); +} + /* The FDI link training functions for ILK/Ibexpeak. */ static void ironlake_fdi_link_train(struct drm_crtc *crtc) { @@ -1771,27 +1802,6 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) DRM_DEBUG_KMS("FDI train done\n"); - /* enable normal train */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_NORMAL_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE; - } - I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); - - /* wait one idle pattern time */ - POSTING_READ(reg); - udelay(1000); } static const int const snb_b_fdi_train_param [] = { @@ -1980,7 +1990,7 @@ static void intel_clear_scanline_wait(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; u32 tmp; - if (IS_GEN2(dev)) + if (IS_GEN2(dev) || IS_GEN6(dev)) /* Can't break the hang on i8xx */ return; @@ -2022,8 +2032,10 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { temp = I915_READ(PCH_LVDS); - if ((temp & LVDS_PORT_EN) == 0) + if ((temp & LVDS_PORT_EN) == 0) { I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); + POSTING_READ(PCH_LVDS); + } } ironlake_fdi_enable(crtc); @@ -2083,6 +2095,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0) temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); I915_WRITE(PCH_DPLL_SEL, temp); + POSTING_READ(PCH_DPLL_SEL); } /* set transcoder timing */ @@ -2094,6 +2107,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); + intel_fdi_normal_train(crtc); + /* For PCH DP, enable TRANS_DP_CTL */ if (HAS_PCH_CPT(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { @@ -2204,9 +2219,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) udelay(100); /* Ironlake workaround, disable clock pointer after downing FDI */ - I915_WRITE(FDI_RX_CHICKEN(pipe), - I915_READ(FDI_RX_CHICKEN(pipe) & - ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); + if (HAS_PCH_IBX(dev)) + I915_WRITE(FDI_RX_CHICKEN(pipe), + I915_READ(FDI_RX_CHICKEN(pipe) & + ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); /* still set train pattern 1 */ reg = FDI_TX_CTL(pipe); @@ -2251,12 +2267,21 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) DRM_ERROR("failed to disable transcoder\n"); } + /* keep bpc mask in transcoder */ + temp = I915_READ(reg); + temp &= ~PIPE_BPC_MASK; + temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK); + I915_WRITE(reg, temp); + POSTING_READ(reg); + udelay(100); + if (HAS_PCH_CPT(dev)) { /* disable TRANS_DP_CTL */ reg = TRANS_DP_CTL(pipe); temp = I915_READ(reg); temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); I915_WRITE(reg, temp); + POSTING_READ(reg); /* disable DPLL_SEL */ temp = I915_READ(PCH_DPLL_SEL); @@ -2265,17 +2290,20 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) else temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); I915_WRITE(PCH_DPLL_SEL, temp); + POSTING_READ(PCH_DPLL_SEL); } /* disable PCH DPLL */ reg = PCH_DPLL(pipe); temp = I915_READ(reg); I915_WRITE(reg, temp & ~DPLL_VCO_ENABLE); + POSTING_READ(reg); /* Switch from PCDclk to Rawclk */ reg = FDI_RX_CTL(pipe); temp = I915_READ(reg); I915_WRITE(reg, temp & ~FDI_PCDCLK); + POSTING_READ(reg); /* Disable CPU FDI TX PLL */ reg = FDI_TX_CTL(pipe); -- 1.7.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx