@@ -1305,37 +1305,40 @@ static void intel_engine_print_registers(const struct intel_engine_cs *engine,
}
if (HAS_EXECLISTS(dev_priv)) {
- const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX];
+ const u32 *hws = execlists->csb_status;
+ const u8 entries = execlists->csb_size;
unsigned int idx;
u8 read, write;
- drm_printf(m, "\tExeclist status: 0x%08x %08x\n",
+ drm_printf(m, "\tExeclist status: 0x%08x %08x, entries %u\n",
I915_READ(RING_EXECLIST_STATUS_LO(engine)),
- I915_READ(RING_EXECLIST_STATUS_HI(engine)));
+ I915_READ(RING_EXECLIST_STATUS_HI(engine)),
+ entries);
read = execlists->csb_head;
write = READ_ONCE(*execlists->csb_write);
drm_printf(m, "\tExeclist CSB read %d, write %d [mmio:%d], tasklet queued? %s (%s)\n",
read, write,
- GEN8_CSB_WRITE_PTR(I915_READ(RING_CONTEXT_STATUS_PTR(engine))),
+ I915_READ(RING_CONTEXT_STATUS_PTR(engine)) &
+ GEN11_CSB_WRITE_PTR_MASK,
yesno(test_bit(TASKLET_STATE_SCHED,
&engine->execlists.tasklet.state)),
enableddisabled(!atomic_read(&engine->execlists.tasklet.count)));
- if (read >= GEN8_CSB_ENTRIES)
+ if (read >= entries)
read = 0;
- if (write >= GEN8_CSB_ENTRIES)
+ if (write >= entries)
write = 0;
if (read > write)
- write += GEN8_CSB_ENTRIES;
+ write += entries;
while (read < write) {
- idx = ++read % GEN8_CSB_ENTRIES;
+ idx = ++read % entries;
drm_printf(m, "\tExeclist CSB[%d]: 0x%08x [mmio:0x%08x], context: %d [mmio:%d]\n",
idx,
hws[idx * 2],
- I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)),
+ I915_READ(RING_CSB_LO(engine, idx)),
hws[idx * 2 + 1],
- I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx)));
+ I915_READ(RING_CSB_HI(engine, idx)));
}
rcu_read_lock();
@@ -760,7 +760,7 @@ invalidate_csb_entries(const u32 *first, const u32 *last)
static void reset_csb_pointers(struct intel_engine_execlists *execlists)
{
- const unsigned int reset_value = GEN8_CSB_ENTRIES - 1;
+ const unsigned int reset_value = execlists->csb_size - 1;
/*
* After a reset, the HW starts writing into CSB entry [0]. We
@@ -867,7 +867,7 @@ static void process_csb(struct intel_engine_cs *engine)
struct intel_engine_execlists * const execlists = &engine->execlists;
struct execlist_port *port = execlists->port;
const u32 * const buf = execlists->csb_status;
- u8 head, tail;
+ u8 head, tail, entries;
/*
* Note that csb_write, csb_status may be either in HWSP or mmio.
@@ -885,6 +885,8 @@ static void process_csb(struct intel_engine_cs *engine)
if (unlikely(head == tail))
return;
+ entries = execlists->csb_size;
+
/*
* Hopefully paired with a wmb() in HW!
*
@@ -900,7 +902,7 @@ static void process_csb(struct intel_engine_cs *engine)
unsigned int status;
unsigned int count;
- if (++head == GEN8_CSB_ENTRIES)
+ if (++head == entries)
head = 0;
/*
@@ -2252,6 +2254,8 @@ static int logical_ring_init(struct intel_engine_cs *engine)
execlists->csb_write =
&engine->status_page.page_addr[intel_hws_csb_write_index(i915)];
+ execlists->csb_size = GEN8_CSB_ENTRIES;
+
reset_csb_pointers(execlists);
return 0;
@@ -36,9 +36,13 @@
#define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT (1 << 0)
#define CTX_CTRL_RS_CTX_ENABLE (1 << 1)
#define CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT (1 << 2)
-#define RING_CONTEXT_STATUS_BUF_BASE(engine) _MMIO((engine)->mmio_base + 0x370)
-#define RING_CONTEXT_STATUS_BUF_LO(engine, i) _MMIO((engine)->mmio_base + 0x370 + (i) * 8)
-#define RING_CONTEXT_STATUS_BUF_HI(engine, i) _MMIO((engine)->mmio_base + 0x370 + (i) * 8 + 4)
+
+#define _RING_CSB_OFFSET(i) ((i) < 6 ? \
+ (0x370 + (i) * 8) : \
+ (0x3c0 + ((i) - 6) * 8))
+#define RING_CSB_OFFSET(engine, i) ((engine)->mmio_base + _RING_CSB_OFFSET(i))
+#define RING_CSB_LO(engine, i) _MMIO(RING_CSB_OFFSET(engine, i))
+#define RING_CSB_HI(engine, i) _MMIO(RING_CSB_OFFSET(engine, i) + 4)
#define RING_CONTEXT_STATUS_PTR(engine) _MMIO((engine)->mmio_base + 0x3a0)
#define RING_EXECLIST_SQ_CONTENTS(engine) _MMIO((engine)->mmio_base + 0x510)
#define RING_EXECLIST_CONTROL(engine) _MMIO((engine)->mmio_base + 0x550)
@@ -55,10 +59,11 @@
#define GEN8_CSB_PTR_MASK 0x7
#define GEN8_CSB_READ_PTR_MASK (GEN8_CSB_PTR_MASK << 8)
#define GEN8_CSB_WRITE_PTR_MASK (GEN8_CSB_PTR_MASK << 0)
-#define GEN8_CSB_WRITE_PTR(csb_status) \
- (((csb_status) & GEN8_CSB_WRITE_PTR_MASK) >> 0)
-#define GEN8_CSB_READ_PTR(csb_status) \
- (((csb_status) & GEN8_CSB_READ_PTR_MASK) >> 8)
+
+#define GEN11_CSB_ENTRIES 12
+#define GEN11_CSB_PTR_MASK 0xf
+#define GEN11_CSB_READ_PTR_MASK (GEN11_CSB_PTR_MASK << 8)
+#define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0)
enum {
INTEL_CONTEXT_SCHEDULE_IN = 0,
@@ -332,6 +332,11 @@ struct intel_engine_execlists {
*/
u32 preempt_complete_status;
+ /**
+ * @csb_size: context status buffer FIFO size
+ */
+ u8 csb_size;
+
/**
* @csb_head: context status buffer head
*/
Make csb entry count variable in preparation for larger CSB status FIFO size found on gen11+ hardware. v2: adapt to hwsp access only (Chris) non continuous mmio (Daniele) Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> --- drivers/gpu/drm/i915/intel_engine_cs.c | 23 +++++++++++++---------- drivers/gpu/drm/i915/intel_lrc.c | 10 +++++++--- drivers/gpu/drm/i915/intel_lrc.h | 19 ++++++++++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +++++ 4 files changed, 37 insertions(+), 20 deletions(-)