43
43
#define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
44
44
#define XE_OA_UNIT_INVALID U32_MAX
45
45
46
+ enum xe_oam_unit_type {
47
+ XE_OAM_UNIT_SAG ,
48
+ XE_OAM_UNIT_SCMI_0 ,
49
+ XE_OAM_UNIT_SCMI_1 ,
50
+ };
51
+
46
52
enum xe_oa_submit_deps {
47
53
XE_OA_SUBMIT_NO_DEPS ,
48
54
XE_OA_SUBMIT_ADD_DEPS ,
@@ -1881,6 +1887,7 @@ static bool engine_supports_oa_format(const struct xe_hw_engine *hwe, int type)
1881
1887
return type == DRM_XE_OA_FMT_TYPE_OAG || type == DRM_XE_OA_FMT_TYPE_OAR ||
1882
1888
type == DRM_XE_OA_FMT_TYPE_OAC || type == DRM_XE_OA_FMT_TYPE_PEC ;
1883
1889
case DRM_XE_OA_UNIT_TYPE_OAM :
1890
+ case DRM_XE_OA_UNIT_TYPE_OAM_SAG :
1884
1891
return type == DRM_XE_OA_FMT_TYPE_OAM || type == DRM_XE_OA_FMT_TYPE_OAM_MPEC ;
1885
1892
default :
1886
1893
return false;
@@ -2448,20 +2455,38 @@ int xe_oa_register(struct xe_device *xe)
2448
2455
2449
2456
static u32 num_oa_units_per_gt (struct xe_gt * gt )
2450
2457
{
2451
- return 1 ;
2458
+ if (!xe_gt_is_media_type (gt ) || GRAPHICS_VER (gt_to_xe (gt )) < 20 )
2459
+ return 1 ;
2460
+ else if (!IS_DGFX (gt_to_xe (gt )))
2461
+ return XE_OAM_UNIT_SCMI_0 + 1 ; /* SAG + SCMI_0 */
2462
+ else
2463
+ return XE_OAM_UNIT_SCMI_1 + 1 ; /* SAG + SCMI_0 + SCMI_1 */
2452
2464
}
2453
2465
2454
2466
static u32 __hwe_oam_unit (struct xe_hw_engine * hwe )
2455
2467
{
2456
- if (GRAPHICS_VERx100 (gt_to_xe (hwe -> gt )) >= 1270 ) {
2457
- /*
2458
- * There's 1 SAMEDIA gt and 1 OAM per SAMEDIA gt. All media slices
2459
- * within the gt use the same OAM. All MTL/LNL SKUs list 1 SA MEDIA
2460
- */
2461
- xe_gt_WARN_ON (hwe -> gt , hwe -> gt -> info .type != XE_GT_TYPE_MEDIA );
2468
+ if (GRAPHICS_VERx100 (gt_to_xe (hwe -> gt )) < 1270 )
2469
+ return XE_OA_UNIT_INVALID ;
2462
2470
2471
+ xe_gt_WARN_ON (hwe -> gt , !xe_gt_is_media_type (hwe -> gt ));
2472
+
2473
+ if (GRAPHICS_VER (gt_to_xe (hwe -> gt )) < 20 )
2463
2474
return 0 ;
2464
- }
2475
+ /*
2476
+ * XE_OAM_UNIT_SAG has only GSCCS attached to it, but only on some platforms. Also
2477
+ * GSCCS cannot be used to submit batches to program the OAM unit. Therefore we don't
2478
+ * assign an OA unit to GSCCS. This means that XE_OAM_UNIT_SAG is exposed as an OA
2479
+ * unit without attached engines. Fused off engines can also result in oa_unit's with
2480
+ * num_engines == 0. OA streams can be opened on all OA units.
2481
+ */
2482
+ else if (hwe -> engine_id == XE_HW_ENGINE_GSCCS0 )
2483
+ return XE_OA_UNIT_INVALID ;
2484
+ else if (!IS_DGFX (gt_to_xe (hwe -> gt )))
2485
+ return XE_OAM_UNIT_SCMI_0 ;
2486
+ else if (hwe -> class == XE_ENGINE_CLASS_VIDEO_DECODE )
2487
+ return (hwe -> instance / 2 & 0x1 ) + 1 ;
2488
+ else if (hwe -> class == XE_ENGINE_CLASS_VIDEO_ENHANCE )
2489
+ return (hwe -> instance & 0x1 ) + 1 ;
2465
2490
2466
2491
return XE_OA_UNIT_INVALID ;
2467
2492
}
@@ -2475,6 +2500,7 @@ static u32 __hwe_oa_unit(struct xe_hw_engine *hwe)
2475
2500
2476
2501
case XE_ENGINE_CLASS_VIDEO_DECODE :
2477
2502
case XE_ENGINE_CLASS_VIDEO_ENHANCE :
2503
+ case XE_ENGINE_CLASS_OTHER :
2478
2504
return __hwe_oam_unit (hwe );
2479
2505
2480
2506
default :
@@ -2514,18 +2540,25 @@ static struct xe_oa_regs __oag_regs(void)
2514
2540
2515
2541
static void __xe_oa_init_oa_units (struct xe_gt * gt )
2516
2542
{
2517
- const u32 mtl_oa_base [] = { 0x13000 };
2543
+ /* Actual address is MEDIA_GT_GSI_OFFSET + oam_base_addr[i] */
2544
+ const u32 oam_base_addr [] = {
2545
+ [XE_OAM_UNIT_SAG ] = 0x13000 ,
2546
+ [XE_OAM_UNIT_SCMI_0 ] = 0x14000 ,
2547
+ [XE_OAM_UNIT_SCMI_1 ] = 0x14800 ,
2548
+ };
2518
2549
int i , num_units = gt -> oa .num_oa_units ;
2519
2550
2520
2551
for (i = 0 ; i < num_units ; i ++ ) {
2521
2552
struct xe_oa_unit * u = & gt -> oa .oa_unit [i ];
2522
2553
2523
- if (gt -> info . type != XE_GT_TYPE_MEDIA ) {
2554
+ if (! xe_gt_is_media_type ( gt ) ) {
2524
2555
u -> regs = __oag_regs ();
2525
2556
u -> type = DRM_XE_OA_UNIT_TYPE_OAG ;
2526
- } else if (GRAPHICS_VERx100 (gt_to_xe (gt )) >= 1270 ) {
2527
- u -> regs = __oam_regs (mtl_oa_base [i ]);
2528
- u -> type = DRM_XE_OA_UNIT_TYPE_OAM ;
2557
+ } else {
2558
+ xe_gt_assert (gt , GRAPHICS_VERx100 (gt_to_xe (gt )) >= 1270 );
2559
+ u -> regs = __oam_regs (oam_base_addr [i ]);
2560
+ u -> type = i == XE_OAM_UNIT_SAG && GRAPHICS_VER (gt_to_xe (gt )) >= 20 ?
2561
+ DRM_XE_OA_UNIT_TYPE_OAM_SAG : DRM_XE_OA_UNIT_TYPE_OAM ;
2529
2562
}
2530
2563
2531
2564
xe_mmio_write32 (& gt -> mmio , u -> regs .oa_ctrl , 0 );
@@ -2560,10 +2593,6 @@ static int xe_oa_init_gt(struct xe_gt *gt)
2560
2593
}
2561
2594
}
2562
2595
2563
- /*
2564
- * Fused off engines can result in oa_unit's with num_engines == 0. These units
2565
- * will appear in OA unit query, but no OA streams can be opened on them.
2566
- */
2567
2596
gt -> oa .num_oa_units = num_oa_units ;
2568
2597
gt -> oa .oa_unit = u ;
2569
2598
@@ -2579,6 +2608,11 @@ static int xe_oa_init_oa_units(struct xe_oa *oa)
2579
2608
struct xe_gt * gt ;
2580
2609
int i , ret ;
2581
2610
2611
+ /* Needed for OAM implementation here */
2612
+ BUILD_BUG_ON (XE_OAM_UNIT_SAG != 0 );
2613
+ BUILD_BUG_ON (XE_OAM_UNIT_SCMI_0 != 1 );
2614
+ BUILD_BUG_ON (XE_OAM_UNIT_SCMI_1 != 2 );
2615
+
2582
2616
for_each_gt (gt , oa -> xe , i ) {
2583
2617
ret = xe_oa_init_gt (gt );
2584
2618
if (ret )
0 commit comments