[PATCH 1/5] drm/xe/oa/uapi: Expose media OA units

Umesh Nerlige Ramappa umesh.nerlige.ramappa at intel.com
Fri Jun 6 17:37:53 UTC 2025


On Fri, Jun 06, 2025 at 09:02:49AM -0700, Ashutosh Dixit wrote:
>On Xe2+ platforms, media engines are attached to "SCMI" OA media (OAM)
>units. One or more SCMI OAM units might be present on a platform. In
>addition there is another OAM unit for global events, called
>OAM-SAG. Performance metrics for media workloads can be obtained from these
>OAM units, similar to OAG.
>
>Expose these OAM units for userspace to use. OAM-SAG is exposed as an OA
>unit without any attached engines.
>
>Bspec: 70819, 67103, 63844, 72572, 74476, 61284
>
>v2: Fix xe_gt_WARN_ON in __hwe_oam_unit for < 12.7 platforms
>v3: Return XE_OA_UNIT_INVALID for < 12.7 to indicate no OAM units
>v4: Move xe_oa_print_oa_units() to separate patch
>v5: Introduce DRM_XE_OA_UNIT_TYPE_OAM_SAG
>
>Signed-off-by: Ashutosh Dixit <ashutosh.dixit at intel.com>

LGTM,

Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa at intel.com>

