Skip to content

Commit bf3035f

Browse files
mattropeLucas De Marchi
authored andcommitted
drm/xe/xe3p_xpc: Setup PAT table
Xe3p_XPC IP requires a new PAT table; note that this table has one fewer column than the Xe2/Xe3 tables since compression is not supported. There's also no "WT" entry (which we wouldn't have used on a platform without display anyway). Bspec: 71582 Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com> Link: https://lore.kernel.org/r/20251016-xe3p-v3-23-3dd173a3097a@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
1 parent bd03427 commit bf3035f

1 file changed

Lines changed: 95 additions & 1 deletion

File tree

drivers/gpu/drm/xe/xe_pat.c

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,41 @@ static const struct xe_pat_table_entry xe2_pat_table[] = {
154154
static const struct xe_pat_table_entry xe2_pat_ats = XE2_PAT( 0, 0, 0, 0, 3, 3 );
155155
static const struct xe_pat_table_entry xe2_pat_pta = XE2_PAT( 0, 0, 0, 0, 3, 0 );
156156

157+
/*
158+
* Xe3p_XPC PAT table uses the same layout as Xe2/Xe3, except that there's no
159+
* option for compression. Also note that the "L3" and "L4" register fields
160+
* actually control L2 and L3 cache respectively on this platform.
161+
*/
162+
#define XE3P_XPC_PAT(no_promote, l3clos, l3_policy, l4_policy, __coh_mode) \
163+
XE2_PAT(no_promote, 0, l3clos, l3_policy, l4_policy, __coh_mode)
164+
165+
static const struct xe_pat_table_entry xe3p_xpc_pat_ats = XE3P_XPC_PAT( 0, 0, 0, 0, 3 );
166+
static const struct xe_pat_table_entry xe3p_xpc_pat_pta = XE3P_XPC_PAT( 0, 0, 0, 0, 0 );
167+
168+
static const struct xe_pat_table_entry xe3p_xpc_pat_table[] = {
169+
[ 0] = XE3P_XPC_PAT( 0, 0, 0, 0, 0 ),
170+
[ 1] = XE3P_XPC_PAT( 0, 0, 0, 0, 2 ),
171+
[ 2] = XE3P_XPC_PAT( 0, 0, 0, 0, 3 ),
172+
[ 3] = XE3P_XPC_PAT( 0, 0, 3, 3, 0 ),
173+
[ 4] = XE3P_XPC_PAT( 0, 0, 3, 3, 2 ),
174+
[ 5] = XE3P_XPC_PAT( 0, 0, 3, 0, 0 ),
175+
[ 6] = XE3P_XPC_PAT( 0, 0, 3, 0, 2 ),
176+
[ 7] = XE3P_XPC_PAT( 0, 0, 3, 0, 3 ),
177+
[ 8] = XE3P_XPC_PAT( 0, 0, 0, 3, 0 ),
178+
[ 9] = XE3P_XPC_PAT( 0, 0, 0, 3, 2 ),
179+
[10] = XE3P_XPC_PAT( 0, 0, 0, 3, 3 ),
180+
/* 11..22 are reserved; leave set to all 0's */
181+
[23] = XE3P_XPC_PAT( 0, 1, 0, 0, 0 ),
182+
[24] = XE3P_XPC_PAT( 0, 1, 0, 0, 2 ),
183+
[25] = XE3P_XPC_PAT( 0, 1, 0, 0, 3 ),
184+
[26] = XE3P_XPC_PAT( 0, 2, 0, 0, 0 ),
185+
[27] = XE3P_XPC_PAT( 0, 2, 0, 0, 2 ),
186+
[28] = XE3P_XPC_PAT( 0, 2, 0, 0, 3 ),
187+
[29] = XE3P_XPC_PAT( 0, 3, 0, 0, 0 ),
188+
[30] = XE3P_XPC_PAT( 0, 3, 0, 0, 2 ),
189+
[31] = XE3P_XPC_PAT( 0, 3, 0, 0, 3 ),
190+
};
191+
157192
u16 xe_pat_index_get_coh_mode(struct xe_device *xe, u16 pat_index)
158193
{
159194
WARN_ON(pat_index >= xe->pat.n_entries);
@@ -380,9 +415,68 @@ static const struct xe_pat_ops xe2_pat_ops = {
380415
.dump = xe2_dump,
381416
};
382417

418+
static int xe3p_xpc_dump(struct xe_gt *gt, struct drm_printer *p)
419+
{
420+
struct xe_device *xe = gt_to_xe(gt);
421+
unsigned int fw_ref;
422+
u32 pat;
423+
int i;
424+
425+
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
426+
if (!fw_ref)
427+
return -ETIMEDOUT;
428+
429+
drm_printf(p, "PAT table:\n");
430+
431+
for (i = 0; i < xe->pat.n_entries; i++) {
432+
pat = xe_gt_mcr_unicast_read_any(gt, XE_REG_MCR(_PAT_INDEX(i)));
433+
434+
drm_printf(p, "PAT[%2d] = [ %u, %u, %u, %u, %u ] (%#8x)\n", i,
435+
!!(pat & XE2_NO_PROMOTE),
436+
REG_FIELD_GET(XE2_L3_CLOS, pat),
437+
REG_FIELD_GET(XE2_L3_POLICY, pat),
438+
REG_FIELD_GET(XE2_L4_POLICY, pat),
439+
REG_FIELD_GET(XE2_COH_MODE, pat),
440+
pat);
441+
}
442+
443+
/*
444+
* Also print PTA_MODE, which describes how the hardware accesses
445+
* PPGTT entries.
446+
*/
447+
pat = xe_gt_mcr_unicast_read_any(gt, XE_REG_MCR(_PAT_PTA));
448+
449+
drm_printf(p, "Page Table Access:\n");
450+
drm_printf(p, "PTA_MODE= [ %u, %u, %u, %u, %u ] (%#8x)\n",
451+
!!(pat & XE2_NO_PROMOTE),
452+
REG_FIELD_GET(XE2_L3_CLOS, pat),
453+
REG_FIELD_GET(XE2_L3_POLICY, pat),
454+
REG_FIELD_GET(XE2_L4_POLICY, pat),
455+
REG_FIELD_GET(XE2_COH_MODE, pat),
456+
pat);
457+
458+
xe_force_wake_put(gt_to_fw(gt), fw_ref);
459+
return 0;
460+
}
461+
462+
static const struct xe_pat_ops xe3p_xpc_pat_ops = {
463+
.program_graphics = program_pat_mcr,
464+
.program_media = program_pat,
465+
.dump = xe3p_xpc_dump,
466+
};
467+
383468
void xe_pat_init_early(struct xe_device *xe)
384469
{
385-
if (GRAPHICS_VER(xe) == 30 || GRAPHICS_VER(xe) == 20) {
470+
if (GRAPHICS_VERx100(xe) == 3511) {
471+
xe->pat.ops = &xe3p_xpc_pat_ops;
472+
xe->pat.table = xe3p_xpc_pat_table;
473+
xe->pat.pat_ats = &xe3p_xpc_pat_ats;
474+
xe->pat.pat_pta = &xe3p_xpc_pat_pta;
475+
xe->pat.n_entries = ARRAY_SIZE(xe3p_xpc_pat_table);
476+
xe->pat.idx[XE_CACHE_NONE] = 3;
477+
xe->pat.idx[XE_CACHE_WT] = 3; /* N/A (no display); use UC */
478+
xe->pat.idx[XE_CACHE_WB] = 2;
479+
} else if (GRAPHICS_VER(xe) == 30 || GRAPHICS_VER(xe) == 20) {
386480
xe->pat.ops = &xe2_pat_ops;
387481
xe->pat.table = xe2_pat_table;
388482
xe->pat.pat_ats = &xe2_pat_ats;

0 commit comments

Comments
 (0)