[PATCH 3/6] drm/i915: Apply context workarounds directly

Oscar Mateo oscar.mateo at intel.com
Thu Feb 15 19:42:11 UTC 2018


Once upon a time, we tried to apply workarounds for registers that lived
inside the context image for every new context. That meant emitting LRI
commands soon after each context was created. Nowadays, we have a single
golden context that gets used as a master template for future contexts.

That golden context will acquire initial values for its image from the
existing values in HW (thanks to inhibit restore bit). If all WAs are
applied (normally, using MMIO writes) before that happens, they will
get soaked up by the golden context and transmitted correctly.

Signed-off-by: Oscar Mateo <oscar.mateo at intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c  |  2 +-
 drivers/gpu/drm/i915/intel_lrc.c         |  4 --
 drivers/gpu/drm/i915/intel_ringbuffer.c  |  4 --
 drivers/gpu/drm/i915/intel_workarounds.c | 87 ++++++++++----------------------
 drivers/gpu/drm/i915/intel_workarounds.h |  3 +-
 5 files changed, 30 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a5ada99..45a9d19 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -459,7 +459,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
 	GEM_BUG_ON(dev_priv->kernel_context);
 	GEM_BUG_ON(dev_priv->preempt_context);
 
-	ret = intel_ctx_workarounds_init(dev_priv);
+	ret = intel_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 39d43bb..f792ce2 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1908,10 +1908,6 @@ static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
 {
 	int ret;
 
-	ret = intel_ctx_workarounds_emit(req);
-	if (ret)
-		return ret;
-
 	ret = intel_rcs_context_init_mocs(req);
 	/*
 	 * Failing to program the MOCS is non-fatal.The system will not
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 0b6c20f..5b3d308 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -600,10 +600,6 @@ static int intel_rcs_ctx_init(struct drm_i915_gem_request *req)
 {
 	int ret;
 
-	ret = intel_ctx_workarounds_emit(req);
-	if (ret != 0)
-		return ret;
-
 	ret = i915_gem_render_state_emit(req);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index 9e8c6d4..3be41a9 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -22,6 +22,8 @@ static int wa_add(struct drm_i915_private *dev_priv,
 
 	dev_priv->workarounds.count++;
 
+	I915_WRITE(addr, val);
+
 	return 0;
 }
 
@@ -40,7 +42,7 @@ static int wa_add(struct drm_i915_private *dev_priv,
 #define WA_SET_FIELD_MASKED(addr, mask, value) \
 	WA_REG(addr, mask, _MASKED_FIELD(mask, value))
 
-static int gen8_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int gen8_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
 
@@ -89,11 +91,11 @@ static int gen8_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int bdw_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int bdw_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen8_ctx_workarounds_init(dev_priv);
+	ret = gen8_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
@@ -120,11 +122,11 @@ static int bdw_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int chv_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int chv_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen8_ctx_workarounds_init(dev_priv);
+	ret = gen8_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
@@ -137,7 +139,7 @@ static int chv_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int gen9_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int gen9_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	if (HAS_LLC(dev_priv)) {
 		/* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
@@ -270,22 +272,22 @@ static int skl_tune_iz_hashing(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int skl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int skl_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen9_ctx_workarounds_init(dev_priv);
+	ret = gen9_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
 	return skl_tune_iz_hashing(dev_priv);
 }
 
-static int bxt_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int bxt_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen9_ctx_workarounds_init(dev_priv);
+	ret = gen9_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
@@ -300,11 +302,11 @@ static int bxt_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int kbl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int kbl_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen9_ctx_workarounds_init(dev_priv);
+	ret = gen9_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
@@ -326,11 +328,11 @@ static int kbl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int glk_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int glk_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen9_ctx_workarounds_init(dev_priv);
+	ret = gen9_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
@@ -341,11 +343,11 @@ static int glk_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int cfl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int cfl_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	ret = gen9_ctx_workarounds_init(dev_priv);
+	ret = gen9_ctx_workarounds_apply(dev_priv);
 	if (ret)
 		return ret;
 
@@ -361,7 +363,7 @@ static int cfl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int cnl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+static int cnl_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	/* WaForceContextSaveRestoreNonCoherent:cnl */
 	WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
@@ -399,7 +401,7 @@ static int cnl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv)
+int intel_ctx_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	int err;
 
@@ -408,21 +410,21 @@ int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	if (INTEL_GEN(dev_priv) < 8)
 		err = 0;
 	else if (IS_BROADWELL(dev_priv))
-		err = bdw_ctx_workarounds_init(dev_priv);
+		err = bdw_ctx_workarounds_apply(dev_priv);
 	else if (IS_CHERRYVIEW(dev_priv))
-		err = chv_ctx_workarounds_init(dev_priv);
+		err = chv_ctx_workarounds_apply(dev_priv);
 	else if (IS_SKYLAKE(dev_priv))
-		err = skl_ctx_workarounds_init(dev_priv);
+		err = skl_ctx_workarounds_apply(dev_priv);
 	else if (IS_BROXTON(dev_priv))
-		err = bxt_ctx_workarounds_init(dev_priv);
+		err = bxt_ctx_workarounds_apply(dev_priv);
 	else if (IS_KABYLAKE(dev_priv))
-		err = kbl_ctx_workarounds_init(dev_priv);
+		err = kbl_ctx_workarounds_apply(dev_priv);
 	else if (IS_GEMINILAKE(dev_priv))
-		err = glk_ctx_workarounds_init(dev_priv);
+		err = glk_ctx_workarounds_apply(dev_priv);
 	else if (IS_COFFEELAKE(dev_priv))
-		err = cfl_ctx_workarounds_init(dev_priv);
+		err = cfl_ctx_workarounds_apply(dev_priv);
 	else if (IS_CANNONLAKE(dev_priv))
-		err = cnl_ctx_workarounds_init(dev_priv);
+		err = cnl_ctx_workarounds_apply(dev_priv);
 	else {
 		MISSING_CASE(INTEL_GEN(dev_priv));
 		err = 0;
@@ -435,39 +437,6 @@ int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-int intel_ctx_workarounds_emit(struct drm_i915_gem_request *req)
-{
-	struct i915_workarounds *w = &req->i915->workarounds;
-	u32 *cs;
-	int ret, i;
-
-	if (w->count == 0)
-		return 0;
-
-	ret = req->engine->emit_flush(req, EMIT_BARRIER);
-	if (ret)
-		return ret;
-
-	cs = intel_ring_begin(req, (w->count * 2 + 2));
-	if (IS_ERR(cs))
-		return PTR_ERR(cs);
-
-	*cs++ = MI_LOAD_REGISTER_IMM(w->count);
-	for (i = 0; i < w->count; i++) {
-		*cs++ = i915_mmio_reg_offset(w->reg[i].addr);
-		*cs++ = w->reg[i].value;
-	}
-	*cs++ = MI_NOOP;
-
-	intel_ring_advance(req, cs);
-
-	ret = req->engine->emit_flush(req, EMIT_BARRIER);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 }
diff --git a/drivers/gpu/drm/i915/intel_workarounds.h b/drivers/gpu/drm/i915/intel_workarounds.h
index 64f9599..a11a90e 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -7,8 +7,7 @@
 #ifndef _I915_WORKAROUNDS_H_
 #define _I915_WORKAROUNDS_H_
 
-int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv);
-int intel_ctx_workarounds_emit(struct drm_i915_gem_request *req);
+int intel_ctx_workarounds_apply(struct drm_i915_private *dev_priv);
 
 void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);
 
-- 
1.9.1



More information about the Intel-gfx-trybot mailing list