[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