Commit c3d318b7 authored by Matt Roper's avatar Matt Roper Committed by Lucas De Marchi
Browse files

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: default avatarMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: default avatarGustavo Sousa <gustavo.sousa@intel.com>
Link: https://lore.kernel.org/r/20251016-xe3p-v3-8-3dd173a3097a@intel.com


Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
parent f4e9acaa
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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)
+34 −9
Original line number Diff line number Diff line
@@ -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);
		}
	}
}