]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe: Steer MCR for NODE/L3BANK according to L3 fusing on Xe2/Xe3
authorMatt Roper <matthew.d.roper@intel.com>
Tue, 21 Apr 2026 21:18:34 +0000 (14:18 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Mon, 27 Apr 2026 19:41:43 +0000 (12:41 -0700)
Although the bspec currently indicates that steered reads/writes to L3
register ranges are never terminated for physically present instances
(regardless of fusing) on Xe2, it turns out this is information is
incorrect.  The hardware architects have also confirmed that the current
documentation is wrong (or that possibly the wording was intended to be
interpreted in a different way), but have not yet provided an official
spec update.

All of our driver's writes to registers in these ranges are done as
multicast, so steering is not actually important to proper driver
operation; the only impact of this documentation mistake is that on some
fused-down SKUs where the first L3 bank is absent we're not able to
properly read back the values that were written to those registers to
confirm that the writes were applied correctly (e.g., when using the
register-save-restore-check debugfs interface).

Since we don't have an official spec update yet, let's assume that
Xe2/Xe3 use the same fuse => steering logic as Xe3p.  I.e., remove
L3BANK and NODE register ranges from the "INSTANCE0" steering group and
add handle them with dedicated handling according to the L3 fuses.  From
testing on various fused-down platforms this does appear to give proper
steering and fix the failures reported by IGT's
igt@xe_debugfs@check-gt-reg-sr test.

Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/7706
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Link: https://patch.msgid.link/20260421-xe2_l3bank_steering-v1-1-613158a27383@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
drivers/gpu/drm/xe/xe_gt_mcr.c

index 7c6f039c880dfc8c334a50bed8c2f3880c8323e0..89e105cee09b3f8e68a513485134b276b2e339a8 100644 (file)
@@ -216,9 +216,7 @@ static const struct xe_mmio_range xe2lpg_sqidi_psmi_steering_table[] = {
 static const struct xe_mmio_range xe2lpg_instance0_steering_table[] = {
        { 0x004000, 0x004AFF },         /* GAM, rsvd, GAMWKR */
        { 0x008700, 0x00887F },         /* SQIDI, MEMPIPE */
-       { 0x00B000, 0x00B3FF },         /* NODE, L3BANK */
        { 0x00C800, 0x00CFFF },         /* GAM */
-       { 0x00D880, 0x00D8FF },         /* NODE */
        { 0x00DD00, 0x00DDFF },         /* MEMPIPE */
        { 0x00E900, 0x00E97F },         /* MEMPIPE */
        { 0x00F000, 0x00FFFF },         /* GAM, GAMWKR */
@@ -267,7 +265,7 @@ static const struct xe_mmio_range xe3p_xpc_gam_grp1_steering_table[] = {
        {},
 };
 
-static const struct xe_mmio_range xe3p_xpc_node_steering_table[] = {
+static const struct xe_mmio_range xe2_node_steering_table[] = {
        { 0x00B000, 0x00B0FF },
        { 0x00D880, 0x00D8FF },
        {},
@@ -298,7 +296,7 @@ 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_VER(xe) >= 35) {
+       if (GRAPHICS_VER(xe) >= 20) {
                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;
@@ -536,7 +534,7 @@ void xe_gt_mcr_init_early(struct xe_gt *gt)
                        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;
+                       gt->steering[NODE].ranges = xe2_node_steering_table;
                } else if (GRAPHICS_VERx100(xe) >= 3510) {
                        gt->steering[DSS].ranges = xe2lpg_dss_steering_table;
                        gt->steering[INSTANCE0].ranges = xe3p_lpg_instance0_steering_table;
@@ -544,6 +542,8 @@ void xe_gt_mcr_init_early(struct xe_gt *gt)
                        gt->steering[DSS].ranges = xe2lpg_dss_steering_table;
                        gt->steering[SQIDI_PSMI].ranges = xe2lpg_sqidi_psmi_steering_table;
                        gt->steering[INSTANCE0].ranges = xe2lpg_instance0_steering_table;
+                       gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;
+                       gt->steering[NODE].ranges = xe2_node_steering_table;
                } else if (GRAPHICS_VERx100(xe) >= 1270) {
                        gt->steering[INSTANCE0].ranges = xelpg_instance0_steering_table;
                        gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;