[PATCH 53/54] drm/i915/gt: Implement ring scheduler for gen4/5

Chris Wilson chris at chris-wilson.co.uk
Fri Jan 1 18:46:10 UTC 2021


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/gen2_engine_cs.c      | 64 +++++++++++++++++++
 drivers/gpu/drm/i915/gt/gen2_engine_cs.h      |  2 +
 .../gpu/drm/i915/gt/intel_ring_scheduler.c    | 47 ++++++++++----
 3 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen2_engine_cs.c b/drivers/gpu/drm/i915/gt/gen2_engine_cs.c
index b491a64919c8..1fe2fd678eda 100644
--- a/drivers/gpu/drm/i915/gt/gen2_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen2_engine_cs.c
@@ -177,6 +177,70 @@ u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs)
 	return __gen2_emit_breadcrumb(rq, cs, 8, 8);
 }
 
+static unsigned long phys_seqno(const u32 *hwsp)
+{
+	unsigned long addr;
+
+	addr = virt_to_phys((volatile void *)hwsp);
+	GEM_BUG_ON(overflows_type(addr, u32)); /* expected dma32 */
+
+	return addr;
+}
+
+static u32 *__gen4_emit_breadcrumb(struct i915_request *rq, u32 *cs,
+				   int flush, int post)
+{
+	struct intel_timeline *tl = rcu_dereference_protected(rq->timeline, 1);
+	u32 offset = __i915_request_hwsp_offset(rq);
+
+	GEM_BUG_ON(tl->mode == INTEL_TIMELINE_RELATIVE_CONTEXT);
+
+	*cs++ = MI_FLUSH;
+
+	while (flush--) {
+		*cs++ = MI_STORE_DWORD_INDEX;
+		*cs++ = I915_GEM_HWS_SCRATCH * sizeof(u32);
+		*cs++ = rq->fence.seqno;
+	}
+
+	if (intel_timeline_is_relative(tl)) {
+		offset = offset_in_page(offset);
+		while (post--) {
+			*cs++ = MI_STORE_DWORD_INDEX;
+			*cs++ = offset;
+			*cs++ = rq->fence.seqno;
+			*cs++ = MI_NOOP;
+		}
+	} else {
+		u32 cmd;
+
+		cmd = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
+		if (IS_I965G(rq->engine->i915)) {
+			offset = phys_seqno(rq->hwsp_seqno);
+			cmd &= ~MI_USE_GGTT;
+		}
+
+		while (post--) {
+			*cs++ = cmd;
+			*cs++ = 0;
+			*cs++ = offset;
+			*cs++ = rq->fence.seqno;
+		}
+	}
+
+	*cs++ = MI_USER_INTERRUPT;
+
+	rq->tail = intel_ring_offset(rq, cs);
+	assert_ring_tail_valid(rq->ring, rq->tail);
+
+	return cs;
+}
+
+u32 *gen4_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs)
+{
+	return __gen4_emit_breadcrumb(rq, cs, 8, 8);
+}
+
 /* Just userspace ABI convention to limit the wa batch bo to a resonable size */
 #define I830_BATCH_LIMIT SZ_256K
 #define I830_TLB_ENTRIES (2)
diff --git a/drivers/gpu/drm/i915/gt/gen2_engine_cs.h b/drivers/gpu/drm/i915/gt/gen2_engine_cs.h
index a5cd64a65c9e..e2083340f72e 100644
--- a/drivers/gpu/drm/i915/gt/gen2_engine_cs.h
+++ b/drivers/gpu/drm/i915/gt/gen2_engine_cs.h
@@ -18,6 +18,8 @@ int gen4_emit_flush_vcs(struct i915_request *rq, u32 mode);
 u32 *gen3_emit_breadcrumb(struct i915_request *rq, u32 *cs);
 u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs);
 
+u32 *gen4_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs);
+
 int i830_emit_bb_start(struct i915_request *rq,
 		       u64 offset, u32 len,
 		       unsigned int dispatch_flags);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c b/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c
index 0979adfa4159..418476145f2a 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c
@@ -1006,8 +1006,16 @@ static void ring_release(struct intel_engine_cs *engine)
 
 static void setup_irq(struct intel_engine_cs *engine)
 {
-	engine->irq_enable = gen6_irq_enable;
-	engine->irq_disable = gen6_irq_disable;
+	if (INTEL_GEN(engine->i915) >= 6) {
+		engine->irq_enable = gen6_irq_enable;
+		engine->irq_disable = gen6_irq_disable;
+	} else if (INTEL_GEN(engine->i915) >= 5) {
+		engine->irq_enable = gen5_irq_enable;
+		engine->irq_disable = gen5_irq_disable;
+	} else {
+		engine->irq_enable = gen3_irq_enable;
+		engine->irq_disable = gen3_irq_disable;
+	}
 }
 
 static void setup_common(struct intel_engine_cs *engine)
@@ -1016,7 +1024,7 @@ static void setup_common(struct intel_engine_cs *engine)
 
 	/* gen8+ are only supported with execlists */
 	GEM_BUG_ON(INTEL_GEN(i915) >= 8);
-	GEM_BUG_ON(INTEL_GEN(i915) < 6);
+	GEM_BUG_ON(INTEL_GEN(i915) < 4);
 
 	setup_irq(engine);
 
@@ -1038,10 +1046,15 @@ static void setup_common(struct intel_engine_cs *engine)
 
 	if (INTEL_GEN(i915) >= 7)
 		engine->emit_fini_breadcrumb = gen7_emit_breadcrumb_xcs;
-	else
+	else if (INTEL_GEN(i915) >= 6)
 		engine->emit_fini_breadcrumb = gen6_emit_breadcrumb_xcs;
+	else
+		engine->emit_fini_breadcrumb = gen4_emit_breadcrumb_xcs;
 
-	engine->emit_bb_start = gen6_emit_bb_start;
+	if (INTEL_GEN(i915) >= 6)
+		engine->emit_bb_start = gen6_emit_bb_start;
+	else
+		engine->emit_bb_start = gen4_emit_bb_start;
 
 	engine->set_default_submission = set_default_submission;
 }
@@ -1060,19 +1073,31 @@ static void setup_rcs(struct intel_engine_cs *engine)
 		engine->emit_fini_breadcrumb = gen7_emit_breadcrumb_rcs;
 		if (IS_HASWELL(i915))
 			engine->emit_bb_start = hsw_emit_bb_start;
-	} else {
+	} else if (INTEL_GEN(i915) >= 6) {
 		engine->emit_flush = gen6_emit_flush_rcs;
 		engine->emit_fini_breadcrumb = gen6_emit_breadcrumb_rcs;
+	} else if (INTEL_GEN(i915) >= 5) {
+		engine->emit_flush = gen4_emit_flush_rcs;
+	} else {
+		engine->emit_flush = gen4_emit_flush_rcs;
+		engine->irq_enable_mask = I915_USER_INTERRUPT;
 	}
 }
 
 static void setup_vcs(struct intel_engine_cs *engine)
 {
-	engine->emit_flush = gen6_emit_flush_vcs;
-	engine->irq_enable_mask = GT_BSD_USER_INTERRUPT;
-
-	if (IS_GEN(engine->i915, 6))
-		engine->fw_domain = FORCEWAKE_ALL;
+	if (INTEL_GEN(engine->i915) >= 6) {
+		if (IS_GEN(engine->i915, 6))
+			engine->fw_domain = FORCEWAKE_ALL;
+		engine->emit_flush = gen6_emit_flush_vcs;
+		engine->irq_enable_mask = GT_BSD_USER_INTERRUPT;
+	} else if (INTEL_GEN(engine->i915) >= 5) {
+		engine->emit_flush = gen4_emit_flush_vcs;
+		engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT;
+	} else {
+		engine->emit_flush = gen4_emit_flush_vcs;
+		engine->irq_enable_mask = I915_BSD_USER_INTERRUPT;
+	}
 }
 
 static void setup_bcs(struct intel_engine_cs *engine)
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list