Commit 14139c3e authored by Chris Wilson's avatar Chris Wilson

drm/i915/gt: Lift stop_ring() to reset_prepare

Push the sleeping stop_ring() out of the reset resume function to reset
prepare; we are not allowed to sleep in the former.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210119110802.22228-3-chris@chris-wilson.co.uk
parent 80655d2a
...@@ -157,21 +157,6 @@ static void ring_setup_status_page(struct intel_engine_cs *engine) ...@@ -157,21 +157,6 @@ static void ring_setup_status_page(struct intel_engine_cs *engine)
flush_cs_tlb(engine); flush_cs_tlb(engine);
} }
static bool stop_ring(struct intel_engine_cs *engine)
{
intel_engine_stop_cs(engine);
ENGINE_WRITE(engine, RING_HEAD, ENGINE_READ(engine, RING_TAIL));
ENGINE_WRITE(engine, RING_HEAD, 0);
ENGINE_WRITE(engine, RING_TAIL, 0);
/* The ring must be empty before it is disabled */
ENGINE_WRITE(engine, RING_CTL, 0);
return (ENGINE_READ(engine, RING_HEAD) & HEAD_ADDR) == 0;
}
static struct i915_address_space *vm_alias(struct i915_address_space *vm) static struct i915_address_space *vm_alias(struct i915_address_space *vm)
{ {
if (i915_is_ggtt(vm)) if (i915_is_ggtt(vm))
...@@ -213,31 +198,6 @@ static int xcs_resume(struct intel_engine_cs *engine) ...@@ -213,31 +198,6 @@ static int xcs_resume(struct intel_engine_cs *engine)
intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL); intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
/* WaClearRingBufHeadRegAtInit:ctg,elk */
if (!stop_ring(engine)) {
/* G45 ring initialization often fails to reset head to zero */
drm_dbg(&dev_priv->drm, "%s head not reset to zero "
"ctl %08x head %08x tail %08x start %08x\n",
engine->name,
ENGINE_READ(engine, RING_CTL),
ENGINE_READ(engine, RING_HEAD),
ENGINE_READ(engine, RING_TAIL),
ENGINE_READ(engine, RING_START));
if (!stop_ring(engine)) {
drm_err(&dev_priv->drm,
"failed to set %s head to zero "
"ctl %08x head %08x tail %08x start %08x\n",
engine->name,
ENGINE_READ(engine, RING_CTL),
ENGINE_READ(engine, RING_HEAD),
ENGINE_READ(engine, RING_TAIL),
ENGINE_READ(engine, RING_START));
ret = -EIO;
goto out;
}
}
if (HWS_NEEDS_PHYSICAL(dev_priv)) if (HWS_NEEDS_PHYSICAL(dev_priv))
ring_setup_phys_status_page(engine); ring_setup_phys_status_page(engine);
else else
...@@ -339,11 +299,21 @@ static void xcs_sanitize(struct intel_engine_cs *engine) ...@@ -339,11 +299,21 @@ static void xcs_sanitize(struct intel_engine_cs *engine)
clflush_cache_range(engine->status_page.addr, PAGE_SIZE); clflush_cache_range(engine->status_page.addr, PAGE_SIZE);
} }
static void reset_prepare(struct intel_engine_cs *engine) static bool stop_ring(struct intel_engine_cs *engine)
{ {
struct intel_uncore *uncore = engine->uncore; ENGINE_WRITE_FW(engine, RING_HEAD, ENGINE_READ_FW(engine, RING_TAIL));
const u32 base = engine->mmio_base;
ENGINE_WRITE_FW(engine, RING_HEAD, 0);
ENGINE_WRITE_FW(engine, RING_TAIL, 0);
/* The ring must be empty before it is disabled */
ENGINE_WRITE_FW(engine, RING_CTL, 0);
return (ENGINE_READ_FW(engine, RING_HEAD) & HEAD_ADDR) == 0;
}
static void reset_prepare(struct intel_engine_cs *engine)
{
/* /*
* We stop engines, otherwise we might get failed reset and a * We stop engines, otherwise we might get failed reset and a
* dead gpu (on elk). Also as modern gpu as kbl can suffer * dead gpu (on elk). Also as modern gpu as kbl can suffer
...@@ -355,30 +325,35 @@ static void reset_prepare(struct intel_engine_cs *engine) ...@@ -355,30 +325,35 @@ static void reset_prepare(struct intel_engine_cs *engine)
* WaKBLVECSSemaphoreWaitPoll:kbl (on ALL_ENGINES) * WaKBLVECSSemaphoreWaitPoll:kbl (on ALL_ENGINES)
* *
* WaMediaResetMainRingCleanup:ctg,elk (presumably) * WaMediaResetMainRingCleanup:ctg,elk (presumably)
* WaClearRingBufHeadRegAtInit:ctg,elk
* *
* FIXME: Wa for more modern gens needs to be validated * FIXME: Wa for more modern gens needs to be validated
*/ */
ENGINE_TRACE(engine, "\n"); ENGINE_TRACE(engine, "\n");
intel_engine_stop_cs(engine);
if (intel_engine_stop_cs(engine)) if (!stop_ring(engine)) {
ENGINE_TRACE(engine, "timed out on STOP_RING\n"); /* G45 ring initialization often fails to reset head to zero */
drm_dbg(&engine->i915->drm,
intel_uncore_write_fw(uncore, "%s head not reset to zero "
RING_HEAD(base), "ctl %08x head %08x tail %08x start %08x\n",
intel_uncore_read_fw(uncore, RING_TAIL(base))); engine->name,
intel_uncore_posting_read_fw(uncore, RING_HEAD(base)); /* paranoia */ ENGINE_READ_FW(engine, RING_CTL),
ENGINE_READ_FW(engine, RING_HEAD),
intel_uncore_write_fw(uncore, RING_HEAD(base), 0); ENGINE_READ_FW(engine, RING_TAIL),
intel_uncore_write_fw(uncore, RING_TAIL(base), 0); ENGINE_READ_FW(engine, RING_START));
intel_uncore_posting_read_fw(uncore, RING_TAIL(base)); }
/* The ring must be empty before it is disabled */
intel_uncore_write_fw(uncore, RING_CTL(base), 0);
/* Check acts as a post */ if (!stop_ring(engine)) {
if (intel_uncore_read_fw(uncore, RING_HEAD(base))) drm_err(&engine->i915->drm,
ENGINE_TRACE(engine, "ring head [%x] not parked\n", "failed to set %s head to zero "
intel_uncore_read_fw(uncore, RING_HEAD(base))); "ctl %08x head %08x tail %08x start %08x\n",
engine->name,
ENGINE_READ_FW(engine, RING_CTL),
ENGINE_READ_FW(engine, RING_HEAD),
ENGINE_READ_FW(engine, RING_TAIL),
ENGINE_READ_FW(engine, RING_START));
}
} }
static void reset_rewind(struct intel_engine_cs *engine, bool stalled) static void reset_rewind(struct intel_engine_cs *engine, bool stalled)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment