@@ -376,9 +376,26 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long *flags)
376
376
* driver threads, but also with hardware/firmware agents. A dedicated
377
377
* locking register is used.
378
378
*/
379
- if (GRAPHICS_VER_FULL (gt -> i915 ) >= IP_VER (12 , 70 ))
379
+ if (GRAPHICS_VER_FULL (gt -> i915 ) >= IP_VER (12 , 70 )) {
380
+ /*
381
+ * The steering control and semaphore registers are inside an
382
+ * "always on" power domain with respect to RC6. However there
383
+ * are some issues if higher-level platform sleep states are
384
+ * entering/exiting at the same time these registers are
385
+ * accessed. Grabbing GT forcewake and holding it over the
386
+ * entire lock/steer/unlock cycle ensures that those sleep
387
+ * states have been fully exited before we access these
388
+ * registers. This wakeref will be released in the unlock
389
+ * routine.
390
+ *
391
+ * This is expected to become a formally documented/numbered
392
+ * workaround soon.
393
+ */
394
+ intel_uncore_forcewake_get (gt -> uncore , FORCEWAKE_GT );
395
+
380
396
err = wait_for (intel_uncore_read_fw (gt -> uncore ,
381
397
MTL_STEER_SEMAPHORE ) == 0x1 , 100 );
398
+ }
382
399
383
400
/*
384
401
* Even on platforms with a hardware lock, we'll continue to grab
@@ -415,8 +432,11 @@ void intel_gt_mcr_unlock(struct intel_gt *gt, unsigned long flags)
415
432
{
416
433
spin_unlock_irqrestore (& gt -> mcr_lock , flags );
417
434
418
- if (GRAPHICS_VER_FULL (gt -> i915 ) >= IP_VER (12 , 70 ))
435
+ if (GRAPHICS_VER_FULL (gt -> i915 ) >= IP_VER (12 , 70 )) {
419
436
intel_uncore_write_fw (gt -> uncore , MTL_STEER_SEMAPHORE , 0x1 );
437
+
438
+ intel_uncore_forcewake_put (gt -> uncore , FORCEWAKE_GT );
439
+ }
420
440
}
421
441
422
442
/**
0 commit comments