Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/xe/pat: Handle unicast vs MCR PAT registers

The PAT_INDEX registers are MCR registers on some platforms and unicast
on others. On MTL the handling even varies between GTs: the primary GT
uses MCR registers while the media GT uses unicast registers. Let's add
proper MCR programming on the relevant platforms/GTs.

Given that we PAT tables to change pretty regularly on future platforms,
we'll make PAT programming an exception to the usual model of assuming
new platforms should inherit the previous platform's behavior. Instead
we'll raise a warning if the current platform isn't handled in the
if/else ladder. This should help prevent subtle cache misbehavior if we
forget to add the table for a new platform.

Bspec: 66534, 67609, 67788
Reviewed-by: Nirmoy Das <nirmoy.das@intel.com>
Link: https://lore.kernel.org/r/20230324210415.2434992-4-matthew.d.roper@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Matt Roper and committed by
Rodrigo Vivi
152d7f2d 4f843703

+30 -7
+30 -7
drivers/gpu/drm/xe/xe_pat.c
··· 7 7 8 8 #include "regs/xe_reg_defs.h" 9 9 #include "xe_gt.h" 10 + #include "xe_gt_mcr.h" 10 11 #include "xe_mmio.h" 11 12 12 - #define GEN12_PAT_INDEX(index) _MMIO(0x4800 + (index) * 4) 13 + #define _PAT_INDEX(index) (0x4800 + (index) * 4) 13 14 14 15 #define GEN8_PPAT_WB (3<<0) 15 16 #define GEN8_PPAT_WT (2<<0) ··· 59 58 60 59 #define PROGRAM_PAT_UNICAST(gt, table) do { \ 61 60 for (int i = 0; i < ARRAY_SIZE(table); i++) \ 62 - xe_mmio_write32(gt, GEN12_PAT_INDEX(i).reg, table[i]); \ 61 + xe_mmio_write32(gt, _PAT_INDEX(i), table[i]); \ 62 + } while (0) 63 + 64 + #define PROGRAM_PAT_MCR(gt, table) do { \ 65 + for (int i = 0; i < ARRAY_SIZE(table); i++) \ 66 + xe_gt_mcr_multicast_write(gt, MCR_REG(_PAT_INDEX(i)), table[i]); \ 63 67 } while (0) 64 68 65 69 void xe_pat_init(struct xe_gt *gt) 66 70 { 67 71 struct xe_device *xe = gt_to_xe(gt); 68 72 69 - if (xe->info.platform == XE_METEORLAKE) 70 - PROGRAM_PAT_UNICAST(gt, mtl_pat_table); 71 - else if (xe->info.platform == XE_PVC) 72 - PROGRAM_PAT_UNICAST(gt, pvc_pat_table); 73 - else 73 + if (xe->info.platform == XE_METEORLAKE) { 74 + if (xe_gt_is_media_type(gt)) 75 + PROGRAM_PAT_UNICAST(gt, mtl_pat_table); 76 + else 77 + PROGRAM_PAT_MCR(gt, mtl_pat_table); 78 + } else if (xe->info.platform == XE_PVC) { 79 + PROGRAM_PAT_MCR(gt, pvc_pat_table); 80 + } else if (xe->info.platform == XE_DG2) { 81 + PROGRAM_PAT_MCR(gt, pvc_pat_table); 82 + } else if (GRAPHICS_VERx100(xe) <= 1210) { 74 83 PROGRAM_PAT_UNICAST(gt, tgl_pat_table); 84 + } else { 85 + /* 86 + * Going forward we expect to need new PAT settings for most 87 + * new platforms; failure to provide a new table can easily 88 + * lead to subtle, hard-to-debug problems. If none of the 89 + * conditions above match the platform we're running on we'll 90 + * raise an error rather than trying to silently inherit the 91 + * most recent platform's behavior. 92 + */ 93 + drm_err(&xe->drm, "Missing PAT table for platform with graphics version %d.%2d!\n", 94 + GRAPHICS_VER(xe), GRAPHICS_VERx100(xe) % 100); 95 + } 75 96 }