[Intel-gfx] [PATCH 19/19] drm/i915/execlists: Repeat CSB mmio until it returns a sensible result
Chris Wilson
chris at chris-wilson.co.uk
Tue Jan 2 15:12:35 UTC 2018
Even though we wait until the HW has sent us its first CS interrupt
before believing that it is powered on, a read from the powercontext
saved CSB registers may still return garbage. So we must wait a little
bit for the right result. This, of course, assumes that we always see an
invalid result when the powercontext is not loaded, otherwise we will
attempt to read stale data.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/intel_lrc.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 2b2c61ed81db..1734fdef052a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -806,7 +806,8 @@ static void execlists_submission_tasklet(unsigned long data)
execlists->csb_head = -1; /* force mmio read of CSB ptrs */
}
- /* The write will be ordered by the uncached read (itself
+ /*
+ * The write will be ordered by the uncached read (itself
* a memory barrier), so we do not need another in the form
* of a locked instruction. The race between the interrupt
* handler and the split test/clear is harmless as we order
@@ -818,8 +819,20 @@ static void execlists_submission_tasklet(unsigned long data)
*/
__clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
if (unlikely(execlists->csb_head == -1)) { /* following a reset */
- head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)));
- tail = GEN8_CSB_WRITE_PTR(head);
+ do {
+ head = readl(dev_priv->regs +
+ i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)));
+ tail = GEN8_CSB_WRITE_PTR(head);
+ /*
+ * We have to wait until the powercontext has
+ * been loaded by the GPU before it starts
+ * reporting correctly. As we sometimes see
+ * an CS interrupt before we are able to
+ * read from the powercontext saved
+ * register, we repeat the read. Baffling and
+ * quite scary.
+ */
+ } while (unlikely(tail >= GEN8_CSB_ENTRIES));
head = GEN8_CSB_READ_PTR(head);
execlists->csb_head = head;
} else {
--
2.15.1
More information about the Intel-gfx
mailing list