@@ -338,106 +338,170 @@ static int gen6_reset_engines(struct intel_gt *gt,
338
338
return gen6_hw_domain_reset (gt , hw_mask );
339
339
}
340
340
341
- static int gen11_lock_sfc (struct intel_engine_cs * engine , u32 * hw_mask )
341
+ static struct intel_engine_cs * find_sfc_paired_vecs_engine (struct intel_engine_cs * engine )
342
+ {
343
+ int vecs_id ;
344
+
345
+ GEM_BUG_ON (engine -> class != VIDEO_DECODE_CLASS );
346
+
347
+ vecs_id = _VECS ((engine -> instance ) / 2 );
348
+
349
+ return engine -> gt -> engine [vecs_id ];
350
+ }
351
+
352
+ struct sfc_lock_data {
353
+ i915_reg_t lock_reg ;
354
+ i915_reg_t ack_reg ;
355
+ i915_reg_t usage_reg ;
356
+ u32 lock_bit ;
357
+ u32 ack_bit ;
358
+ u32 usage_bit ;
359
+ u32 reset_bit ;
360
+ };
361
+
362
+ static void get_sfc_forced_lock_data (struct intel_engine_cs * engine ,
363
+ struct sfc_lock_data * sfc_lock )
364
+ {
365
+ switch (engine -> class ) {
366
+ default :
367
+ MISSING_CASE (engine -> class );
368
+ fallthrough ;
369
+ case VIDEO_DECODE_CLASS :
370
+ sfc_lock -> lock_reg = GEN11_VCS_SFC_FORCED_LOCK (engine );
371
+ sfc_lock -> lock_bit = GEN11_VCS_SFC_FORCED_LOCK_BIT ;
372
+
373
+ sfc_lock -> ack_reg = GEN11_VCS_SFC_LOCK_STATUS (engine );
374
+ sfc_lock -> ack_bit = GEN11_VCS_SFC_LOCK_ACK_BIT ;
375
+
376
+ sfc_lock -> usage_reg = GEN11_VCS_SFC_LOCK_STATUS (engine );
377
+ sfc_lock -> usage_bit = GEN11_VCS_SFC_USAGE_BIT ;
378
+ sfc_lock -> reset_bit = GEN11_VCS_SFC_RESET_BIT (engine -> instance );
379
+
380
+ break ;
381
+ case VIDEO_ENHANCEMENT_CLASS :
382
+ sfc_lock -> lock_reg = GEN11_VECS_SFC_FORCED_LOCK (engine );
383
+ sfc_lock -> lock_bit = GEN11_VECS_SFC_FORCED_LOCK_BIT ;
384
+
385
+ sfc_lock -> ack_reg = GEN11_VECS_SFC_LOCK_ACK (engine );
386
+ sfc_lock -> ack_bit = GEN11_VECS_SFC_LOCK_ACK_BIT ;
387
+
388
+ sfc_lock -> usage_reg = GEN11_VECS_SFC_USAGE (engine );
389
+ sfc_lock -> usage_bit = GEN11_VECS_SFC_USAGE_BIT ;
390
+ sfc_lock -> reset_bit = GEN11_VECS_SFC_RESET_BIT (engine -> instance );
391
+
392
+ break ;
393
+ }
394
+ }
395
+
396
+ static int gen11_lock_sfc (struct intel_engine_cs * engine ,
397
+ u32 * reset_mask ,
398
+ u32 * unlock_mask )
342
399
{
343
400
struct intel_uncore * uncore = engine -> uncore ;
344
401
u8 vdbox_sfc_access = engine -> gt -> info .vdbox_sfc_access ;
345
- i915_reg_t sfc_forced_lock , sfc_forced_lock_ack ;
346
- u32 sfc_forced_lock_bit , sfc_forced_lock_ack_bit ;
347
- i915_reg_t sfc_usage ;
348
- u32 sfc_usage_bit ;
349
- u32 sfc_reset_bit ;
402
+ struct sfc_lock_data sfc_lock ;
403
+ bool lock_obtained , lock_to_other = false;
350
404
int ret ;
351
405
352
406
switch (engine -> class ) {
353
407
case VIDEO_DECODE_CLASS :
354
408
if ((BIT (engine -> instance ) & vdbox_sfc_access ) == 0 )
355
409
return 0 ;
356
410
357
- sfc_forced_lock = GEN11_VCS_SFC_FORCED_LOCK (engine );
358
- sfc_forced_lock_bit = GEN11_VCS_SFC_FORCED_LOCK_BIT ;
359
-
360
- sfc_forced_lock_ack = GEN11_VCS_SFC_LOCK_STATUS (engine );
361
- sfc_forced_lock_ack_bit = GEN11_VCS_SFC_LOCK_ACK_BIT ;
411
+ fallthrough ;
412
+ case VIDEO_ENHANCEMENT_CLASS :
413
+ get_sfc_forced_lock_data (engine , & sfc_lock );
362
414
363
- sfc_usage = GEN11_VCS_SFC_LOCK_STATUS (engine );
364
- sfc_usage_bit = GEN11_VCS_SFC_USAGE_BIT ;
365
- sfc_reset_bit = GEN11_VCS_SFC_RESET_BIT (engine -> instance );
366
415
break ;
416
+ default :
417
+ return 0 ;
418
+ }
367
419
368
- case VIDEO_ENHANCEMENT_CLASS :
369
- sfc_forced_lock = GEN11_VECS_SFC_FORCED_LOCK (engine );
370
- sfc_forced_lock_bit = GEN11_VECS_SFC_FORCED_LOCK_BIT ;
420
+ if (!(intel_uncore_read_fw (uncore , sfc_lock .usage_reg ) & sfc_lock .usage_bit )) {
421
+ struct intel_engine_cs * paired_vecs ;
371
422
372
- sfc_forced_lock_ack = GEN11_VECS_SFC_LOCK_ACK (engine );
373
- sfc_forced_lock_ack_bit = GEN11_VECS_SFC_LOCK_ACK_BIT ;
423
+ if (engine -> class != VIDEO_DECODE_CLASS ||
424
+ !IS_GEN (engine -> i915 , 12 ))
425
+ return 0 ;
374
426
375
- sfc_usage = GEN11_VECS_SFC_USAGE (engine );
376
- sfc_usage_bit = GEN11_VECS_SFC_USAGE_BIT ;
377
- sfc_reset_bit = GEN11_VECS_SFC_RESET_BIT (engine -> instance );
378
- break ;
427
+ /*
428
+ * Wa_14010733141
429
+ *
430
+ * If the VCS-MFX isn't using the SFC, we also need to check
431
+ * whether VCS-HCP is using it. If so, we need to issue a *VE*
432
+ * forced lock on the VE engine that shares the same SFC.
433
+ */
434
+ if (!(intel_uncore_read_fw (uncore ,
435
+ GEN12_HCP_SFC_LOCK_STATUS (engine )) &
436
+ GEN12_HCP_SFC_USAGE_BIT ))
437
+ return 0 ;
379
438
380
- default :
381
- return 0 ;
439
+ paired_vecs = find_sfc_paired_vecs_engine (engine );
440
+ get_sfc_forced_lock_data (paired_vecs , & sfc_lock );
441
+ lock_to_other = true;
442
+ * unlock_mask |= paired_vecs -> mask ;
443
+ } else {
444
+ * unlock_mask |= engine -> mask ;
382
445
}
383
446
384
447
/*
385
- * If the engine is using a SFC, tell the engine that a software reset
448
+ * If the engine is using an SFC, tell the engine that a software reset
386
449
* is going to happen. The engine will then try to force lock the SFC.
387
450
* If SFC ends up being locked to the engine we want to reset, we have
388
451
* to reset it as well (we will unlock it once the reset sequence is
389
452
* completed).
390
453
*/
391
- if (!(intel_uncore_read_fw (uncore , sfc_usage ) & sfc_usage_bit ))
392
- return 0 ;
393
-
394
- rmw_set_fw (uncore , sfc_forced_lock , sfc_forced_lock_bit );
454
+ rmw_set_fw (uncore , sfc_lock .lock_reg , sfc_lock .lock_bit );
395
455
396
456
ret = __intel_wait_for_register_fw (uncore ,
397
- sfc_forced_lock_ack ,
398
- sfc_forced_lock_ack_bit ,
399
- sfc_forced_lock_ack_bit ,
457
+ sfc_lock . ack_reg ,
458
+ sfc_lock . ack_bit ,
459
+ sfc_lock . ack_bit ,
400
460
1000 , 0 , NULL );
401
461
402
- /* Was the SFC released while we were trying to lock it? */
403
- if (!(intel_uncore_read_fw (uncore , sfc_usage ) & sfc_usage_bit ))
462
+ /*
463
+ * Was the SFC released while we were trying to lock it?
464
+ *
465
+ * We should reset both the engine and the SFC if:
466
+ * - We were locking the SFC to this engine and the lock succeeded
467
+ * OR
468
+ * - We were locking the SFC to a different engine (Wa_14010733141)
469
+ * but the SFC was released before the lock was obtained.
470
+ *
471
+ * Otherwise we need only reset the engine by itself and we can
472
+ * leave the SFC alone.
473
+ */
474
+ lock_obtained = (intel_uncore_read_fw (uncore , sfc_lock .usage_reg ) &
475
+ sfc_lock .usage_bit ) != 0 ;
476
+ if (lock_obtained == lock_to_other )
404
477
return 0 ;
405
478
406
479
if (ret ) {
407
480
ENGINE_TRACE (engine , "Wait for SFC forced lock ack failed\n" );
408
481
return ret ;
409
482
}
410
483
411
- * hw_mask |= sfc_reset_bit ;
484
+ * reset_mask |= sfc_lock . reset_bit ;
412
485
return 0 ;
413
486
}
414
487
415
488
static void gen11_unlock_sfc (struct intel_engine_cs * engine )
416
489
{
417
490
struct intel_uncore * uncore = engine -> uncore ;
418
491
u8 vdbox_sfc_access = engine -> gt -> info .vdbox_sfc_access ;
419
- i915_reg_t sfc_forced_lock ;
420
- u32 sfc_forced_lock_bit ;
421
-
422
- switch (engine -> class ) {
423
- case VIDEO_DECODE_CLASS :
424
- if ((BIT (engine -> instance ) & vdbox_sfc_access ) == 0 )
425
- return ;
426
-
427
- sfc_forced_lock = GEN11_VCS_SFC_FORCED_LOCK (engine );
428
- sfc_forced_lock_bit = GEN11_VCS_SFC_FORCED_LOCK_BIT ;
429
- break ;
492
+ struct sfc_lock_data sfc_lock = {};
430
493
431
- case VIDEO_ENHANCEMENT_CLASS :
432
- sfc_forced_lock = GEN11_VECS_SFC_FORCED_LOCK (engine );
433
- sfc_forced_lock_bit = GEN11_VECS_SFC_FORCED_LOCK_BIT ;
434
- break ;
494
+ if (engine -> class != VIDEO_DECODE_CLASS &&
495
+ engine -> class != VIDEO_ENHANCEMENT_CLASS )
496
+ return ;
435
497
436
- default :
498
+ if (engine -> class == VIDEO_DECODE_CLASS &&
499
+ (BIT (engine -> instance ) & vdbox_sfc_access ) == 0 )
437
500
return ;
438
- }
439
501
440
- rmw_clear_fw (uncore , sfc_forced_lock , sfc_forced_lock_bit );
502
+ get_sfc_forced_lock_data (engine , & sfc_lock );
503
+
504
+ rmw_clear_fw (uncore , sfc_lock .lock_reg , sfc_lock .lock_bit );
441
505
}
442
506
443
507
static int gen11_reset_engines (struct intel_gt * gt ,
@@ -456,34 +520,38 @@ static int gen11_reset_engines(struct intel_gt *gt,
456
520
};
457
521
struct intel_engine_cs * engine ;
458
522
intel_engine_mask_t tmp ;
459
- u32 hw_mask ;
523
+ u32 reset_mask , unlock_mask = 0 ;
460
524
int ret ;
461
525
462
526
if (engine_mask == ALL_ENGINES ) {
463
- hw_mask = GEN11_GRDOM_FULL ;
527
+ reset_mask = GEN11_GRDOM_FULL ;
464
528
} else {
465
- hw_mask = 0 ;
529
+ reset_mask = 0 ;
466
530
for_each_engine_masked (engine , gt , engine_mask , tmp ) {
467
531
GEM_BUG_ON (engine -> id >= ARRAY_SIZE (hw_engine_mask ));
468
- hw_mask |= hw_engine_mask [engine -> id ];
469
- ret = gen11_lock_sfc (engine , & hw_mask );
532
+ reset_mask |= hw_engine_mask [engine -> id ];
533
+ ret = gen11_lock_sfc (engine , & reset_mask , & unlock_mask );
470
534
if (ret )
471
535
goto sfc_unlock ;
472
536
}
473
537
}
474
538
475
- ret = gen6_hw_domain_reset (gt , hw_mask );
539
+ ret = gen6_hw_domain_reset (gt , reset_mask );
476
540
477
541
sfc_unlock :
478
542
/*
479
543
* We unlock the SFC based on the lock status and not the result of
480
544
* gen11_lock_sfc to make sure that we clean properly if something
481
545
* wrong happened during the lock (e.g. lock acquired after timeout
482
546
* expiration).
547
+ *
548
+ * Due to Wa_14010733141, we may have locked an SFC to an engine that
549
+ * wasn't being reset. So instead of calling gen11_unlock_sfc()
550
+ * on engine_mask, we instead call it on the mask of engines that our
551
+ * gen11_lock_sfc() calls told us actually had locks attempted.
483
552
*/
484
- if (engine_mask != ALL_ENGINES )
485
- for_each_engine_masked (engine , gt , engine_mask , tmp )
486
- gen11_unlock_sfc (engine );
553
+ for_each_engine_masked (engine , gt , unlock_mask , tmp )
554
+ gen11_unlock_sfc (engine );
487
555
488
556
return ret ;
489
557
}
0 commit comments