@@ -1918,6 +1918,20 @@ static void execlists_reset(struct intel_engine_cs *engine,
spin_unlock_irqrestore(&engine->timeline.lock, flags);
+ if (!request)
+ return;
+
+ regs = request->hw_context->lrc_reg_state;
+
+ /*
+ * After a reset, the context may have preserved the STOP bit
+ * of RING_MI_MODE we used to freeze the active engine before
+ * the reset. If that bit is restored the ring stops instead
+ * of being executed.
+ */
+ regs[CTX_MI_MODE + 1] |= STOP_RING << 16;
+ regs[CTX_MI_MODE + 1] &= ~STOP_RING;
+
/*
* If the request was innocent, we leave the request in the ELSP
* and will try to replay it on restarting. The context image may
@@ -1929,7 +1943,7 @@ static void execlists_reset(struct intel_engine_cs *engine,
* and have to at least restore the RING register in the context
* image back to the expected values to skip over the guilty request.
*/
- if (!request || request->fence.error != -EIO)
+ if (request->fence.error != -EIO)
return;
/*
@@ -1940,7 +1954,6 @@ static void execlists_reset(struct intel_engine_cs *engine,
* future request will be after userspace has had the opportunity
* to recreate its own state.
*/
- regs = request->hw_context->lrc_reg_state;
if (engine->pinned_default_state) {
memcpy(regs, /* skip restoring the vanilla PPHWSP */
engine->pinned_default_state + LRC_STATE_PN * PAGE_SIZE,
@@ -39,6 +39,8 @@
#define CTX_R_PWR_CLK_STATE 0x42
#define CTX_END 0x44
+#define CTX_MI_MODE 0x54
+
#define CTX_REG(reg_state, pos, reg, val) do { \
u32 *reg_state__ = (reg_state); \
const u32 pos__ = (pos); \