[PATCH v2 4/6] drm/xe: Add plumbing for indirect context workarounds

Tvrtko Ursulin tvrtko.ursulin at igalia.com
Mon Jun 2 11:19:54 UTC 2025


Some upcoming workarounds need to be emitted from the indirect workaround
context so lets add some plumbing where they will be able to easily slot
in.

No functional changes for now since everything is still deactivated.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at igalia.com>
Cc: Lucas De Marchi <lucas.demarchi at intel.com>
Cc: Matt Roper <matthew.d.roper at intel.com>
---
 drivers/gpu/drm/xe/regs/xe_lrc_layout.h |  4 ++
 drivers/gpu/drm/xe/xe_lrc.c             | 60 +++++++++++++++++++++++++
 drivers/gpu/drm/xe/xe_lrc_types.h       |  3 +-
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/regs/xe_lrc_layout.h b/drivers/gpu/drm/xe/regs/xe_lrc_layout.h
index 994af591a2e8..06c3a24ac381 100644
--- a/drivers/gpu/drm/xe/regs/xe_lrc_layout.h
+++ b/drivers/gpu/drm/xe/regs/xe_lrc_layout.h
@@ -12,6 +12,8 @@
 #define CTX_RING_START			(0x08 + 1)
 #define CTX_RING_CTL			(0x0a + 1)
 #define CTX_BB_PER_CTX_PTR		(0x12 + 1)
+#define CTX_CS_INDIRECT_CTX		(0x14 + 1)
+#define CTX_CS_INDIRECT_CTX_OFFSET	(0x16 + 1)
 #define CTX_TIMESTAMP			(0x22 + 1)
 #define CTX_TIMESTAMP_UDW		(0x24 + 1)
 #define CTX_INDIRECT_RING_STATE		(0x26 + 1)
@@ -36,4 +38,6 @@
 #define INDIRECT_CTX_RING_START_UDW	(0x08 + 1)
 #define INDIRECT_CTX_RING_CTL		(0x0a + 1)
 
+#define XELP_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT	0xd
+
 #endif
diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index a627e4503518..6bc71f78fea1 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -39,6 +39,7 @@
 #define LRC_ENGINE_INSTANCE			GENMASK_ULL(53, 48)
 
 #define LRC_PPHWSP_SIZE				SZ_4K
+#define LRC_INDIRECT_CTX_SIZE			SZ_4K
 #define LRC_INDIRECT_RING_STATE_SIZE		SZ_4K
 
 static struct xe_device *
@@ -47,6 +48,12 @@ lrc_to_xe(struct xe_lrc *lrc)
 	return gt_to_xe(lrc->fence_ctx.gt);
 }
 
+static bool
+gt_engine_needs_indirect_ctx(struct xe_gt *gt, enum xe_engine_class class)
+{
+	return false;
+}
+
 size_t xe_gt_lrc_size(struct xe_gt *gt, enum xe_engine_class class)
 {
 	struct xe_device *xe = gt_to_xe(gt);
@@ -79,6 +86,9 @@ size_t xe_gt_lrc_size(struct xe_gt *gt, enum xe_engine_class class)
 		size += 1 * SZ_4K;
 	}
 
+	if (gt_engine_needs_indirect_ctx(gt, class))
+		size += LRC_INDIRECT_CTX_SIZE;
+
 	/* Add indirect ring state page */
 	if (xe_gt_has_indirect_ring_state(gt))
 		size += LRC_INDIRECT_RING_STATE_SIZE;
@@ -989,6 +999,50 @@ static void xe_lrc_setup_wa_bb(struct xe_lrc *lrc)
 			     xe_bo_ggtt_addr(lrc->bb_per_ctx_bo) | 1);
 }
 
+static unsigned int
+xelp_setup_indirect_ctx_rcs(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
+			    struct iosys_map *map, unsigned int offset)
+{
+	return offset;
+}
+
+static void
+xelp_setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe)
+{
+	struct xe_device *xe = lrc_to_xe(lrc);
+	struct iosys_map map = lrc->bo->vmap;
+	unsigned int start, offset;
+
+	if (!(lrc->flags & XE_LRC_FLAG_INDIRECT_CTX))
+		return;
+
+	offset = lrc->size - LRC_INDIRECT_CTX_SIZE;
+	iosys_map_incr(&map, offset);
+	offset /= sizeof(u32);
+	start = offset;
+
+	if (hwe->class == XE_ENGINE_CLASS_RENDER ||
+	    hwe->class == XE_ENGINE_CLASS_COMPUTE)
+		offset = xelp_setup_indirect_ctx_rcs(lrc, hwe, &map, offset);
+	else
+		XE_WARN_ON(1);
+
+	/* Align to 64B cacheline. */
+	while (offset & 0xf) {
+		xe_map_write32(xe, &map, MI_NOOP);
+		iosys_map_incr(&map, sizeof(u32));
+		offset++;
+	}
+
+	xe_lrc_write_ctx_reg(lrc,
+			     CTX_CS_INDIRECT_CTX,
+			     (xe_bo_ggtt_addr(lrc->bo) + start * sizeof(u32)) |
+			     ((offset - start) * sizeof(u32) / 64) /* Size in CLs. */);
+	xe_lrc_write_ctx_reg(lrc,
+			     CTX_CS_INDIRECT_CTX_OFFSET,
+			     XELP_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT << 6);
+}
+
 #define PVC_CTX_ASID		(0x2e + 1)
 #define PVC_CTX_ACC_CTR_THOLD	(0x2a + 1)
 
@@ -1012,6 +1066,10 @@ static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
 	lrc->size = ring_size + lrc_size;
 	lrc->ring.size = ring_size;
 	lrc->ring.tail = 0;
+
+	if (gt_engine_needs_indirect_ctx(gt, hwe->class))
+		lrc->flags |= XE_LRC_FLAG_INDIRECT_CTX;
+
 	if (xe_gt_has_indirect_ring_state(gt))
 		lrc->flags |= XE_LRC_FLAG_INDIRECT_RING_STATE;
 
@@ -1142,6 +1200,8 @@ static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
 
 	xe_lrc_setup_wa_bb(lrc);
 
+	xelp_setup_indirect_ctx(lrc, hwe);
+
 	return 0;
 
 err_lrc_finish:
diff --git a/drivers/gpu/drm/xe/xe_lrc_types.h b/drivers/gpu/drm/xe/xe_lrc_types.h
index 559c7c831212..9ce7d02ef210 100644
--- a/drivers/gpu/drm/xe/xe_lrc_types.h
+++ b/drivers/gpu/drm/xe/xe_lrc_types.h
@@ -29,7 +29,8 @@ struct xe_lrc {
 	struct xe_gt *gt;
 
 	/** @flags: LRC flags */
-#define XE_LRC_FLAG_INDIRECT_RING_STATE		0x1
+#define XE_LRC_FLAG_INDIRECT_CTX		0x1
+#define XE_LRC_FLAG_INDIRECT_RING_STATE		0x2
 	u32 flags;
 
 	/** @refcount: ref count of this lrc */
-- 
2.48.0



More information about the Intel-xe mailing list