]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/xe3p: Determine service copy availability from fuse
authorMatt Roper <matthew.d.roper@intel.com>
Fri, 17 Oct 2025 02:26:27 +0000 (19:26 -0700)
committerLucas De Marchi <lucas.demarchi@intel.com>
Fri, 17 Oct 2025 22:32:38 +0000 (15:32 -0700)
Xe3p introduces a dedicated SERVICE_COPY_ENABLE fuse register to reflect
the availability of the service copy engines (BCS1-BCS8).

Bspec: 74624
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
Link: https://lore.kernel.org/r/20251016-xe3p-v3-8-3dd173a3097a@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/regs/xe_gt_regs.h
drivers/gpu/drm/xe/xe_hw_engine.c

index 21c15441c4537b12b945d09c4c2e6fca88f41675..228de47c0f3f58f0bbf70649c273dbb56382d996 100644 (file)
 #define XE2_GT_GEOMETRY_DSS_1                  XE_REG(0x9150)
 #define XE2_GT_GEOMETRY_DSS_2                  XE_REG(0x9154)
 
+#define SERVICE_COPY_ENABLE                    XE_REG(0x9170)
+#define   FUSE_SERVICE_COPY_ENABLE_MASK                REG_GENMASK(7, 0)
+
 #define GDRST                                  XE_REG(0x941c)
 #define   GRDOM_GUC                            REG_BIT(3)
 #define   GRDOM_FULL                           REG_BIT(0)
index b08a6d42c8ffcf9a3a80be2deb5eb8b76d96b5a5..073ecd263e543ff042872a27bd69d617cc16c796 100644 (file)
@@ -718,27 +718,52 @@ static void read_media_fuses(struct xe_gt *gt)
        }
 }
 
+static u32 infer_svccopy_from_meml3(struct xe_gt *gt)
+{
+       u32 meml3 = REG_FIELD_GET(MEML3_EN_MASK,
+                                 xe_mmio_read32(&gt->mmio, MIRROR_FUSE3));
+       u32 svccopy_mask = 0;
+
+       /*
+        * Each of the four meml3 bits determines the fusing of two service
+        * copy engines.
+        */
+       for (int i = 0; i < 4; i++)
+               svccopy_mask |= (meml3 & BIT(i)) ? 0b11 << 2 * i : 0;
+
+       return svccopy_mask;
+}
+
+static u32 read_svccopy_fuses(struct xe_gt *gt)
+{
+       return REG_FIELD_GET(FUSE_SERVICE_COPY_ENABLE_MASK,
+                            xe_mmio_read32(&gt->mmio, SERVICE_COPY_ENABLE));
+}
+
 static void read_copy_fuses(struct xe_gt *gt)
 {
        struct xe_device *xe = gt_to_xe(gt);
        u32 bcs_mask;
 
-       if (GRAPHICS_VERx100(xe) < 1260 || GRAPHICS_VERx100(xe) >= 1270)
-               return;
-
        xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
 
-       bcs_mask = xe_mmio_read32(&gt->mmio, MIRROR_FUSE3);
-       bcs_mask = REG_FIELD_GET(MEML3_EN_MASK, bcs_mask);
+       if (GRAPHICS_VER(xe) >= 35)
+               bcs_mask = read_svccopy_fuses(gt);
+       else if (GRAPHICS_VERx100(xe) == 1260)
+               bcs_mask = infer_svccopy_from_meml3(gt);
+       else
+               return;
 
-       /* BCS0 is always present; only BCS1-BCS8 may be fused off */
-       for (int i = XE_HW_ENGINE_BCS1, j = 0; i <= XE_HW_ENGINE_BCS8; ++i, ++j) {
+       /* Only BCS1-BCS8 may be fused off */
+       bcs_mask <<= XE_HW_ENGINE_BCS1;
+       for (int i = XE_HW_ENGINE_BCS1; i <= XE_HW_ENGINE_BCS8; ++i) {
                if (!(gt->info.engine_mask & BIT(i)))
                        continue;
 
-               if (!(BIT(j / 2) & bcs_mask)) {
+               if (!(bcs_mask & BIT(i))) {
                        gt->info.engine_mask &= ~BIT(i);
-                       xe_gt_info(gt, "bcs%u fused off\n", j);
+                       xe_gt_info(gt, "bcs%u fused off\n",
+                                  i - XE_HW_ENGINE_BCS0);
                }
        }
 }