]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/pat: Determine ATS / PTA programming during early sw init
authorMatt Roper <matthew.d.roper@intel.com>
Fri, 13 Jun 2025 21:47:52 +0000 (14:47 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Mon, 16 Jun 2025 15:58:59 +0000 (08:58 -0700)
Decide whether programming of the special ATS and PTA PAT entries is
necessary (and which entries should be programmed) during early software
initialization rather than hardcoding this into the 'program' functions.
Future platforms may want to re-use the same functions but utilize
different special entry values.  Consolidating all of the decisions
into one place keeps things simple.

Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
Link: https://lore.kernel.org/r/20250613214751.792066-3-matthew.d.roper@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
drivers/gpu/drm/xe/xe_device_types.h
drivers/gpu/drm/xe/xe_pat.c

index e5d02a47a52879cf69da5c3c8fcea0880adc9e93..a504b8ea6f3fb613d2466c590783d9f84d54773b 100644 (file)
@@ -502,6 +502,10 @@ struct xe_device {
                const struct xe_pat_table_entry *table;
                /** @pat.n_entries: Number of PAT entries */
                int n_entries;
+               /** @pat.ats_entry: PAT entry for PCIe ATS responses */
+               const struct xe_pat_table_entry *pat_ats;
+               /** @pat.pta_entry: PAT entry for page table accesses */
+               const struct xe_pat_table_entry *pat_pta;
                u32 idx[__XE_CACHE_LEVEL_COUNT];
        } pat;
 
index 38a6a49c1b2a7f3fb252aa30495ab60fbfd088e4..31663ead78227f9dd8b7aab3c13cc5e4a1c010fb 100644 (file)
@@ -307,21 +307,27 @@ static const struct xe_pat_ops xelpg_pat_ops = {
 static void xe2lpg_program_pat(struct xe_gt *gt, const struct xe_pat_table_entry table[],
                               int n_entries)
 {
+       struct xe_device *xe = gt_to_xe(gt);
+
        program_pat_mcr(gt, table, n_entries);
-       xe_gt_mcr_multicast_write(gt, XE_REG_MCR(_PAT_ATS), xe2_pat_ats.value);
 
-       if (IS_DGFX(gt_to_xe(gt)))
-               xe_gt_mcr_multicast_write(gt, XE_REG_MCR(_PAT_PTA), xe2_pat_pta.value);
+       if (xe->pat.pat_ats)
+               xe_gt_mcr_multicast_write(gt, XE_REG_MCR(_PAT_ATS), xe->pat.pat_ats->value);
+       if (xe->pat.pat_pta)
+               xe_gt_mcr_multicast_write(gt, XE_REG_MCR(_PAT_PTA), xe->pat.pat_pta->value);
 }
 
 static void xe2lpm_program_pat(struct xe_gt *gt, const struct xe_pat_table_entry table[],
                               int n_entries)
 {
+       struct xe_device *xe = gt_to_xe(gt);
+
        program_pat(gt, table, n_entries);
-       xe_mmio_write32(&gt->mmio, XE_REG(_PAT_ATS), xe2_pat_ats.value);
 
-       if (IS_DGFX(gt_to_xe(gt)))
-               xe_mmio_write32(&gt->mmio, XE_REG(_PAT_PTA), xe2_pat_pta.value);
+       if (xe->pat.pat_ats)
+               xe_mmio_write32(&gt->mmio, XE_REG(_PAT_ATS), xe->pat.pat_ats->value);
+       if (xe->pat.pat_pta)
+               xe_mmio_write32(&gt->mmio, XE_REG(_PAT_PTA), xe->pat.pat_pta->value);
 }
 
 static void xe2_dump(struct xe_gt *gt, struct drm_printer *p)
@@ -386,6 +392,9 @@ void xe_pat_init_early(struct xe_device *xe)
        if (GRAPHICS_VER(xe) == 30 || GRAPHICS_VER(xe) == 20) {
                xe->pat.ops = &xe2_pat_ops;
                xe->pat.table = xe2_pat_table;
+               xe->pat.pat_ats = &xe2_pat_ats;
+               if (IS_DGFX(xe))
+                       xe->pat.pat_pta = &xe2_pat_pta;
 
                /* Wa_16023588340. XXX: Should use XE_WA */
                if (GRAPHICS_VERx100(xe) == 2001)