[PATCH 19/19] drm/i915/execlists: Repeat CSB mmio until it returns a sensible result

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxx>
---
 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux