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

Reply via email to