drm/i915/execlists: Flush GTIIR on clearing CS interrupts during reset
authorChris Wilson <[email protected]>
Fri, 2 Feb 2018 14:54:55 +0000 (14:54 +0000)
committerChris Wilson <[email protected]>
Fri, 2 Feb 2018 20:31:52 +0000 (20:31 +0000)
Be paranoid and flush the GTIIR after clearing the CS interrupt to be
sure it has taken before we re-enable the interrupt handler. We still
see early interrupts following reset, the tasklet handling the mmio read
before it has been written by the CS. This hopefully reduces the
frequency to 0...

References: https://bugs.freedesktop.org/show_bug.cgi?id=104262
Signed-off-by: Chris Wilson <[email protected]>
Cc: Mika Kuoppala <[email protected]>
Cc: Michel Thierry <[email protected]>
Cc: Tvrtko Ursulin <[email protected]>
Acked-by: Michel Thierry <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
drivers/gpu/drm/i915/intel_lrc.c

index 40dbeaee9dfab8f48bf0658302be27aafd96e591..deeedfc9fe449f0492b655efa18dbc61748e833c 100644 (file)
@@ -1527,6 +1527,7 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
 static void reset_irq(struct intel_engine_cs *engine)
 {
        struct drm_i915_private *dev_priv = engine->i915;
+       int i;
 
        /*
         * Clear any pending interrupt state.
@@ -1535,10 +1536,14 @@ static void reset_irq(struct intel_engine_cs *engine)
         * 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);
+       for (i = 0; i < 2; i++) {
+               I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
+                          GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
+               POSTING_READ(GEN8_GT_IIR(gtiir[engine->id]));
+       }
+       GEM_BUG_ON(I915_READ(GEN8_GT_IIR(gtiir[engine->id])) &
+                  (GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift));
+
        clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
 }