From: Matt Roper Date: Tue, 21 Apr 2026 21:18:34 +0000 (-0700) Subject: drm/xe: Steer MCR for NODE/L3BANK according to L3 fusing on Xe2/Xe3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29e33bb890c2f5a2623d938b677e2039ff3edc68;p=thirdparty%2Fkernel%2Flinux.git drm/xe: Steer MCR for NODE/L3BANK according to L3 fusing on Xe2/Xe3 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 Link: https://patch.msgid.link/20260421-xe2_l3bank_steering-v1-1-613158a27383@intel.com Signed-off-by: Matt Roper --- diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index 7c6f039c880df..89e105cee09b3 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -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 = >->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;