[Intel-gfx] [PATCH] drm/i915: RFC: Introduce Wa_14011282866

Matt Atwood matthew.s.atwood at intel.com
Wed May 10 21:58:11 UTC 2023


From: Tilak Tangudu <tilak.tangudu at intel.com>

Wa_14011282866 applies to RKL, ADL-S, ADL-P and TGL.

Allocate buffer pinned to GGTT and add WA to restore sampler power
context.

Bspec: 46247

Signed-off-by: Matt Atwood <matthew.s.atwood at intel.com>
Signed-off-by: Tilak Tangudu <tilak.tangudu at intel.com>
---
 drivers/gpu/drm/i915/gt/intel_gt_regs.h   |  5 ++
 drivers/gpu/drm/i915/gt/intel_rc6.c       | 88 +++++++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_rc6_types.h |  3 +
 3 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index b8a39c219b60..91cbdd24572f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -48,6 +48,11 @@
 /* RCP unit config (Gen8+) */
 #define RCP_CONFIG				_MMIO(0xd08)
 
+#define CTX_WA_PTR				_MMIO(0x2058)
+#define CTX_WA_PTR_ADDR_MASK			REG_GENMASK(31, 12)
+#define CTX_WA_TYPE_MASK			REG_GENMASK(4, 3)
+#define CTX_WA_VALID				REG_BIT(0)
+
 #define RC6_LOCATION				_MMIO(0xd40)
 #define   RC6_CTX_IN_DRAM			(1 << 0)
 #define RC6_CTX_BASE				_MMIO(0xd48)
diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
index 908a3d0f2343..9589af2e8ca3 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -12,6 +12,7 @@
 #include "i915_vgpu.h"
 #include "intel_engine_regs.h"
 #include "intel_gt.h"
+#include "intel_gpu_commands.h"
 #include "intel_gt_pm.h"
 #include "intel_gt_regs.h"
 #include "intel_pcode.h"
@@ -38,6 +39,7 @@
  * require higher latency to switch to and wake up.
  */
 
+#define RC6_CTX_WA_BB_SIZE (PAGE_SIZE)
 static struct intel_gt *rc6_to_gt(struct intel_rc6 *rc6)
 {
 	return container_of(rc6, struct intel_gt, rc6);
@@ -53,8 +55,86 @@ static struct drm_i915_private *rc6_to_i915(struct intel_rc6 *rc)
 	return rc6_to_gt(rc)->i915;
 }
 
+static int rc6_wa_bb_ctx_init(struct intel_rc6 *rc6)
+{
+	struct drm_i915_private *i915 = rc6_to_i915(rc6);
+	struct intel_gt *gt = rc6_to_gt(rc6);
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	void *batch;
+	struct i915_gem_ww_ctx ww;
+	int err;
+
+	obj = i915_gem_object_create_shmem(i915, RC6_CTX_WA_BB_SIZE);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	vma = i915_vma_instance(obj, &gt->ggtt->vm, NULL);
+	if (IS_ERR(vma)) {
+		err = PTR_ERR(vma);
+		goto err;
+	}
+	rc6->vma = vma;
+	i915_gem_ww_ctx_init(&ww, true);
+retry:
+	err = i915_gem_object_lock(rc6->vma->obj, &ww);
+	if (!err)
+		err = i915_ggtt_pin(rc6->vma, &ww, 0, PIN_HIGH);
+	if (err)
+		goto err_ww_fini;
+
+	batch = i915_gem_object_pin_map(rc6->vma->obj, I915_MAP_WB);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err_unpin;
+	}
+	rc6->rc6_wa_bb = batch;
+	return 0;
+err_unpin:
+	if (err)
+		i915_vma_unpin(rc6->vma);
+err_ww_fini:
+	if (err == -EDEADLK) {
+		err = i915_gem_ww_ctx_backoff(&ww);
+		if (!err)
+			goto retry;
+	}
+	i915_gem_ww_ctx_fini(&ww);
+
+	if (err)
+		i915_vma_put(rc6->vma);
+err:
+	i915_gem_object_put(obj);
+	return err;
+}
+
+static void rc6_wa_bb_restore_sampler_power_ctx(struct intel_rc6 *rc6)
+{
+	struct intel_uncore *uncore = rc6_to_uncore(rc6);
+	u32 *rc6_wa_bb;
+
+	if (!rc6->vma->obj)
+		return;
+
+	rc6_wa_bb = rc6->rc6_wa_bb;
+	*rc6_wa_bb++ = MI_NOOP;
+	*rc6_wa_bb++ = MI_LOAD_REGISTER_IMM(1) | MI_LRI_FORCE_POSTED;
+	*rc6_wa_bb++ = i915_mmio_reg_offset(GEN10_SAMPLER_MODE);
+	*rc6_wa_bb++ = _MASKED_BIT_ENABLE(ENABLE_SMALLPL);
+	*rc6_wa_bb++ = MI_NOOP;
+	*rc6_wa_bb++ = MI_BATCH_BUFFER_END;
+
+	i915_gem_object_flush_map(rc6->vma->obj);
+
+	intel_uncore_write(uncore, CTX_WA_PTR,
+			   REG_FIELD_PREP(CTX_WA_PTR_ADDR_MASK,
+					  i915_vma_offset(rc6->vma) & GENMASK(19, 0)) |
+			   CTX_WA_VALID);
+}
+
 static void gen11_rc6_enable(struct intel_rc6 *rc6)
 {
+	struct drm_i915_private *i915 = rc6_to_i915(rc6);
 	struct intel_gt *gt = rc6_to_gt(rc6);
 	struct intel_uncore *uncore = gt->uncore;
 	struct intel_engine_cs *engine;
@@ -103,6 +183,11 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
 	intel_uncore_write_fw(uncore, GEN9_MEDIA_PG_IDLE_HYSTERESIS, 60);
 	intel_uncore_write_fw(uncore, GEN9_RENDER_PG_IDLE_HYSTERESIS, 60);
 
+	/* Wa_14011282866 Restore sampler power context */
+	if (IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) ||
+	    IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915))
+		rc6_wa_bb_restore_sampler_power_ctx(rc6);
+
 	/* 3a: Enable RC6
 	 *
 	 * With GuCRC, we do not enable bit 31 of RC_CTL,
@@ -610,6 +695,9 @@ void intel_rc6_init(struct intel_rc6 *rc6)
 		err = chv_rc6_init(rc6);
 	else if (IS_VALLEYVIEW(i915))
 		err = vlv_rc6_init(rc6);
+	else if (IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) ||
+		 IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915))
+		err = rc6_wa_bb_ctx_init(rc6);
 	else
 		err = 0;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_rc6_types.h b/drivers/gpu/drm/i915/gt/intel_rc6_types.h
index cd4587098162..643fd4e839ad 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_rc6_types.h
@@ -33,6 +33,9 @@ struct intel_rc6 {
 
 	struct drm_i915_gem_object *pctx;
 
+	u32 *rc6_wa_bb;
+	struct i915_vma *vma;
+
 	bool supported : 1;
 	bool enabled : 1;
 	bool manual : 1;
-- 
2.40.0



More information about the Intel-gfx mailing list