Commit a9c1f90c authored by Mika Kuoppala's avatar Mika Kuoppala Committed by Daniel Vetter

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: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Acked-by: default avatarVinit Azad <vinit.azad@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent f33bcab9
...@@ -3447,14 +3447,24 @@ int intel_enable_rc6(const struct drm_device *dev) ...@@ -3447,14 +3447,24 @@ int intel_enable_rc6(const struct drm_device *dev)
static void gen6_enable_rps_interrupts(struct drm_device *dev) static void gen6_enable_rps_interrupts(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 enabled_intrs;
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
WARN_ON(dev_priv->rps.pm_iir); WARN_ON(dev_priv->rps.pm_iir);
snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
spin_unlock_irq(&dev_priv->irq_lock); spin_unlock_irq(&dev_priv->irq_lock);
/* only unmask PM interrupts we need. Mask all others. */ /* only unmask PM interrupts we need. Mask all others. */
I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS); enabled_intrs = GEN6_PM_RPS_EVENTS;
/* IVB and SNB hard hangs on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
*/
if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
enabled_intrs |= GEN6_PM_RP_UP_EI_EXPIRED;
I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs);
} }
static void gen6_enable_rps(struct drm_device *dev) static void gen6_enable_rps(struct drm_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment