drm/xe/mocs: MOCS registers are multicast on Xe_HP and beyond
authorMatt Roper <matthew.d.roper@intel.com>
Mon, 23 Oct 2023 20:41:13 +0000 (13:41 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:43:22 +0000 (11:43 -0500)
The MOCS registers should be written in an MCR-specific manner on Xe_HP
and beyond to prevent any other driver threads or external firmware from
putting the hardware into unicast mode while we initialize the MOCS
table.

Bspec: 66534, 67609, 71185
Cc: Ruthuvikas Ravikumar <ruthuvikas.ravikumar@intel.com>
Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
Link: https://lore.kernel.org/r/20231023204112.2856331-2-matthew.d.roper@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/regs/xe_gt_regs.h
drivers/gpu/drm/xe/xe_guc_ads.c
drivers/gpu/drm/xe/xe_mocs.c

index 55ceadfc30b0b7aabce75f4bfb2f670dfcdfd6fc..b00fe089525a5ac63bd337531aede9421f121ac1 100644 (file)
@@ -43,7 +43,8 @@
 #define FORCEWAKE_ACK_GT_MTL                   XE_REG(0xdfc)
 
 /* L3 Cache Control */
-#define LNCFCMOCS(i)                           XE_REG(0xb020 + (i) * 4)
+#define XELP_LNCFCMOCS(i)                      XE_REG(0xb020 + (i) * 4)
+#define XEHP_LNCFCMOCS(i)                      XE_REG_MCR(0xb020 + (i) * 4)
 #define LNCFCMOCS_REG_COUNT                    32
 
 #define MCFG_MCR_SELECTOR                      XE_REG(0xfd0)
@@ -79,7 +80,8 @@
 #define   PREEMPT_GPGPU_LEVEL_MASK             PREEMPT_GPGPU_LEVEL(1, 1)
 #define   PREEMPT_3D_OBJECT_LEVEL              REG_BIT(0)
 
-#define GLOBAL_MOCS(i)                         XE_REG(0x4000 + (i) * 4) /* Global MOCS regs */
+#define XELP_GLOBAL_MOCS(i)                    XE_REG(0x4000 + (i) * 4)
+#define XEHP_GLOBAL_MOCS(i)                    XE_REG_MCR(0x4000 + (i) * 4)
 #define CCS_AUX_INV                            XE_REG(0x4208)
 
 #define VD0_AUX_INV                            XE_REG(0x4218)
index efa4d25424b84281d1649322cb24a917b845a7d0..88789826e78178377317d6af4a047feff05e881e 100644 (file)
@@ -473,7 +473,7 @@ static unsigned int guc_mmio_regset_write(struct xe_guc_ads *ads,
        if (needs_wa_1607983814(xe) && hwe->class == XE_ENGINE_CLASS_RENDER) {
                for (i = 0; i < LNCFCMOCS_REG_COUNT; i++) {
                        guc_mmio_regset_write_one(ads, regset_map,
-                                                 LNCFCMOCS(i), count++);
+                                                 XELP_LNCFCMOCS(i), count++);
                }
        }
 
index 19a8146ded9a76c8ba01075f7e287b32840f7859..21972bbef8fd7e7d46fc165e12917c449a9f622b 100644 (file)
@@ -10,6 +10,7 @@
 #include "xe_device.h"
 #include "xe_exec_queue.h"
 #include "xe_gt.h"
+#include "xe_gt_mcr.h"
 #include "xe_mmio.h"
 #include "xe_platform_types.h"
 #include "xe_step_types.h"
@@ -491,8 +492,7 @@ static u32 get_entry_control(const struct xe_mocs_info *info,
 }
 
 static void __init_mocs_table(struct xe_gt *gt,
-                             const struct xe_mocs_info *info,
-                             u32 addr)
+                             const struct xe_mocs_info *info)
 {
        struct xe_device *xe = gt_to_xe(gt);
 
@@ -505,10 +505,13 @@ static void __init_mocs_table(struct xe_gt *gt,
        for (i = 0;
             i < info->n_entries ? (mocs = get_entry_control(info, i)), 1 : 0;
             i++) {
-               struct xe_reg reg = XE_REG(addr + i * 4);
+               mocs_dbg(&gt_to_xe(gt)->drm, "%d 0x%x 0x%x\n", i,
+                        XELP_GLOBAL_MOCS(i).addr, mocs);
 
-               mocs_dbg(&gt_to_xe(gt)->drm, "%d 0x%x 0x%x\n", i, reg.addr, mocs);
-               xe_mmio_write32(gt, reg, mocs);
+               if (GRAPHICS_VERx100(gt_to_xe(gt)) > 1250)
+                       xe_gt_mcr_multicast_write(gt, XEHP_GLOBAL_MOCS(i), mocs);
+               else
+                       xe_mmio_write32(gt, XELP_GLOBAL_MOCS(i), mocs);
        }
 }
 
@@ -542,9 +545,13 @@ static void init_l3cc_table(struct xe_gt *gt,
             (l3cc = l3cc_combine(get_entry_l3cc(info, 2 * i),
                                  get_entry_l3cc(info, 2 * i + 1))), 1 : 0;
             i++) {
-               mocs_dbg(&gt_to_xe(gt)->drm, "%d 0x%x 0x%x\n", i, LNCFCMOCS(i).addr,
+               mocs_dbg(&gt_to_xe(gt)->drm, "%d 0x%x 0x%x\n", i, XELP_LNCFCMOCS(i).addr,
                         l3cc);
-               xe_mmio_write32(gt, LNCFCMOCS(i), l3cc);
+
+               if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1250)
+                       xe_gt_mcr_multicast_write(gt, XEHP_LNCFCMOCS(i), l3cc);
+               else
+                       xe_mmio_write32(gt, XELP_LNCFCMOCS(i), l3cc);
        }
 }
 
@@ -569,7 +576,7 @@ void xe_mocs_init(struct xe_gt *gt)
        mocs_dbg(&gt_to_xe(gt)->drm, "flag:0x%x\n", flags);
 
        if (flags & HAS_GLOBAL_MOCS)
-               __init_mocs_table(gt, &table, GLOBAL_MOCS(0).addr);
+               __init_mocs_table(gt, &table);
 
        /*
         * Initialize the L3CC table as part of mocs initalization to make