drm/xe/xe3p: Determine service copy availability from fuse

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>
This commit is contained in:
Matt Roper
2025-10-16 19:26:27 -07:00
committed by Lucas De Marchi
parent f4e9acaa5d
commit c3d318b7f6
2 changed files with 37 additions and 9 deletions

View File

@@ -239,6 +239,9 @@
#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)

View 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);
}
}
}