[PATCH 02/10] gt wa verify

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Thu Nov 29 08:58:27 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 | 66 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_workarounds.h |  2 +
 4 files changed, 80 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 c55b1f75c980..4da93642a80e 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 70f144ee519c..b74129f2ce36 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -1077,6 +1077,72 @@ 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, u32 mask, const char *name,
+	const char *from)
+{
+	DRM_ERROR("%s workaround lost on %s! (%x=%x/%x, type %u, expected %x, mask=%x/%x)\n",
+		  name, from,
+		  i915_mmio_reg_offset(wa->reg), cur, cur & mask,
+		  wa->type, wa->val, wa->mask, mask);
+}
+
+static void
+wa_verify_bits(const struct i915_wa *wa, u32 cur, u32 mask, const char *name,
+	       const char *from, bool all)
+{
+	u32 bits = all ? mask : wa->val;
+	u32 bits_ = bits;
+	u32 cur_ = cur;
+	u32 val_ = wa->val;
+
+	while (bits_) {
+		if (((val_ & 1) && !(cur_ & 1)) ||
+		    (!(val_ & 1) && (cur_ & 1) && all)) {
+			wa_fail(wa, cur, bits, 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;
+
+	if (!wal->count)
+		return;
+
+	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
+		u32 val = I915_READ(wa->reg);
+
+		switch (wa->type) {
+		case I915_WA_MASKED:
+			wa_verify_bits(wa, val, wa->val, wal->name, from,
+				       false);
+			break;
+		case I915_WA_MASK_AND_OR:
+			wa_verify_bits(wa, val, wa->mask, wal->name, from,
+				       wa->mask ? true : false);
+			break;
+		default:
+			MISSING_CASE(wa->type);
+		};
+	}
+}
+
+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 4c979ba75e4f..0d2ba043b7d1 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -31,6 +31,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