drm/i915/execlists: Clear context-switch interrupt earlier in the reset
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 2 Jan 2018 15:12:32 +0000 (15:12 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 3 Jan 2018 11:01:05 +0000 (11:01 +0000)
Move the clearing of the CS-interrupt into the engine reset phase,
before the current init-hw phase. This helps clarify that we clear the
pending interrupts prior to any restarting of the execlists.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: MichaƂ Winiarski <michal.winiarski@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180102151235.3949-16-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/intel_lrc.c

index 739c33b07c5907f3d75a001d1f18d8a485e79c10..8f699a1c9ed5e750c39d066de2ad2abb81a9e06d 100644 (file)
@@ -1493,18 +1493,6 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
 
        GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));
 
-       /*
-        * Clear any pending interrupt state.
-        *
-        * We do it twice out of paranoia that some of the IIR are double
-        * buffered, and if we only reset it once there may still be
-        * an interrupt pending.
-        */
-       I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
-                  GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
-       I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
-                  GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
-       clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
        execlists->csb_head = -1;
        execlists->active = 0;
 
@@ -1551,6 +1539,24 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
        return init_workarounds_ring(engine);
 }
 
+static void reset_irq(struct intel_engine_cs *engine)
+{
+       struct drm_i915_private *dev_priv = engine->i915;
+
+       /*
+        * Clear any pending interrupt state.
+        *
+        * We do it twice out of paranoia that some of the IIR are double
+        * buffered, and if we only reset it once there may still be
+        * an interrupt pending.
+        */
+       I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
+                  GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
+       I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
+                  GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
+       clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
+}
+
 static void reset_common_ring(struct intel_engine_cs *engine,
                              struct drm_i915_gem_request *request)
 {
@@ -1560,6 +1566,9 @@ static void reset_common_ring(struct intel_engine_cs *engine,
 
        GEM_TRACE("%s seqno=%x\n",
                  engine->name, request ? request->global_seqno : 0);
+
+       reset_irq(engine);
+
        spin_lock_irqsave(&engine->timeline->lock, flags);
 
        /*