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:
+ case DRM_XE_OA_UNIT_TYPE_MERT:
return type == DRM_XE_OA_FMT_TYPE_OAM || type == DRM_XE_OA_FMT_TYPE_OAM_MPEC;
default:
return false;
{ .start = 0xE18C, .end = 0xE18C }, /* SAMPLER_MODE */
{ .start = 0xE590, .end = 0xE590 }, /* TDL_LSC_LAT_MEASURE_TDL_GFX */
{ .start = 0x13000, .end = 0x137FC }, /* PES_0_PESL0 - PES_63_UPPER_PESL3 */
+ { .start = 0x145194, .end = 0x145194 }, /* SYS_MEM_LAT_MEASURE */
+ { .start = 0x145340, .end = 0x14537C }, /* MERTSS_PES_0 - MERTSS_PES_7 */
{},
};
static u32 num_oa_units_per_gt(struct xe_gt *gt)
{
if (xe_gt_is_main_type(gt) || GRAPHICS_VER(gt_to_xe(gt)) < 20)
- return 1;
+ /*
+ * Mert OA unit belongs to the SoC, not a gt, so should be accessed using
+ * xe_root_tile_mmio(). However, for all known platforms this is the same as
+ * accessing via xe_root_mmio_gt()->mmio.
+ */
+ return xe_device_has_mert(gt_to_xe(gt)) ? 2 : 1;
else if (!IS_DGFX(gt_to_xe(gt)))
return XE_OAM_UNIT_SCMI_0 + 1; /* SAG + SCMI_0 */
else
};
}
+static struct xe_oa_regs __oamert_regs(void)
+{
+ return (struct xe_oa_regs) {
+ .base = 0,
+ .oa_head_ptr = OAMERT_HEAD_POINTER,
+ .oa_tail_ptr = OAMERT_TAIL_POINTER,
+ .oa_buffer = OAMERT_BUFFER,
+ .oa_ctx_ctrl = OAMERT_CONTEXT_CONTROL,
+ .oa_ctrl = OAMERT_CONTROL,
+ .oa_debug = OAMERT_DEBUG,
+ .oa_status = OAMERT_STATUS,
+ .oa_mmio_trg = OAMERT_MMIO_TRG,
+ .oa_ctrl_counter_select_mask = OAM_CONTROL_COUNTER_SEL_MASK,
+ };
+}
+
static void __xe_oa_init_oa_units(struct xe_gt *gt)
{
const u32 oam_base_addr[] = {
struct xe_oa_unit *u = >->oa.oa_unit[i];
if (xe_gt_is_main_type(gt)) {
- u->regs = __oag_regs();
- u->type = DRM_XE_OA_UNIT_TYPE_OAG;
+ if (!i) {
+ u->regs = __oag_regs();
+ u->type = DRM_XE_OA_UNIT_TYPE_OAG;
+ } else {
+ xe_gt_assert(gt, xe_device_has_mert(gt_to_xe(gt)));
+ xe_gt_assert(gt, gt == xe_root_mmio_gt(gt_to_xe(gt)));
+ u->regs = __oamert_regs();
+ u->type = DRM_XE_OA_UNIT_TYPE_MERT;
+ }
} else {
xe_gt_assert(gt, GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270);
u->regs = __oam_regs(oam_base_addr[i]);