Skip to content

Commit d3de561

Browse files
icklerodrigovivi
authored andcommitted
drm/i915/gt: Reset twice
After applying an engine reset, on some platforms like Jasperlake, we occasionally detect that the engine state is not cleared until shortly after the resume. As we try to resume the engine with volatile internal state, the first request fails with a spurious CS event (it looks like it reports a lite-restore to the hung context, instead of the expected idle->active context switch). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: stable@vger.kernel.org Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com> Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221212161338.1007659-1-andi.shyti@linux.intel.com (cherry picked from commit 3db9d59) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent afce71f commit d3de561

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

drivers/gpu/drm/i915/gt/intel_reset.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,25 +278,47 @@ static int ilk_do_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask,
278278
static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
279279
{
280280
struct intel_uncore *uncore = gt->uncore;
281+
int loops = 2;
281282
int err;
282283

283284
/*
284285
* GEN6_GDRST is not in the gt power well, no need to check
285286
* for fifo space for the write or forcewake the chip for
286287
* the read
287288
*/
288-
intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
289+
do {
290+
intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
289291

290-
/* Wait for the device to ack the reset requests */
291-
err = __intel_wait_for_register_fw(uncore,
292-
GEN6_GDRST, hw_domain_mask, 0,
293-
500, 0,
294-
NULL);
292+
/*
293+
* Wait for the device to ack the reset requests.
294+
*
295+
* On some platforms, e.g. Jasperlake, we see that the
296+
* engine register state is not cleared until shortly after
297+
* GDRST reports completion, causing a failure as we try
298+
* to immediately resume while the internal state is still
299+
* in flux. If we immediately repeat the reset, the second
300+
* reset appears to serialise with the first, and since
301+
* it is a no-op, the registers should retain their reset
302+
* value. However, there is still a concern that upon
303+
* leaving the second reset, the internal engine state
304+
* is still in flux and not ready for resuming.
305+
*/
306+
err = __intel_wait_for_register_fw(uncore, GEN6_GDRST,
307+
hw_domain_mask, 0,
308+
2000, 0,
309+
NULL);
310+
} while (err == 0 && --loops);
295311
if (err)
296312
GT_TRACE(gt,
297313
"Wait for 0x%08x engines reset failed\n",
298314
hw_domain_mask);
299315

316+
/*
317+
* As we have observed that the engine state is still volatile
318+
* after GDRST is acked, impose a small delay to let everything settle.
319+
*/
320+
udelay(50);
321+
300322
return err;
301323
}
302324

0 commit comments

Comments
 (0)