aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-02-19 13:47:30 -0500
committerVille Syrjälä <ville.syrjala@linux.intel.com>2016-02-22 12:28:13 -0500
commitaae8ba844495473cb11298ad263e26e656e6e4b4 (patch)
tree5b36bb6882c812ae29e1ad8e5f6fd6578f03339d
parent2230fde85cfff2966d2f5fb77321a1ac41c2ecb8 (diff)
drm/i915: Make sure pipe interrupts are processed before turning off power well on BDW+
Starting from BDW the DE_PIPE interrupts for pipe B and C belong to the relevant display power well. So we should make sure we've finished processing them before turning off the power well. The pipe interrupts shouldn't really happen at this point anymore since we've already shut down the planes/pipes/whatnot, but being a bit paranoid shouldn't hurt. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1455907651-16397-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak <imre.deak@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c16
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c19
3 files changed, 37 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d56c261ad867..a9048e1b96e5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3366,6 +3366,22 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
3366 spin_unlock_irq(&dev_priv->irq_lock); 3366 spin_unlock_irq(&dev_priv->irq_lock);
3367} 3367}
3368 3368
3369void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
3370 unsigned int pipe_mask)
3371{
3372 spin_lock_irq(&dev_priv->irq_lock);
3373 if (pipe_mask & 1 << PIPE_A)
3374 GEN8_IRQ_RESET_NDX(DE_PIPE, PIPE_A);
3375 if (pipe_mask & 1 << PIPE_B)
3376 GEN8_IRQ_RESET_NDX(DE_PIPE, PIPE_B);
3377 if (pipe_mask & 1 << PIPE_C)
3378 GEN8_IRQ_RESET_NDX(DE_PIPE, PIPE_C);
3379 spin_unlock_irq(&dev_priv->irq_lock);
3380
3381 /* make sure we're done processing display irqs */
3382 synchronize_irq(dev_priv->dev->irq);
3383}
3384
3369static void cherryview_irq_preinstall(struct drm_device *dev) 3385static void cherryview_irq_preinstall(struct drm_device *dev)
3370{ 3386{
3371 struct drm_i915_private *dev_priv = dev->dev_private; 3387 struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c208ca630e99..4852049c9ab3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -993,6 +993,8 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
993int intel_get_crtc_scanline(struct intel_crtc *crtc); 993int intel_get_crtc_scanline(struct intel_crtc *crtc);
994void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, 994void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
995 unsigned int pipe_mask); 995 unsigned int pipe_mask);
996void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
997 unsigned int pipe_mask);
996 998
997/* intel_crt.c */ 999/* intel_crt.c */
998void intel_crt_init(struct drm_device *dev); 1000void intel_crt_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index ec4faae49b3f..e2329768902c 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -284,6 +284,13 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
284 1 << PIPE_C | 1 << PIPE_B); 284 1 << PIPE_C | 1 << PIPE_B);
285} 285}
286 286
287static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv)
288{
289 if (IS_BROADWELL(dev_priv))
290 gen8_irq_power_well_pre_disable(dev_priv,
291 1 << PIPE_C | 1 << PIPE_B);
292}
293
287static void skl_power_well_post_enable(struct drm_i915_private *dev_priv, 294static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
288 struct i915_power_well *power_well) 295 struct i915_power_well *power_well)
289{ 296{
@@ -309,6 +316,14 @@ static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
309 } 316 }
310} 317}
311 318
319static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv,
320 struct i915_power_well *power_well)
321{
322 if (power_well->data == SKL_DISP_PW_2)
323 gen8_irq_power_well_pre_disable(dev_priv,
324 1 << PIPE_C | 1 << PIPE_B);
325}
326
312static void hsw_set_power_well(struct drm_i915_private *dev_priv, 327static void hsw_set_power_well(struct drm_i915_private *dev_priv,
313 struct i915_power_well *power_well, bool enable) 328 struct i915_power_well *power_well, bool enable)
314{ 329{
@@ -334,6 +349,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
334 349
335 } else { 350 } else {
336 if (enable_requested) { 351 if (enable_requested) {
352 hsw_power_well_pre_disable(dev_priv);
337 I915_WRITE(HSW_PWR_WELL_DRIVER, 0); 353 I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
338 POSTING_READ(HSW_PWR_WELL_DRIVER); 354 POSTING_READ(HSW_PWR_WELL_DRIVER);
339 DRM_DEBUG_KMS("Requesting to disable the power well\n"); 355 DRM_DEBUG_KMS("Requesting to disable the power well\n");
@@ -709,6 +725,9 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
709 state_mask = SKL_POWER_WELL_STATE(power_well->data); 725 state_mask = SKL_POWER_WELL_STATE(power_well->data);
710 is_enabled = tmp & state_mask; 726 is_enabled = tmp & state_mask;
711 727
728 if (!enable && enable_requested)
729 skl_power_well_pre_disable(dev_priv, power_well);
730
712 if (enable) { 731 if (enable) {
713 if (!enable_requested) { 732 if (!enable_requested) {
714 WARN((tmp & state_mask) && 733 WARN((tmp & state_mask) &&