[PATCH 2/9] gt wa verify

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Thu Nov 29 11:29:15 UTC 2018


From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c          |  4 ++
 drivers/gpu/drm/i915/i915_gem.c          |  8 ++++
 drivers/gpu/drm/i915/intel_workarounds.c | 51 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_workarounds.h |  2 +
 4 files changed, 65 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 2f3dc1cf83a6..14d019c9455b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -53,6 +53,7 @@
 #include "i915_vgpu.h"
 #include "intel_drv.h"
 #include "intel_uc.h"
+#include "intel_workarounds.h"
 
 static struct drm_driver driver;
 
@@ -2362,6 +2363,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
 		goto out;
 	}
 
+	/* Catch GT workarounds affected by engine reset. */
+	intel_gt_workarounds_verify(engine->i915, engine->name);
+
 	/*
 	 * The request that caused the hang is stuck on elsp, we know the
 	 * active request and can drop it, adjust head to skip the offending
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 18adb3dd1fcd..d5e37ed2f103 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -163,6 +163,11 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 	 */
 	synchronize_irq(i915->drm.irq);
 
+	/*
+	 * Catch GT workarounds being affected by anything during GPU activity.
+	 */
+	intel_gt_workarounds_verify(i915, "idle");
+
 	intel_engines_park(i915);
 	i915_timelines_park(i915);
 
@@ -5334,7 +5339,10 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
 		I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev_priv) ?
 			   LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
 
+	/* Apply the GT workarounds... */
 	intel_gt_workarounds_apply(dev_priv);
+	/* ...and catch whether they are sticking. */
+	intel_gt_workarounds_verify(dev_priv, "init");
 
 	i915_gem_init_swizzling(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index 3334f74c4d8e..986ebab9f4b3 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -1065,6 +1065,11 @@ wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal)
 		I915_WRITE(wa->reg, val);
 printk(">wa-%s: reg=%x mask=%x val=%x ---> %x\n",
        wal->name, i915_mmio_reg_offset(wa->reg), wa->mask, wa->val, val);
+{
+u32 tmp = I915_READ(wa->reg);
+if ((tmp & wa->mask) != (val & wa->mask))
+	printk("!!!! %x/%x !!!!!\n", tmp, tmp & wa->mask);
+}
 	}
 
 	DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name);
@@ -1075,6 +1080,52 @@ void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv)
 	wa_list_apply(dev_priv, &dev_priv->gt_wa_list);
 }
 
+static void
+wa_fail(const struct i915_wa *wa, u32 cur, const char *name, const char *from)
+{
+	DRM_ERROR("%s workaround lost on %s! (%x=%x/%x, expected %x, mask=%x)\n",
+		  name, from,
+		  i915_mmio_reg_offset(wa->reg),
+		  cur, cur & wa->mask, wa->val, wa->mask);
+}
+
+static void
+wa_verify_bits(const struct i915_wa *wa, u32 cur, const char *name,
+	       const char *from)
+{
+	u32 bits = wa->mask;
+	u32 cur_ = cur;
+	u32 val_ = wa->val;
+
+	while (bits) {
+		if ((bits & 1) && ((cur_ & 1) != (val_ & 1))) {
+			wa_fail(wa, cur, name, from);
+			break;
+		}
+
+		bits >>= 1;
+		cur_ >>= 1;
+		val_ >>= 1;
+	}
+}
+
+static void wa_list_verify(struct drm_i915_private *dev_priv,
+			   const struct i915_wa_list *wal,
+			   const char *from)
+{
+	struct i915_wa *wa;
+	unsigned int i;
+
+	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
+		wa_verify_bits(wa, I915_READ(wa->reg), wal->name, from);
+}
+
+void intel_gt_workarounds_verify(struct drm_i915_private *dev_priv,
+				 const char *from)
+{
+	wa_list_verify(dev_priv, &dev_priv->gt_wa_list, from);
+}
+
 struct whitelist {
 	i915_reg_t reg[RING_MAX_NONPRIV_SLOTS];
 	unsigned int count;
diff --git a/drivers/gpu/drm/i915/intel_workarounds.h b/drivers/gpu/drm/i915/intel_workarounds.h
index 64aed9cf0200..f11572177f0e 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -33,6 +33,8 @@ int intel_ctx_workarounds_emit(struct i915_request *rq);
 
 void intel_gt_workarounds_init(struct drm_i915_private *dev_priv);
 void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);
+void intel_gt_workarounds_verify(struct drm_i915_private *dev_priv,
+				 const char *from);
 
 void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);
 
-- 
2.19.1



More information about the Intel-gfx-trybot mailing list