summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/xe/regs/xe_gt_regs.h3
-rw-r--r--drivers/gpu/drm/xe/xe_device.c57
-rw-r--r--drivers/gpu/drm/xe/xe_device_types.h2
-rw-r--r--drivers/gpu/drm/xe/xe_pci.c6
-rw-r--r--drivers/gpu/drm/xe/xe_pci_types.h1
5 files changed, 69 insertions, 0 deletions
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 917a088c28f2..93643da57428 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -227,6 +227,9 @@
#define MIRROR_FUSE1 XE_REG(0x911c)
+#define FUSE2 XE_REG(0x9120)
+#define PRODUCTION_HW REG_BIT(2)
+
#define MIRROR_L3BANK_ENABLE XE_REG(0x9130)
#define XE3_L3BANK_ENABLE REG_GENMASK(31, 0)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 339b9aef9499..cdaa1c1e73f5 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -804,6 +804,61 @@ static int probe_has_flat_ccs(struct xe_device *xe)
return 0;
}
+/*
+ * Detect if the driver is being run on pre-production hardware. We don't
+ * keep workarounds for pre-production hardware long term, so print an
+ * error and add taint if we're being loaded on a pre-production platform
+ * for which the pre-prod workarounds have already been removed.
+ *
+ * The general policy is that we'll remove any workarounds that only apply to
+ * pre-production hardware around the time force_probe restrictions are lifted
+ * for a platform of the next major IP generation (for example, Xe2 pre-prod
+ * workarounds should be removed around the time the first Xe3 platforms have
+ * force_probe lifted).
+ */
+static void detect_preproduction_hw(struct xe_device *xe)
+{
+ struct xe_gt *gt;
+ int id;
+
+ /*
+ * SR-IOV VFs don't have access to the FUSE2 register, so we can't
+ * check pre-production status there. But the host OS will notice
+ * and report the pre-production status, which should be enough to
+ * help us catch mistaken use of pre-production hardware.
+ */
+ if (IS_SRIOV_VF(xe))
+ return;
+
+ /*
+ * The "SW_CAP" fuse contains a bit indicating whether the device is a
+ * production or pre-production device. This fuse is reflected through
+ * the GT "FUSE2" register, even though the contents of the fuse are
+ * not GT-specific. Every GT's reflection of this fuse should show the
+ * same value, so we'll just use the first available GT for lookup.
+ */
+ for_each_gt(gt, xe, id)
+ break;
+
+ if (!gt)
+ return;
+
+ CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GT);
+ if (!xe_force_wake_ref_has_domain(fw_ref.domains, XE_FW_GT)) {
+ xe_gt_err(gt, "Forcewake failure; cannot determine production/pre-production hw status.\n");
+ return;
+ }
+
+ if (xe_mmio_read32(&gt->mmio, FUSE2) & PRODUCTION_HW)
+ return;
+
+ xe_info(xe, "Pre-production hardware detected.\n");
+ if (!xe->info.has_pre_prod_wa) {
+ xe_err(xe, "Pre-production workarounds for this platform have already been removed.\n");
+ add_taint(TAINT_MACHINE_CHECK, LOCKDEP_STILL_OK);
+ }
+}
+
int xe_device_probe(struct xe_device *xe)
{
struct xe_tile *tile;
@@ -974,6 +1029,8 @@ int xe_device_probe(struct xe_device *xe)
if (err)
goto err_unregister_display;
+ detect_preproduction_hw(xe);
+
return devm_add_action_or_reset(xe->drm.dev, xe_device_sanitize, xe);
err_unregister_display:
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 918739f85366..85700533db52 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -327,6 +327,8 @@ struct xe_device {
u8 has_mert:1;
/** @info.has_page_reclaim_hw_assist: Device supports page reclamation feature */
u8 has_page_reclaim_hw_assist:1;
+ /** @info.has_pre_prod_wa: Pre-production workarounds still present in driver */
+ u8 has_pre_prod_wa:1;
/** @info.has_pxp: Device has PXP support */
u8 has_pxp:1;
/** @info.has_range_tlb_inval: Has range based TLB invalidations */
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index 7ff2eb96b841..179797e875b7 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -347,6 +347,7 @@ static const struct xe_device_desc lnl_desc = {
.dma_mask_size = 46,
.has_display = true,
.has_flat_ccs = 1,
+ .has_pre_prod_wa = 1,
.has_pxp = true,
.has_mem_copy_instr = true,
.max_gt_per_tile = 2,
@@ -369,6 +370,7 @@ static const struct xe_device_desc bmg_desc = {
.has_heci_cscfi = 1,
.has_i2c = true,
.has_late_bind = true,
+ .has_pre_prod_wa = 1,
.has_sriov = true,
.has_mem_copy_instr = true,
.max_gt_per_tile = 2,
@@ -388,6 +390,7 @@ static const struct xe_device_desc ptl_desc = {
.has_flat_ccs = 1,
.has_sriov = true,
.has_mem_copy_instr = true,
+ .has_pre_prod_wa = 1,
.max_gt_per_tile = 2,
.needs_scratch = true,
.needs_shared_vf_gt_wq = true,
@@ -401,6 +404,7 @@ static const struct xe_device_desc nvls_desc = {
.has_display = true,
.has_flat_ccs = 1,
.has_mem_copy_instr = true,
+ .has_pre_prod_wa = 1,
.max_gt_per_tile = 2,
.require_force_probe = true,
.va_bits = 48,
@@ -416,6 +420,7 @@ static const struct xe_device_desc cri_desc = {
.has_i2c = true,
.has_mbx_power_limits = true,
.has_mert = true,
+ .has_pre_prod_wa = 1,
.has_sriov = true,
.max_gt_per_tile = 2,
.require_force_probe = true,
@@ -685,6 +690,7 @@ static int xe_info_init_early(struct xe_device *xe,
xe->info.has_llc = desc->has_llc;
xe->info.has_mert = desc->has_mert;
xe->info.has_page_reclaim_hw_assist = desc->has_page_reclaim_hw_assist;
+ xe->info.has_pre_prod_wa = desc->has_pre_prod_wa;
xe->info.has_pxp = desc->has_pxp;
xe->info.has_sriov = xe_configfs_primary_gt_allowed(to_pci_dev(xe->drm.dev)) &&
desc->has_sriov;
diff --git a/drivers/gpu/drm/xe/xe_pci_types.h b/drivers/gpu/drm/xe/xe_pci_types.h
index 602efc5c1252..3bb51d155951 100644
--- a/drivers/gpu/drm/xe/xe_pci_types.h
+++ b/drivers/gpu/drm/xe/xe_pci_types.h
@@ -50,6 +50,7 @@ struct xe_device_desc {
u8 has_mbx_power_limits:1;
u8 has_mem_copy_instr:1;
u8 has_mert:1;
+ u8 has_pre_prod_wa:1;
u8 has_page_reclaim_hw_assist:1;
u8 has_pxp:1;
u8 has_sriov:1;