diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2013-12-05 08:51:37 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-12-17 07:17:56 -0500 |
commit | 017636cc09e2c58bc493cc1fe74d858f50d173af (patch) | |
tree | a22697805e4aa021c311bed1d8db250c8b8f8341 /drivers/gpu/drm/i915/intel_pm.c | |
parent | ce0e0713a6b21ec611d4a2eb5c60d18dbb4bf479 (diff) |
drm/i915: Disable LP1+ watermarks safely in init
ILK doesn't like if we just write the LP1+ watermarks registers with 0.
We need to just disable the watermarks by clearing the enable bit. Use
that method also when disabling LP1+ watermarks in init_clock_gating.
It looks like disabling the sprite LP1 watermarks can cause underruns
even if we just toggle the WM1S_LP_EN bit. So treat that bit like the
actual watermark numbers and avoid setting it to 0 immediately.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 276e98df1c0d..e321fbc28a0b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5051,6 +5051,20 @@ static void g4x_disable_trickle_feed(struct drm_device *dev) | |||
5051 | } | 5051 | } |
5052 | } | 5052 | } |
5053 | 5053 | ||
5054 | static void ilk_init_lp_watermarks(struct drm_device *dev) | ||
5055 | { | ||
5056 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5057 | |||
5058 | I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); | ||
5059 | I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); | ||
5060 | I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); | ||
5061 | |||
5062 | /* | ||
5063 | * Don't touch WM1S_LP_EN here. | ||
5064 | * Doing so could cause underruns. | ||
5065 | */ | ||
5066 | } | ||
5067 | |||
5054 | static void ironlake_init_clock_gating(struct drm_device *dev) | 5068 | static void ironlake_init_clock_gating(struct drm_device *dev) |
5055 | { | 5069 | { |
5056 | struct drm_i915_private *dev_priv = dev->dev_private; | 5070 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5084,9 +5098,8 @@ static void ironlake_init_clock_gating(struct drm_device *dev) | |||
5084 | I915_WRITE(DISP_ARB_CTL, | 5098 | I915_WRITE(DISP_ARB_CTL, |
5085 | (I915_READ(DISP_ARB_CTL) | | 5099 | (I915_READ(DISP_ARB_CTL) | |
5086 | DISP_FBC_WM_DIS)); | 5100 | DISP_FBC_WM_DIS)); |
5087 | I915_WRITE(WM3_LP_ILK, 0); | 5101 | |
5088 | I915_WRITE(WM2_LP_ILK, 0); | 5102 | ilk_init_lp_watermarks(dev); |
5089 | I915_WRITE(WM1_LP_ILK, 0); | ||
5090 | 5103 | ||
5091 | /* | 5104 | /* |
5092 | * Based on the document from hardware guys the following bits | 5105 | * Based on the document from hardware guys the following bits |
@@ -5193,9 +5206,7 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
5193 | I915_WRITE(GEN6_GT_MODE, | 5206 | I915_WRITE(GEN6_GT_MODE, |
5194 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); | 5207 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); |
5195 | 5208 | ||
5196 | I915_WRITE(WM3_LP_ILK, 0); | 5209 | ilk_init_lp_watermarks(dev); |
5197 | I915_WRITE(WM2_LP_ILK, 0); | ||
5198 | I915_WRITE(WM1_LP_ILK, 0); | ||
5199 | 5210 | ||
5200 | I915_WRITE(CACHE_MODE_0, | 5211 | I915_WRITE(CACHE_MODE_0, |
5201 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); | 5212 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); |
@@ -5369,9 +5380,7 @@ static void haswell_init_clock_gating(struct drm_device *dev) | |||
5369 | { | 5380 | { |
5370 | struct drm_i915_private *dev_priv = dev->dev_private; | 5381 | struct drm_i915_private *dev_priv = dev->dev_private; |
5371 | 5382 | ||
5372 | I915_WRITE(WM3_LP_ILK, 0); | 5383 | ilk_init_lp_watermarks(dev); |
5373 | I915_WRITE(WM2_LP_ILK, 0); | ||
5374 | I915_WRITE(WM1_LP_ILK, 0); | ||
5375 | 5384 | ||
5376 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | 5385 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. |
5377 | * This implements the WaDisableRCZUnitClockGating:hsw workaround. | 5386 | * This implements the WaDisableRCZUnitClockGating:hsw workaround. |
@@ -5420,9 +5429,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
5420 | struct drm_i915_private *dev_priv = dev->dev_private; | 5429 | struct drm_i915_private *dev_priv = dev->dev_private; |
5421 | uint32_t snpcr; | 5430 | uint32_t snpcr; |
5422 | 5431 | ||
5423 | I915_WRITE(WM3_LP_ILK, 0); | 5432 | ilk_init_lp_watermarks(dev); |
5424 | I915_WRITE(WM2_LP_ILK, 0); | ||
5425 | I915_WRITE(WM1_LP_ILK, 0); | ||
5426 | 5433 | ||
5427 | I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); | 5434 | I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); |
5428 | 5435 | ||