[Intel-gfx] [PATCH 6/8] drm/i915/gt: Pull ring submission resume under its caller forcewake

2021-01-06 Thread Chris Wilson
Take advantage of calling xcs_resume under a forcewake by using direct
mmio access. In particular, we can avoid the sleeping variants to allow
resume to be called from softirq context, required for engine resets.

Signed-off-by: Chris Wilson 
---
 .../gpu/drm/i915/gt/intel_ring_submission.c   | 96 ---
 1 file changed, 42 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 7c31126a1b6d..77aec0a94541 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -121,31 +121,27 @@ static void set_hwsp(struct intel_engine_cs *engine, u32 
offset)
hwsp = RING_HWS_PGA(engine->mmio_base);
}
 
-   intel_uncore_write(engine->uncore, hwsp, offset);
-   intel_uncore_posting_read(engine->uncore, hwsp);
+   intel_uncore_write_fw(engine->uncore, hwsp, offset);
+   intel_uncore_posting_read_fw(engine->uncore, hwsp);
 }
 
 static void flush_cs_tlb(struct intel_engine_cs *engine)
 {
-   struct drm_i915_private *dev_priv = engine->i915;
-
-   if (!IS_GEN_RANGE(dev_priv, 6, 7))
+   if (!IS_GEN_RANGE(engine->i915, 6, 7))
return;
 
/* ring should be idle before issuing a sync flush*/
-   drm_WARN_ON(_priv->drm,
-   (ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
+   GEM_DEBUG_WARN_ON((ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
 
-   ENGINE_WRITE(engine, RING_INSTPM,
-_MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
-   INSTPM_SYNC_FLUSH));
-   if (intel_wait_for_register(engine->uncore,
-   RING_INSTPM(engine->mmio_base),
-   INSTPM_SYNC_FLUSH, 0,
-   1000))
-   drm_err(_priv->drm,
-   "%s: wait for SyncFlush to complete for TLB 
invalidation timed out\n",
-   engine->name);
+   ENGINE_WRITE_FW(engine, RING_INSTPM,
+   _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
+  INSTPM_SYNC_FLUSH));
+   if (__intel_wait_for_register_fw(engine->uncore,
+RING_INSTPM(engine->mmio_base),
+INSTPM_SYNC_FLUSH, 0,
+2000, 0, NULL))
+   ENGINE_TRACE(engine,
+"wait for SyncFlush to complete for TLB 
invalidation timed out\n");
 }
 
 static void ring_setup_status_page(struct intel_engine_cs *engine)
@@ -176,13 +172,13 @@ static void set_pp_dir(struct intel_engine_cs *engine)
if (!vm)
return;
 
-   ENGINE_WRITE(engine, RING_PP_DIR_DCLV, PP_DIR_DCLV_2G);
-   ENGINE_WRITE(engine, RING_PP_DIR_BASE, pp_dir(vm));
+   ENGINE_WRITE_FW(engine, RING_PP_DIR_DCLV, PP_DIR_DCLV_2G);
+   ENGINE_WRITE_FW(engine, RING_PP_DIR_BASE, pp_dir(vm));
 
if (INTEL_GEN(engine->i915) >= 7) {
-   ENGINE_WRITE(engine,
-RING_MODE_GEN7,
-_MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
+   ENGINE_WRITE_FW(engine,
+   RING_MODE_GEN7,
+   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
}
 }
 
@@ -190,13 +186,10 @@ static int xcs_resume(struct intel_engine_cs *engine)
 {
struct drm_i915_private *dev_priv = engine->i915;
struct intel_ring *ring = engine->legacy.ring;
-   int ret = 0;
 
ENGINE_TRACE(engine, "ring:{HEAD:%04x, TAIL:%04x}\n",
 ring->head, ring->tail);
 
-   intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
-
if (HWS_NEEDS_PHYSICAL(dev_priv))
ring_setup_phys_status_page(engine);
else
@@ -204,16 +197,13 @@ static int xcs_resume(struct intel_engine_cs *engine)
 
intel_breadcrumbs_reset(engine->breadcrumbs);
 
-   /* Enforce ordering by reading HEAD register back */
-   ENGINE_POSTING_READ(engine, RING_HEAD);
-
/*
 * Initialize the ring. This must happen _after_ we've cleared the ring
 * registers with the above sequence (the readback of the HEAD registers
 * also enforces ordering), otherwise the hw might lose the new ring
 * register values.
 */
-   ENGINE_WRITE(engine, RING_START, i915_ggtt_offset(ring->vma));
+   ENGINE_WRITE_FW(engine, RING_START, i915_ggtt_offset(ring->vma));
 
/* Check that the ring offsets point within the ring! */
GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head));
@@ -223,46 +213,44 @@ static int xcs_resume(struct intel_engine_cs *engine)
set_pp_dir(engine);
 
/* First wake the ring up to an empty/idle ring */
-   ENGINE_WRITE(engine, RING_HEAD, ring->head);
-   

[Intel-gfx] [PATCH 6/8] drm/i915/gt: Pull ring submission resume under its caller forcewake

2021-01-04 Thread Chris Wilson
Take advantage of calling xcs_resume under a forcewake by using direct
mmio access. In particular, we can avoid the sleeping variants to allow
resume to be called from softirq context, required for engine resets.

Signed-off-by: Chris Wilson 
---
 .../gpu/drm/i915/gt/intel_ring_submission.c   | 98 ---
 1 file changed, 43 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 7c31126a1b6d..77aec0a94541 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -121,31 +121,27 @@ static void set_hwsp(struct intel_engine_cs *engine, u32 
offset)
hwsp = RING_HWS_PGA(engine->mmio_base);
}
 
-   intel_uncore_write(engine->uncore, hwsp, offset);
-   intel_uncore_posting_read(engine->uncore, hwsp);
+   intel_uncore_write_fw(engine->uncore, hwsp, offset);
+   intel_uncore_posting_read_fw(engine->uncore, hwsp);
 }
 
 static void flush_cs_tlb(struct intel_engine_cs *engine)
 {
-   struct drm_i915_private *dev_priv = engine->i915;
-
-   if (!IS_GEN_RANGE(dev_priv, 6, 7))
+   if (!IS_GEN_RANGE(engine->i915, 6, 7))
return;
 
/* ring should be idle before issuing a sync flush*/
-   drm_WARN_ON(_priv->drm,
-   (ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
-
-   ENGINE_WRITE(engine, RING_INSTPM,
-_MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
-   INSTPM_SYNC_FLUSH));
-   if (intel_wait_for_register(engine->uncore,
-   RING_INSTPM(engine->mmio_base),
-   INSTPM_SYNC_FLUSH, 0,
-   1000))
-   drm_err(_priv->drm,
-   "%s: wait for SyncFlush to complete for TLB 
invalidation timed out\n",
-   engine->name);
+   GEM_DEBUG_WARN_ON((ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
+
+   ENGINE_WRITE_FW(engine, RING_INSTPM,
+   _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
+  INSTPM_SYNC_FLUSH));
+   if (__intel_wait_for_register_fw(engine->uncore,
+RING_INSTPM(engine->mmio_base),
+INSTPM_SYNC_FLUSH, 0,
+2000, 0, NULL))
+   ENGINE_TRACE(engine,
+"wait for SyncFlush to complete for TLB 
invalidation timed out\n");
 }
 
 static void ring_setup_status_page(struct intel_engine_cs *engine)
@@ -176,13 +172,13 @@ static void set_pp_dir(struct intel_engine_cs *engine)
if (!vm)
return;
 
-   ENGINE_WRITE(engine, RING_PP_DIR_DCLV, PP_DIR_DCLV_2G);
-   ENGINE_WRITE(engine, RING_PP_DIR_BASE, pp_dir(vm));
+   ENGINE_WRITE_FW(engine, RING_PP_DIR_DCLV, PP_DIR_DCLV_2G);
+   ENGINE_WRITE_FW(engine, RING_PP_DIR_BASE, pp_dir(vm));
 
if (INTEL_GEN(engine->i915) >= 7) {
-   ENGINE_WRITE(engine,
-RING_MODE_GEN7,
-_MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
+   ENGINE_WRITE_FW(engine,
+   RING_MODE_GEN7,
+   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
}
 }
 
@@ -190,13 +186,10 @@ static int xcs_resume(struct intel_engine_cs *engine)
 {
struct drm_i915_private *dev_priv = engine->i915;
struct intel_ring *ring = engine->legacy.ring;
-   int ret = 0;
 
ENGINE_TRACE(engine, "ring:{HEAD:%04x, TAIL:%04x}\n",
 ring->head, ring->tail);
 
-   intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
-
if (HWS_NEEDS_PHYSICAL(dev_priv))
ring_setup_phys_status_page(engine);
else
@@ -204,16 +197,13 @@ static int xcs_resume(struct intel_engine_cs *engine)
 
intel_breadcrumbs_reset(engine->breadcrumbs);
 
-   /* Enforce ordering by reading HEAD register back */
-   ENGINE_POSTING_READ(engine, RING_HEAD);
-
/*
 * Initialize the ring. This must happen _after_ we've cleared the ring
 * registers with the above sequence (the readback of the HEAD registers
 * also enforces ordering), otherwise the hw might lose the new ring
 * register values.
 */
-   ENGINE_WRITE(engine, RING_START, i915_ggtt_offset(ring->vma));
+   ENGINE_WRITE_FW(engine, RING_START, i915_ggtt_offset(ring->vma));
 
/* Check that the ring offsets point within the ring! */
GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head));
@@ -223,46 +213,44 @@ static int xcs_resume(struct intel_engine_cs *engine)
set_pp_dir(engine);
 
/* First wake the ring up to an empty/idle ring */
-   ENGINE_WRITE(engine, RING_HEAD, ring->head);
-