[PATCH 3/3] drm/i915: Emit mocs inside default context setup

Chris Wilson chris at chris-wilson.co.uk
Mon Oct 21 22:11:22 UTC 2019


Restore emission of MOCS registers from inside the default context, as
the L3CC seem to be overloaded by the power context and unable to be set
by the CPU prior to execution on some machines. Although seemingly
redundant, we should be able to cover all bases with the one-off set of
LRI.

Fixes: eca0b7208969 ("drm/i915: Do initial mocs configuration directly")
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Prathap Kumar Valsan <prathap.kumar.valsan at intel.com>
---
 drivers/gpu/drm/i915/gt/intel_mocs.c | 95 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_mocs.h |  2 +
 drivers/gpu/drm/i915/i915_gem.c      |  4 ++
 3 files changed, 101 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c
index f69507fafc21..0767fa33289b 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.c
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.c
@@ -450,6 +450,101 @@ void intel_mocs_init_engine(struct intel_engine_cs *engine)
 		init_l3cc_table(engine, &table);
 }
 
+static int emit_mocs_table(struct i915_request *rq,
+			   const struct drm_i915_mocs_table *table)
+{
+	u32 unused_value = table->table[I915_MOCS_PTE].control_value;
+	unsigned int i;
+	u32 *cs;
+
+	cs = intel_ring_begin(rq, table->n_entries * 2 + 2);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	*cs++ = MI_LOAD_REGISTER_IMM(table->n_entries);
+
+	for (i = 0; i < table->size; i++) {
+		*cs++ = i915_mmio_reg_offset(mocs_register(rq->engine, i));
+		*cs++ = get_entry_control(table, i);
+	}
+
+	/* All remaining entries are unused */
+	for (; i < table->n_entries; i++) {
+		*cs++ = i915_mmio_reg_offset(mocs_register(rq->engine, i));
+		*cs++ = unused_value;
+	}
+
+	*cs++ = MI_NOOP;
+	intel_ring_advance(rq, cs);
+
+	return 0;
+}
+
+static int emit_l3cc_table(struct i915_request *rq,
+			   const struct drm_i915_mocs_table *table)
+{
+	u16 unused_value = table->table[I915_MOCS_PTE].l3cc_value;
+	unsigned int i;
+	u32 *cs;
+
+	cs = intel_ring_begin(rq, table->n_entries + 2);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	*cs++ = MI_LOAD_REGISTER_IMM(table->n_entries / 2);
+
+	for (i = 0; i < table->size / 2; i++) {
+		u16 low = get_entry_l3cc(table, 2 * i);
+		u16 high = get_entry_l3cc(table, 2 * i + 1);
+
+		*cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
+		*cs++ = l3cc_combine(low, high);
+	}
+
+	/* Odd table size - 1 left over */
+	if (table->size & 1) {
+		u16 low = get_entry_l3cc(table, 2 * i);
+
+		*cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
+		*cs++ = l3cc_combine(low, unused_value);
+		i++;
+	}
+
+	/* All remaining entries are also unused */
+	for (; i < table->n_entries / 2; i++) {
+		*cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
+		*cs++ = l3cc_combine(unused_value, unused_value);
+	}
+
+	*cs++ = MI_NOOP;
+	intel_ring_advance(rq, cs);
+
+	return 0;
+}
+
+int intel_mocs_emit_context(struct i915_request *rq)
+{
+	struct drm_i915_mocs_table table;
+	int err;
+
+	if (!get_mocs_settings(rq->i915, &table))
+		return 0;
+
+	if (!HAS_GLOBAL_MOCS_REGISTERS(rq->i915)) {
+		err = emit_mocs_table(rq, &table);
+		if (err)
+			return err;
+	}
+
+	if (rq->engine->class == RENDER_CLASS) {
+		err = emit_l3cc_table(rq, &table);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static void intel_mocs_init_global(struct intel_gt *gt)
 {
 	struct intel_uncore *uncore = gt->uncore;
diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.h b/drivers/gpu/drm/i915/gt/intel_mocs.h
index 83371f3e6ba1..7bd6bfc67543 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.h
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.h
@@ -49,10 +49,12 @@
  * context handling keep the MOCS in step.
  */
 
+struct i915_request;
 struct intel_engine_cs;
 struct intel_gt;
 
 void intel_mocs_init(struct intel_gt *gt);
 void intel_mocs_init_engine(struct intel_engine_cs *engine);
+int intel_mocs_emit_context(struct i915_request *rq);
 
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 39cb0e246a88..54f29fe409c2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1113,6 +1113,10 @@ static int __intel_engines_record_defaults(struct drm_i915_private *i915)
 		if (err)
 			goto err_rq;
 
+		err = intel_mocs_emit_context(rq);
+		if (err)
+			goto err_rq;
+
 		err = intel_renderstate_emit(rq);
 		if (err)
 			goto err_rq;
-- 
2.24.0.rc0



More information about the Intel-gfx-trybot mailing list