]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/guc: Add Wa_14025883347 for GuC DMA failure on reset
authorSk Anirban <sk.anirban@intel.com>
Mon, 2 Feb 2026 10:53:15 +0000 (16:23 +0530)
committerMatt Roper <matthew.d.roper@intel.com>
Mon, 9 Feb 2026 20:00:16 +0000 (12:00 -0800)
Prevent GuC firmware DMA failures during GuC-only reset by disabling
idle flow and verifying SRAM handling completion. Without this, reset
can be issued while SRAM handler is copying WOPCM to SRAM,
causing GuC HW to get stuck.

v2: Modify error message (Badal)
    Rename reg bit name (Daniele)
    Update WA skip condition (Daniele)
    Update SRAM handling logic (Daniele)
v3: Reorder WA call (Badal)
    Wait for GuC ready status (Daniele)
v4: Update reg name (Badal)
    Add comment (Daniele)
    Add extended graphics version (Daniele)
    Modify rules

Signed-off-by: Sk Anirban <sk.anirban@intel.com>
Reviewed-by: Badal Nilawar <badal.nilawar@intel.com>
Acked-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Link: https://patch.msgid.link/20260202105313.3338094-4-sk.anirban@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
drivers/gpu/drm/xe/regs/xe_guc_regs.h
drivers/gpu/drm/xe/xe_guc.c
drivers/gpu/drm/xe/xe_wa_oob.rules

index 87984713dd126117b06f90664fa4c8024342f324..5faac8316b66c4e7fedd70994c39e29a856d0dfb 100644 (file)
@@ -40,6 +40,9 @@
 #define   GS_BOOTROM_JUMP_PASSED               REG_FIELD_PREP(GS_BOOTROM_MASK, 0x76)
 #define   GS_MIA_IN_RESET                      REG_BIT(0)
 
+#define BOOT_HASH_CHK                          XE_REG(0xc010)
+#define   GUC_BOOT_UKERNEL_VALID               REG_BIT(31)
+
 #define GUC_HEADER_INFO                                XE_REG(0xc014)
 
 #define GUC_WOPCM_SIZE                         XE_REG(0xc050)
 #define   GUC_WOPCM_OFFSET_MASK                        REG_GENMASK(31, GUC_WOPCM_OFFSET_SHIFT)
 #define   HUC_LOADING_AGENT_GUC                        REG_BIT(1)
 #define   GUC_WOPCM_OFFSET_VALID               REG_BIT(0)
+
+#define GUC_SRAM_STATUS                                XE_REG(0xc398)
+#define   GUC_SRAM_HANDLING_MASK               REG_GENMASK(8, 7)
+
 #define GUC_MAX_IDLE_COUNT                     XE_REG(0xc3e4)
+#define   GUC_IDLE_FLOW_DISABLE                        REG_BIT(31)
 #define GUC_PMTIMESTAMP_LO                     XE_REG(0xc3e8)
 #define GUC_PMTIMESTAMP_HI                     XE_REG(0xc3ec)
 
index 303f6ae7c418957ab20d8d30f63dd25b2b3edc34..cbbb4d665b8fe66105727e83cfc59a13624d259e 100644 (file)
@@ -917,6 +917,41 @@ int xe_guc_post_load_init(struct xe_guc *guc)
        return xe_guc_submit_enable(guc);
 }
 
+/*
+ * Wa_14025883347: Prevent GuC firmware DMA failures during GuC-only reset by ensuring
+ * SRAM save/restore operations are complete before reset.
+ */
+static void guc_prevent_fw_dma_failure_on_reset(struct xe_guc *guc)
+{
+       struct xe_gt *gt = guc_to_gt(guc);
+       u32 boot_hash_chk, guc_status, sram_status;
+       int ret;
+
+       guc_status = xe_mmio_read32(&gt->mmio, GUC_STATUS);
+       if (guc_status & GS_MIA_IN_RESET)
+               return;
+
+       boot_hash_chk = xe_mmio_read32(&gt->mmio, BOOT_HASH_CHK);
+       if (!(boot_hash_chk & GUC_BOOT_UKERNEL_VALID))
+               return;
+
+       /* Disable idle flow during reset (GuC reset re-enables it automatically) */
+       xe_mmio_rmw32(&gt->mmio, GUC_MAX_IDLE_COUNT, 0, GUC_IDLE_FLOW_DISABLE);
+
+       ret = xe_mmio_wait32(&gt->mmio, GUC_STATUS, GS_UKERNEL_MASK,
+                            FIELD_PREP(GS_UKERNEL_MASK, XE_GUC_LOAD_STATUS_READY),
+                            100000, &guc_status, false);
+       if (ret)
+               xe_gt_warn(gt, "GuC not ready after disabling idle flow (GUC_STATUS: 0x%x)\n",
+                          guc_status);
+
+       ret = xe_mmio_wait32(&gt->mmio, GUC_SRAM_STATUS, GUC_SRAM_HANDLING_MASK,
+                            0, 5000, &sram_status, false);
+       if (ret)
+               xe_gt_warn(gt, "SRAM handling not complete (GUC_SRAM_STATUS: 0x%x)\n",
+                          sram_status);
+}
+
 int xe_guc_reset(struct xe_guc *guc)
 {
        struct xe_gt *gt = guc_to_gt(guc);
@@ -929,6 +964,9 @@ int xe_guc_reset(struct xe_guc *guc)
        if (IS_SRIOV_VF(gt_to_xe(gt)))
                return xe_gt_sriov_vf_bootstrap(gt);
 
+       if (XE_GT_WA(gt, 14025883347))
+               guc_prevent_fw_dma_failure_on_reset(guc);
+
        xe_mmio_write32(mmio, GDRST, GRDOM_GUC);
 
        ret = xe_mmio_wait32(mmio, GDRST, GRDOM_GUC, 0, 5000, &gdrst, false);
index 5cd7fa6d2a5c0456eb18e4bb31b62ae1bd14e615..ac08f94f90a142629545c4964ca0fd3f9cad6aa9 100644 (file)
@@ -73,3 +73,6 @@
 15015404425_disable    PLATFORM(PANTHERLAKE), MEDIA_STEP(B0, FOREVER)
 16026007364    MEDIA_VERSION(3000)
 14020316580    MEDIA_VERSION(1301)
+
+14025883347    MEDIA_VERSION_RANGE(1301, 3503)
+               GRAPHICS_VERSION_RANGE(2004, 3005)