aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Kuoppala <mika.kuoppala@linux.intel.com>2013-08-22 14:09:00 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-03 05:10:54 -0400
commita9c1f90c8e1792127f8348c1cc2565b79b2ef20a (patch)
tree19df9921b837a6c4c4a1d937faf1524a4cf768a1
parentf33bcab9e816c5bf56b74c3007790f2a256910eb (diff)
drm/i915: Don't mask EI UP interrupt on IVB|SNB
Submitting a batchbuffer which simulates a gpu hang by doing MI_BATCH_BUFFER_START into itself, to test hangcheck, started to hard hang the whole box (IVB). Bisecting lead to this commit: commit 664b422c2966cd39b8f67e8d53a566ea8c877cd6 Author: Vinit Azad <vinit.azad@intel.com> Date: Wed Aug 14 13:34:33 2013 -0700 drm/i915: Only unmask required PM interrupts Experimenting with the mask register showed that unmasking EI UP will prevent the hard hang in IVB and SNB. HSW doesn't hang with EI UP masked. Considering we are just disabling interrupts that aren't even delivered to driver, this change is more likely to paper over some weirdness in gpu's internal state machine. But until better explanation can be found, let's trade little bit of power for stability on these architectures. v2: - Unmask EI_EXPIRED directly in I915_WRITE (Vinit) v3: - Only unmask on SNB and IVB Cc: Vinit Azad <vinit.azad@intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Acked-by: Vinit Azad <vinit.azad@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 46056820d1d2..6b1d00389952 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3447,14 +3447,24 @@ int intel_enable_rc6(const struct drm_device *dev)
3447static void gen6_enable_rps_interrupts(struct drm_device *dev) 3447static void gen6_enable_rps_interrupts(struct drm_device *dev)
3448{ 3448{
3449 struct drm_i915_private *dev_priv = dev->dev_private; 3449 struct drm_i915_private *dev_priv = dev->dev_private;
3450 u32 enabled_intrs;
3450 3451
3451 spin_lock_irq(&dev_priv->irq_lock); 3452 spin_lock_irq(&dev_priv->irq_lock);
3452 WARN_ON(dev_priv->rps.pm_iir); 3453 WARN_ON(dev_priv->rps.pm_iir);
3453 snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); 3454 snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
3454 I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); 3455 I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
3455 spin_unlock_irq(&dev_priv->irq_lock); 3456 spin_unlock_irq(&dev_priv->irq_lock);
3457
3456 /* only unmask PM interrupts we need. Mask all others. */ 3458 /* only unmask PM interrupts we need. Mask all others. */
3457 I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS); 3459 enabled_intrs = GEN6_PM_RPS_EVENTS;
3460
3461 /* IVB and SNB hard hangs on looping batchbuffer
3462 * if GEN6_PM_UP_EI_EXPIRED is masked.
3463 */
3464 if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
3465 enabled_intrs |= GEN6_PM_RP_UP_EI_EXPIRED;
3466
3467 I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs);
3458} 3468}
3459 3469
3460static void gen6_enable_rps(struct drm_device *dev) 3470static void gen6_enable_rps(struct drm_device *dev)