summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_oa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/xe/xe_oa.c')
-rw-r--r--drivers/gpu/drm/xe/xe_oa.c94
1 files changed, 65 insertions, 29 deletions
diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
index f8bb28ab8124..abf87fe0b345 100644
--- a/drivers/gpu/drm/xe/xe_oa.c
+++ b/drivers/gpu/drm/xe/xe_oa.c
@@ -1941,6 +1941,7 @@ static bool oa_unit_supports_oa_format(struct xe_oa_open_param *param, int type)
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;
@@ -1966,10 +1967,6 @@ static int xe_oa_assign_hwe(struct xe_oa *oa, struct xe_oa_open_param *param)
enum xe_hw_engine_id id;
int ret = 0;
- /* If not provided, OA unit defaults to OA unit 0 as per uapi */
- if (!param->oa_unit)
- param->oa_unit = &xe_root_mmio_gt(oa->xe)->oa.oa_unit[0];
-
/* When we have an exec_q, get hwe from the exec_q */
if (param->exec_q) {
param->hwe = xe_gt_hw_engine(param->exec_q->gt, param->exec_q->class,
@@ -2035,7 +2032,15 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
if (ret)
return ret;
+ /* If not provided, OA unit defaults to OA unit 0 as per uapi */
+ if (!param.oa_unit)
+ param.oa_unit = &xe_root_mmio_gt(oa->xe)->oa.oa_unit[0];
+
if (param.exec_queue_id > 0) {
+ /* An exec_queue is only needed for OAR/OAC functionality on OAG */
+ if (XE_IOCTL_DBG(oa->xe, param.oa_unit->type != DRM_XE_OA_UNIT_TYPE_OAG))
+ return -EINVAL;
+
param.exec_q = xe_exec_queue_lookup(xef, param.exec_queue_id);
if (XE_IOCTL_DBG(oa->xe, !param.exec_q))
return -ENOENT;
@@ -2224,6 +2229,8 @@ static const struct xe_mmio_range xe2_oa_mux_regs[] = {
{ .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 */
{},
};
@@ -2515,7 +2522,12 @@ int xe_oa_register(struct xe_device *xe)
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
@@ -2570,40 +2582,57 @@ static u32 __hwe_oa_unit(struct xe_hw_engine *hwe)
static struct xe_oa_regs __oam_regs(u32 base)
{
return (struct xe_oa_regs) {
- base,
- OAM_HEAD_POINTER(base),
- OAM_TAIL_POINTER(base),
- OAM_BUFFER(base),
- OAM_CONTEXT_CONTROL(base),
- OAM_CONTROL(base),
- OAM_DEBUG(base),
- OAM_STATUS(base),
- OAM_CONTROL_COUNTER_SEL_MASK,
+ .base = base,
+ .oa_head_ptr = OAM_HEAD_POINTER(base),
+ .oa_tail_ptr = OAM_TAIL_POINTER(base),
+ .oa_buffer = OAM_BUFFER(base),
+ .oa_ctx_ctrl = OAM_CONTEXT_CONTROL(base),
+ .oa_ctrl = OAM_CONTROL(base),
+ .oa_debug = OAM_DEBUG(base),
+ .oa_status = OAM_STATUS(base),
+ .oa_mmio_trg = OAM_MMIO_TRG(base),
+ .oa_ctrl_counter_select_mask = OAM_CONTROL_COUNTER_SEL_MASK,
};
}
static struct xe_oa_regs __oag_regs(void)
{
return (struct xe_oa_regs) {
- 0,
- OAG_OAHEADPTR,
- OAG_OATAILPTR,
- OAG_OABUFFER,
- OAG_OAGLBCTXCTRL,
- OAG_OACONTROL,
- OAG_OA_DEBUG,
- OAG_OASTATUS,
- OAG_OACONTROL_OA_COUNTER_SEL_MASK,
+ .base = 0,
+ .oa_head_ptr = OAG_OAHEADPTR,
+ .oa_tail_ptr = OAG_OATAILPTR,
+ .oa_buffer = OAG_OABUFFER,
+ .oa_ctx_ctrl = OAG_OAGLBCTXCTRL,
+ .oa_ctrl = OAG_OACONTROL,
+ .oa_debug = OAG_OA_DEBUG,
+ .oa_status = OAG_OASTATUS,
+ .oa_mmio_trg = OAG_MMIOTRIGGER,
+ .oa_ctrl_counter_select_mask = OAG_OACONTROL_OA_COUNTER_SEL_MASK,
+ };
+}
+
+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)
{
- /* 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,
+ [XE_OAM_UNIT_SAG] = XE_OAM_SAG_BASE,
+ [XE_OAM_UNIT_SCMI_0] = XE_OAM_SCMI_0_BASE,
+ [XE_OAM_UNIT_SCMI_1] = XE_OAM_SCMI_1_BASE,
};
int i, num_units = gt->oa.num_oa_units;
@@ -2611,8 +2640,15 @@ static void __xe_oa_init_oa_units(struct xe_gt *gt)
struct xe_oa_unit *u = &gt->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]);