Thanks,
Umesh
>---
> drivers/gpu/drm/xe/xe_oa.c | 68 ++++++++++++++++++++++++++++----------
> include/uapi/drm/xe_drm.h  |  3 ++
> 2 files changed, 54 insertions(+), 17 deletions(-)
>
>diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
>index fb842fa0552e5..0de0d5a18df74 100644
>--- a/drivers/gpu/drm/xe/xe_oa.c
>+++ b/drivers/gpu/drm/xe/xe_oa.c
>@@ -43,6 +43,12 @@
> #define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
> #define XE_OA_UNIT_INVALID U32_MAX
>
>+enum xe_oam_unit_type {
>+	XE_OAM_UNIT_SAG,
>+	XE_OAM_UNIT_SCMI_0,
>+	XE_OAM_UNIT_SCMI_1,
>+};
>+
> enum xe_oa_submit_deps {
> 	XE_OA_SUBMIT_NO_DEPS,
> 	XE_OA_SUBMIT_ADD_DEPS,
>@@ -1881,6 +1887,7 @@ static bool engine_supports_oa_format(const struct xe_hw_engine *hwe, int type)
> 		return type == DRM_XE_OA_FMT_TYPE_OAG || type == DRM_XE_OA_FMT_TYPE_OAR ||
> 			type == DRM_XE_OA_FMT_TYPE_OAC || type == DRM_XE_OA_FMT_TYPE_PEC;
> 	case DRM_XE_OA_UNIT_TYPE_OAM:
>+	case DRM_XE_OA_UNIT_TYPE_OAM_SAG:
> 		return type == DRM_XE_OA_FMT_TYPE_OAM || type == DRM_XE_OA_FMT_TYPE_OAM_MPEC;
> 	default:
> 		return false;
>@@ -2448,20 +2455,38 @@ int xe_oa_register(struct xe_device *xe)
>
> static u32 num_oa_units_per_gt(struct xe_gt *gt)
> {
>-	return 1;
>+	if (!xe_gt_is_media_type(gt) || GRAPHICS_VER(gt_to_xe(gt)) < 20)
>+		return 1;
>+	else if (!IS_DGFX(gt_to_xe(gt)))
>+		return XE_OAM_UNIT_SCMI_0 + 1; /* SAG + SCMI_0 */
>+	else
>+		return XE_OAM_UNIT_SCMI_1 + 1; /* SAG + SCMI_0 + SCMI_1 */
> }
>
> static u32 __hwe_oam_unit(struct xe_hw_engine *hwe)
> {
>-	if (GRAPHICS_VERx100(gt_to_xe(hwe->gt)) >= 1270) {
>-		/*
>-		 * There's 1 SAMEDIA gt and 1 OAM per SAMEDIA gt. All media slices
>-		 * within the gt use the same OAM. All MTL/LNL SKUs list 1 SA MEDIA
>-		 */
>-		xe_gt_WARN_ON(hwe->gt, hwe->gt->info.type != XE_GT_TYPE_MEDIA);
>+	if (GRAPHICS_VERx100(gt_to_xe(hwe->gt)) < 1270)
>+		return XE_OA_UNIT_INVALID;
>
>+	xe_gt_WARN_ON(hwe->gt, !xe_gt_is_media_type(hwe->gt));
>+
>+	if (GRAPHICS_VER(gt_to_xe(hwe->gt)) < 20)
> 		return 0;
>-	}
>+	/*
>+	 * XE_OAM_UNIT_SAG has only GSCCS attached to it, but only on some platforms. Also
>+	 * GSCCS cannot be used to submit batches to program the OAM unit. Therefore we don't
>+	 * assign an OA unit to GSCCS. This means that XE_OAM_UNIT_SAG is exposed as an OA
>+	 * unit without attached engines. Fused off engines can also result in oa_unit's with
>+	 * num_engines == 0. OA streams can be opened on all OA units.
>+	 */
>+	else if (hwe->engine_id == XE_HW_ENGINE_GSCCS0)
>+		return XE_OA_UNIT_INVALID;
>+	else if (!IS_DGFX(gt_to_xe(hwe->gt)))
>+		return XE_OAM_UNIT_SCMI_0;
>+	else if (hwe->class == XE_ENGINE_CLASS_VIDEO_DECODE)
>+		return (hwe->instance / 2 & 0x1) + 1;
>+	else if (hwe->class == XE_ENGINE_CLASS_VIDEO_ENHANCE)
>+		return (hwe->instance & 0x1) + 1;
>
> 	return XE_OA_UNIT_INVALID;
> }
>@@ -2475,6 +2500,7 @@ static u32 __hwe_oa_unit(struct xe_hw_engine *hwe)
>
> 	case XE_ENGINE_CLASS_VIDEO_DECODE:
> 	case XE_ENGINE_CLASS_VIDEO_ENHANCE:
>+	case XE_ENGINE_CLASS_OTHER:
> 		return __hwe_oam_unit(hwe);
>
> 	default:
>@@ -2514,18 +2540,25 @@ static struct xe_oa_regs __oag_regs(void)
>
> static void __xe_oa_init_oa_units(struct xe_gt *gt)
> {
>-	const u32 mtl_oa_base[] = { 0x13000 };
>+	/* Actual address is MEDIA_GT_GSI_OFFSET + oam_base_addr[i] */
>+	const u32 oam_base_addr[] = {
>+		[XE_OAM_UNIT_SAG]    = 0x13000,
>+		[XE_OAM_UNIT_SCMI_0] = 0x14000,
>+		[XE_OAM_UNIT_SCMI_1] = 0x14800,
>+	};
> 	int i, num_units = gt->oa.num_oa_units;
>
> 	for (i = 0; i < num_units; i++) {
> 		struct xe_oa_unit *u = &gt->oa.oa_unit[i];
>
>-		if (gt->info.type != XE_GT_TYPE_MEDIA) {
>+		if (!xe_gt_is_media_type(gt)) {
> 			u->regs = __oag_regs();
> 			u->type = DRM_XE_OA_UNIT_TYPE_OAG;
>-		} else if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) {
>-			u->regs = __oam_regs(mtl_oa_base[i]);
>-			u->type = DRM_XE_OA_UNIT_TYPE_OAM;
>+		} else {
>+			xe_gt_assert(gt, GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270);
>+			u->regs = __oam_regs(oam_base_addr[i]);
>+			u->type = i == XE_OAM_UNIT_SAG && GRAPHICS_VER(gt_to_xe(gt)) >= 20 ?
>+				DRM_XE_OA_UNIT_TYPE_OAM_SAG : DRM_XE_OA_UNIT_TYPE_OAM;
> 		}
>
> 		xe_mmio_write32(&gt->mmio, u->regs.oa_ctrl, 0);
>@@ -2560,10 +2593,6 @@ static int xe_oa_init_gt(struct xe_gt *gt)
> 		}
> 	}
>
>-	/*
>-	 * Fused off engines can result in oa_unit's with num_engines == 0. These units
>-	 * will appear in OA unit query, but no OA streams can be opened on them.
>-	 */
> 	gt->oa.num_oa_units = num_oa_units;
> 	gt->oa.oa_unit = u;
>
>@@ -2579,6 +2608,11 @@ static int xe_oa_init_oa_units(struct xe_oa *oa)
> 	struct xe_gt *gt;
> 	int i, ret;
>
>+	/* Needed for OAM implementation here */
>+	BUILD_BUG_ON(XE_OAM_UNIT_SAG != 0);
>+	BUILD_BUG_ON(XE_OAM_UNIT_SCMI_0 != 1);
>+	BUILD_BUG_ON(XE_OAM_UNIT_SCMI_1 != 2);
>+
> 	for_each_gt(gt, oa->xe, i) {
> 		ret = xe_oa_init_gt(gt);
> 		if (ret)
>diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
>index 6a702ba7817c3..5460ba1e4cc37 100644
>--- a/include/uapi/drm/xe_drm.h
>+++ b/include/uapi/drm/xe_drm.h
>@@ -1617,6 +1617,9 @@ enum drm_xe_oa_unit_type {
>
> 	/** @DRM_XE_OA_UNIT_TYPE_OAM: OAM OA unit */
> 	DRM_XE_OA_UNIT_TYPE_OAM,
>+
>+	/** @DRM_XE_OA_UNIT_TYPE_OAM_SAG: OAM_SAG OA unit */
>+	DRM_XE_OA_UNIT_TYPE_OAM_SAG,
> };
>
> /**
>-- 
>2.48.1
>


More information about the Intel-xe mailing list