]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/xe3p_xpc: Add MCR steering for NODE and L3BANK ranges
authorMatt Roper <matthew.d.roper@intel.com>
Tue, 21 Oct 2025 22:45:56 +0000 (15:45 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Thu, 23 Oct 2025 23:22:06 +0000 (16:22 -0700)
The bspec was originally missing the information related to steering of
L3-related ranges.  Now that a late-breaking spec update has added the
necessary information, implement the steering rules in the code.  Note
that the sole L3BANK range is the same as the one used on Xe_LPG, so we
can re-use the existing table for that MCR type.

Bspec: 74418
Fixes: be614ea19dad ("drm/xe/xe3p_xpc: Add MCR steering")
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/20251021224556.437970-3-matthew.d.roper@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
drivers/gpu/drm/xe/xe_gt_mcr.c
drivers/gpu/drm/xe/xe_gt_topology.c
drivers/gpu/drm/xe/xe_gt_topology.h
drivers/gpu/drm/xe/xe_gt_types.h

index 0b4b617d413b6064faedd89e4e3307bcd2acaa1c..1640108606640029ba33d048f21f3cd296a83365 100644 (file)
@@ -268,6 +268,12 @@ static const struct xe_mmio_range xe3p_xpc_gam_grp1_steering_table[] = {
        {},
 };
 
+static const struct xe_mmio_range xe3p_xpc_node_steering_table[] = {
+       { 0x00B000, 0x00B0FF },
+       { 0x00D880, 0x00D8FF },
+       {},
+};
+
 static const struct xe_mmio_range xe3p_xpc_instance0_steering_table[] = {
        { 0x00B500, 0x00B6FF },         /* PSMI */
        { 0x00C800, 0x00CFFF },         /* GAMCTRL */
@@ -277,9 +283,22 @@ static const struct xe_mmio_range xe3p_xpc_instance0_steering_table[] = {
 
 static void init_steering_l3bank(struct xe_gt *gt)
 {
+       struct xe_device *xe = gt_to_xe(gt);
        struct xe_mmio *mmio = &gt->mmio;
 
-       if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) {
+       if (GRAPHICS_VER(xe) >= 35) {
+               unsigned int first_bank = xe_l3_bank_mask_ffs(gt->fuse_topo.l3_bank_mask);
+               const int banks_per_node = 4;
+               unsigned int node = first_bank / banks_per_node;
+
+               /* L3BANK ranges place node in grpID, bank in instanceid */
+               gt->steering[L3BANK].group_target = node;
+               gt->steering[L3BANK].instance_target = first_bank % banks_per_node;
+
+               /* NODE ranges split the node across grpid and instanceid */
+               gt->steering[NODE].group_target = node >> 1;
+               gt->steering[NODE].instance_target = node & 1;
+       } else if (GRAPHICS_VERx100(xe) >= 1270) {
                u32 mslice_mask = REG_FIELD_GET(MEML3_EN_MASK,
                                                xe_mmio_read32(mmio, MIRROR_FUSE3));
                u32 bank_mask = REG_FIELD_GET(GT_L3_EXC_MASK,
@@ -292,7 +311,7 @@ static void init_steering_l3bank(struct xe_gt *gt)
                gt->steering[L3BANK].group_target = __ffs(mslice_mask);
                gt->steering[L3BANK].instance_target =
                        bank_mask & BIT(0) ? 0 : 2;
-       } else if (gt_to_xe(gt)->info.platform == XE_DG2) {
+       } else if (xe->info.platform == XE_DG2) {
                u32 mslice_mask = REG_FIELD_GET(MEML3_EN_MASK,
                                                xe_mmio_read32(mmio, MIRROR_FUSE3));
                u32 bank = __ffs(mslice_mask) * 8;
@@ -458,6 +477,7 @@ static const struct {
        void (*init)(struct xe_gt *gt);
 } xe_steering_types[] = {
        [L3BANK] =      { "L3BANK",     init_steering_l3bank },
+       [NODE] =        { "NODE",       NULL }, /* initialized by l3bank init */
        [MSLICE] =      { "MSLICE",     init_steering_mslice },
        [LNCF] =        { "LNCF",       NULL }, /* initialized by mslice init */
        [DSS] =         { "DSS / XeCore", init_steering_dss },
@@ -512,6 +532,8 @@ void xe_gt_mcr_init_early(struct xe_gt *gt)
                        gt->steering[DSS].ranges = xe3p_xpc_xecore_steering_table;
                        gt->steering[GAM1].ranges = xe3p_xpc_gam_grp1_steering_table;
                        gt->steering[INSTANCE0].ranges = xe3p_xpc_instance0_steering_table;
+                       gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;
+                       gt->steering[NODE].ranges = xe3p_xpc_node_steering_table;
                } else if (GRAPHICS_VER(xe) >= 20) {
                        gt->steering[DSS].ranges = xe2lpg_dss_steering_table;
                        gt->steering[SQIDI_PSMI].ranges = xe2lpg_sqidi_psmi_steering_table;
index 1e0516ba7422fad7bbb7b71ba7f922df12488a04..bd5260221d8db0c88849ccc1c2f4a4d382358c2c 100644 (file)
@@ -309,6 +309,13 @@ xe_dss_mask_group_ffs(const xe_dss_mask_t mask, int groupsize, int groupnum)
        return find_next_bit(mask, XE_MAX_DSS_FUSE_BITS, groupnum * groupsize);
 }
 
+/* Used to obtain the index of the first L3 bank. */
+unsigned int
+xe_l3_bank_mask_ffs(const xe_l3_bank_mask_t mask)
+{
+       return find_first_bit(mask, XE_MAX_L3_BANK_MASK_BITS);
+}
+
 /**
  * xe_gt_topology_has_dss_in_quadrant - check fusing of DSS in GT quadrant
  * @gt: GT to check
index 3ff40f44bf2a41c28d6db541e2f325ef96e29bac..162d603c9b81b1fdf7a3846a0885a41e075524d8 100644 (file)
@@ -40,6 +40,8 @@ xe_gt_topology_mask_last_dss(const xe_dss_mask_t mask)
 
 unsigned int
 xe_dss_mask_group_ffs(const xe_dss_mask_t mask, int groupsize, int groupnum);
+unsigned int
+xe_l3_bank_mask_ffs(const xe_l3_bank_mask_t mask);
 
 bool
 xe_gt_topology_has_dss_in_quadrant(struct xe_gt *gt, int quad);
index 6e9c84b33b60cd5cd9e9a6558274c68c5a3e7009..0b525643a048a457438df3a4ed724e74f571c6a3 100644 (file)
@@ -66,6 +66,7 @@ struct xe_mmio_range {
  */
 enum xe_steering_type {
        L3BANK,
+       NODE,
        MSLICE,
        LNCF,
        DSS,