@@ -154,6 +154,41 @@ static const struct xe_pat_table_entry xe2_pat_table[] = {
154154static const struct xe_pat_table_entry xe2_pat_ats = XE2_PAT ( 0 , 0 , 0 , 0 , 3 , 3 );
155155static 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+
157192u16 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+
383468void 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