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: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210119110802.22228-3-chris@chris-wilson.co.uk
This commit is contained in:
parent
80655d2ad1
commit
14139c3e8d
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
clflush_cache_range(engine->status_page.addr, PAGE_SIZE);
|
clflush_cache_range(engine->status_page.addr, PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool stop_ring(struct intel_engine_cs *engine)
|
||||||
|
{
|
||||||
|
ENGINE_WRITE_FW(engine, RING_HEAD, ENGINE_READ_FW(engine, RING_TAIL));
|
||||||
|
|
||||||
|
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)
|
static void reset_prepare(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct intel_uncore *uncore = engine->uncore;
|
|
||||||
const u32 base = engine->mmio_base;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
* 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,
|
||||||
|
"%s head not reset to zero "
|
||||||
|
"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));
|
||||||
|
}
|
||||||
|
|
||||||
intel_uncore_write_fw(uncore,
|
if (!stop_ring(engine)) {
|
||||||
RING_HEAD(base),
|
drm_err(&engine->i915->drm,
|
||||||
intel_uncore_read_fw(uncore, RING_TAIL(base)));
|
"failed to set %s head to zero "
|
||||||
intel_uncore_posting_read_fw(uncore, RING_HEAD(base)); /* paranoia */
|
"ctl %08x head %08x tail %08x start %08x\n",
|
||||||
|
engine->name,
|
||||||
intel_uncore_write_fw(uncore, RING_HEAD(base), 0);
|
ENGINE_READ_FW(engine, RING_CTL),
|
||||||
intel_uncore_write_fw(uncore, RING_TAIL(base), 0);
|
ENGINE_READ_FW(engine, RING_HEAD),
|
||||||
intel_uncore_posting_read_fw(uncore, RING_TAIL(base));
|
ENGINE_READ_FW(engine, RING_TAIL),
|
||||||
|
ENGINE_READ_FW(engine, RING_START));
|
||||||
/* The ring must be empty before it is disabled */
|
}
|
||||||
intel_uncore_write_fw(uncore, RING_CTL(base), 0);
|
|
||||||
|
|
||||||
/* Check acts as a post */
|
|
||||||
if (intel_uncore_read_fw(uncore, RING_HEAD(base)))
|
|
||||||
ENGINE_TRACE(engine, "ring head [%x] not parked\n",
|
|
||||||
intel_uncore_read_fw(uncore, RING_HEAD(base)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_rewind(struct intel_engine_cs *engine, bool stalled)
|
static void reset_rewind(struct intel_engine_cs *engine, bool stalled)
|
||||||
|
|
Loading…
Reference in New Issue