[PATCH 9/9] rmw from irq

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


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

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/intel_workarounds.c | 51 ++++++++++++++++++++----
 1 file changed, 44 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index bee51b2454d0..4c8291c85c3b 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -919,31 +919,58 @@ void intel_gt_workarounds_init(struct drm_i915_private *dev_priv)
 	wa_init_finish(wal);
 }
 
+static enum forcewake_domains
+wal_get_fw_for_rmw(struct drm_i915_private *dev_priv,
+		   const struct i915_wa_list *wal)
+{
+	enum forcewake_domains fw = 0;
+	struct i915_wa *wa;
+	unsigned int i;
+
+	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
+		fw |= intel_uncore_forcewake_for_reg(dev_priv,
+						     wa->reg,
+						     FW_REG_READ |
+						     FW_REG_WRITE);
+
+	return fw;
+}
+
 static void
 wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal)
 {
+	enum forcewake_domains fw;
+	unsigned long flags;
 	struct i915_wa *wa;
 	unsigned int i;
 
 	if (!wal->count)
 		return;
 
+	fw = wal_get_fw_for_rmw(dev_priv, wal);
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, flags);
+	intel_uncore_forcewake_get__locked(dev_priv, fw);
+
 	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
-		u32 val = I915_READ(wa->reg);
+		u32 val = I915_READ_FW(wa->reg);
 
 		val &= ~wa->mask;
 		val |= wa->val;
 
-		I915_WRITE(wa->reg, val);
+		I915_WRITE_FW(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);
+u32 tmp = I915_READ_FW(wa->reg);
 if ((tmp & wa->mask) != (val & wa->mask))
 	printk("!!!! %x/%x !!!!!\n", tmp, tmp & wa->mask);
 }
 	}
 
+	intel_uncore_forcewake_put__locked(dev_priv, fw);
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
+
 	DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name);
 }
 
@@ -1112,20 +1139,30 @@ void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine)
 	struct drm_i915_private *dev_priv = engine->i915;
 	const struct i915_wa_list *wal = &engine->whitelist;
 	const u32 base = engine->mmio_base;
+	enum forcewake_domains fw;
+	unsigned long flags;
 	struct i915_wa *wa;
 	unsigned int i;
 
 	if (!wal->count)
 		return;
 
+	fw = wal_get_fw_for_rmw(dev_priv, wal);
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, flags);
+	intel_uncore_forcewake_get__locked(dev_priv, fw);
+
 	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
-		I915_WRITE(RING_FORCE_TO_NONPRIV(base, i),
-			   i915_mmio_reg_offset(wa->reg));
+		I915_WRITE_FW(RING_FORCE_TO_NONPRIV(base, i),
+			      i915_mmio_reg_offset(wa->reg));
 
 	/* And clear the rest just in case of garbage */
 	for (; i < RING_MAX_NONPRIV_SLOTS; i++)
-		I915_WRITE(RING_FORCE_TO_NONPRIV(base, i),
-			   i915_mmio_reg_offset(RING_NOPID(base)));
+		I915_WRITE_FW(RING_FORCE_TO_NONPRIV(base, i),
+			      i915_mmio_reg_offset(RING_NOPID(base)));
+
+	intel_uncore_forcewake_put__locked(dev_priv, fw);
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
 
 	DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name);
 }
-- 
2.19.1



More information about the Intel-gfx-trybot mailing list