diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 4 |
3 files changed, 27 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index fc3bf58d439c..e30d34b08069 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3827,7 +3827,8 @@ #define _TRANSA_CHICKEN2 0xf0064 #define _TRANSB_CHICKEN2 0xf1064 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) -#define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31) +#define TRANS_CHICKEN2_TIMING_OVERRIDE (1<<31) + #define SOUTH_CHICKEN1 0xc2000 #define FDIA_PHASE_SYNC_SHIFT_OVR 19 @@ -4085,7 +4086,7 @@ #define TRANS_DP_CTL_A 0xe0300 #define TRANS_DP_CTL_B 0xe1300 #define TRANS_DP_CTL_C 0xe2300 -#define TRANS_DP_CTL(pipe) (TRANS_DP_CTL_A + (pipe) * 0x01000) +#define TRANS_DP_CTL(pipe) _PIPE(pipe, TRANS_DP_CTL_A, TRANS_DP_CTL_B) #define TRANS_DP_OUTPUT_ENABLE (1<<31) #define TRANS_DP_PORT_SEL_B (0<<29) #define TRANS_DP_PORT_SEL_C (1<<29) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 25a3ed693460..4be95e882d58 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1673,9 +1673,9 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { - int reg; - u32 val, pipeconf_val; + struct drm_device *dev = dev_priv->dev; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + uint32_t reg, val, pipeconf_val; /* PCH only available on ILK+ */ BUG_ON(dev_priv->info->gen < 5); @@ -1689,6 +1689,15 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, assert_fdi_tx_enabled(dev_priv, pipe); assert_fdi_rx_enabled(dev_priv, pipe); + if (HAS_PCH_CPT(dev)) { + /* Workaround: Set the timing override bit before enabling the + * pch transcoder. */ + reg = TRANS_CHICKEN2(pipe); + val = I915_READ(reg); + val |= TRANS_CHICKEN2_TIMING_OVERRIDE; + I915_WRITE(reg, val); + } + reg = TRANSCONF(pipe); val = I915_READ(reg); pipeconf_val = I915_READ(PIPECONF(pipe)); @@ -1731,7 +1740,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, /* Workaround: set timing override bit. */ val = I915_READ(_TRANSA_CHICKEN2); - val |= TRANS_AUTOTRAIN_GEN_STALL_DIS; + val |= TRANS_CHICKEN2_TIMING_OVERRIDE; I915_WRITE(_TRANSA_CHICKEN2, val); val = TRANS_ENABLE; @@ -1751,8 +1760,8 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { - int reg; - u32 val; + struct drm_device *dev = dev_priv->dev; + uint32_t reg, val; /* FDI relies on the transcoder */ assert_fdi_tx_disabled(dev_priv, pipe); @@ -1768,6 +1777,14 @@ static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv, /* wait for PCH transcoder off, transcoder state */ if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) DRM_ERROR("failed to disable transcoder %d\n", pipe); + + if (!HAS_PCH_IBX(dev)) { + /* Workaround: Clear the timing override chicken bit again. */ + reg = TRANS_CHICKEN2(pipe); + val = I915_READ(reg); + val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE; + I915_WRITE(reg, val); + } } static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) @@ -1783,7 +1800,7 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) /* Workaround: clear timing override bit. */ val = I915_READ(_TRANSA_CHICKEN2); - val &= ~TRANS_AUTOTRAIN_GEN_STALL_DIS; + val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE; I915_WRITE(_TRANSA_CHICKEN2, val); } @@ -3327,16 +3344,12 @@ prepare: /* separate function? */ void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; - int dslreg = PIPEDSL(pipe), tc2reg = TRANS_CHICKEN2(pipe); + int dslreg = PIPEDSL(pipe); u32 temp; temp = I915_READ(dslreg); udelay(500); if (wait_for(I915_READ(dslreg) != temp, 5)) { - /* Without this, mode sets may fail silently on FDI */ - I915_WRITE(tc2reg, TRANS_AUTOTRAIN_GEN_STALL_DIS); - udelay(250); - I915_WRITE(tc2reg, 0); if (wait_for(I915_READ(dslreg) != temp, 5)) DRM_ERROR("mode set failed: pipe %d stuck\n", pipe); } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 59c31f6238c1..596d97a68c68 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3794,7 +3794,6 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void cpt_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; /* * On Ibex Peak and Cougar Point, we need to disable clock @@ -3804,9 +3803,6 @@ static void cpt_init_clock_gating(struct drm_device *dev) I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | DPLS_EDP_PPS_FIX_DIS); - /* Without this, mode sets may fail silently on FDI */ - for_each_pipe(pipe) - I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); } void intel_init_clock_gating(struct drm_device *dev) |