drm/i915: Add WaKBLVECSSemaphoreWaitPoll
authorMika Kuoppala <mika.kuoppala@linux.intel.com>
Thu, 7 Jun 2018 17:24:44 +0000 (20:24 +0300)
committerMika Kuoppala <mika.kuoppala@linux.intel.com>
Fri, 8 Jun 2018 09:16:20 +0000 (12:16 +0300)
There is a problem with kbl up to rev E0 where a heavy
memory/fabric traffic from adjacent engine(s) can cause an engine
reset to fail. This traffic can be from normal memory accesses
or it can be from heavy polling on a semaphore wait.

For engine hogging causing a fail, we already fallback to
full reset. Which effectively stops all engines and thus
we only add a workaround documentation.

For the semaphore wait loop poll case, we add one microsecond
poll interval to semaphore wait to guarantee bandwidth for
the reset preration. The side effect is that we make semaphore
completion latencies also 1us longer.

v2: Let full reset handle the adjacent engine idling (Chris)
v3: Skip render engine (Joonas), please checkpatch on define (Mika)

References: https://bugs.freedesktop.org/show_bug.cgi?id=106684
References: VTHSD#2227190, HSDES#1604216706, BSID#0917
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180607172444.17080-1-mika.kuoppala@linux.intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/i915/intel_workarounds.c

index f0317bde3aabc130287b3e19e5a901ed330bbebf..987def26ce829de6bdf534e97aaec9966c2621d6 100644 (file)
@@ -2242,6 +2242,7 @@ enum i915_power_well_id {
 #define RING_RESET_CTL(base)   _MMIO((base)+0xd0)
 #define   RESET_CTL_REQUEST_RESET  (1 << 0)
 #define   RESET_CTL_READY_TO_RESET (1 << 1)
+#define RING_SEMA_WAIT_POLL(base) _MMIO((base) + 0x24c)
 
 #define HSW_GTT_CACHE_EN       _MMIO(0x4024)
 #define   GTT_CACHE_EN_ALL     0xF0007FFF
index bb03f6d8b3d16f103df70ea504573283f5812e20..b892ca8396e8778d0e4670813412c4a8a0b669c9 100644 (file)
@@ -2174,6 +2174,8 @@ int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask)
                 * Thus assume it is best to stop engines on all gens
                 * where we have a gpu reset.
                 *
+                * WaKBLVECSSemaphoreWaitPoll:kbl (on ALL_ENGINES)
+                *
                 * WaMediaResetMainRingCleanup:ctg,elk (presumably)
                 *
                 * FIXME: Wa for more modern gens needs to be validated
index b1ab56a1ec31324a7b736fd37c1b1e8c5f46ac1d..24b929ce3341b07e2f0aa82b5a07fafa5d927370 100644 (file)
@@ -666,6 +666,19 @@ static void kbl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
                   I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
                   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
+
+       /* WaKBLVECSSemaphoreWaitPoll:kbl */
+       if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_E0)) {
+               struct intel_engine_cs *engine;
+               unsigned int tmp;
+
+               for_each_engine(engine, dev_priv, tmp) {
+                       if (engine->id == RCS)
+                               continue;
+
+                       I915_WRITE(RING_SEMA_WAIT_POLL(engine->mmio_base), 1);
+               }
+       }
 }
 
 static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv)