diff options
author | Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> | 2023-11-17 14:51:48 -0800 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-12-21 11:45:06 -0500 |
commit | aae84bf1cd96889a7d80b6b50131f60aa63899d7 (patch) | |
tree | 2d6fdb2646ff60994173c55739c1445d14886866 /drivers/gpu/drm | |
parent | dd0e89e5edc20d3875ed7ded48e7e97118cdfbc8 (diff) |
drm/xe/gsc: Implement WA 14015076503
When the GSC FW is loaded, we need to inform it when a GSCCS reset is
coming and then wait 200ms for it to get ready to process the reset.
v2: move WA code to GSC file, use variable in Makefile (John)
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/xe/Makefile | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/regs/xe_gsc_regs.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gsc.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gsc.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_wa_oob.rules | 1 |
6 files changed, 59 insertions, 1 deletions
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 184e2724ce7b..5806ebb0256a 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -37,7 +37,16 @@ quiet_cmd_wa_oob = GEN $(notdir $(generated_oob)) $(generated_oob) &: $(obj)/xe_gen_wa_oob $(srctree)/$(src)/xe_wa_oob.rules $(call cmd,wa_oob) -$(obj)/xe_guc.o $(obj)/xe_migrate.o $(obj)/xe_ring_ops.o $(obj)/xe_vm.o $(obj)/xe_wa.o $(obj)/xe_ttm_stolen_mgr.o: $(generated_oob) +uses_generated_oob := \ + $(obj)/xe_gsc.o \ + $(obj)/xe_guc.o \ + $(obj)/xe_migrate.o \ + $(obj)/xe_ring_ops.o \ + $(obj)/xe_vm.o \ + $(obj)/xe_wa.o \ + $(obj)/xe_ttm_stolen_mgr.o + +$(uses_generated_oob): $(generated_oob) # Please keep these build lists sorted! diff --git a/drivers/gpu/drm/xe/regs/xe_gsc_regs.h b/drivers/gpu/drm/xe/regs/xe_gsc_regs.h index 22d2ad9cb64d..9a84b55d66ee 100644 --- a/drivers/gpu/drm/xe/regs/xe_gsc_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gsc_regs.h @@ -16,6 +16,13 @@ #define MTL_GSC_HECI1_BASE 0x00116000 #define MTL_GSC_HECI2_BASE 0x00117000 +#define HECI_H_CSR(base) XE_REG((base) + 0x4) +#define HECI_H_CSR_IE REG_BIT(0) +#define HECI_H_CSR_IS REG_BIT(1) +#define HECI_H_CSR_IG REG_BIT(2) +#define HECI_H_CSR_RDY REG_BIT(3) +#define HECI_H_CSR_RST REG_BIT(4) + /* * The FWSTS register values are FW defined and can be different between * HECI1 and HECI2 @@ -26,4 +33,7 @@ #define HECI1_FWSTS1_PROXY_STATE_NORMAL 5 #define HECI1_FWSTS1_INIT_COMPLETE REG_BIT(9) +#define HECI_H_GS1(base) XE_REG((base) + 0xc4c) +#define HECI_H_GS1_ER_PREP REG_BIT(0) + #endif diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c index e014b829bc8a..5731c026a77a 100644 --- a/drivers/gpu/drm/xe/xe_gsc.c +++ b/drivers/gpu/drm/xe/xe_gsc.c @@ -7,6 +7,7 @@ #include <drm/drm_managed.h> +#include "generated/xe_wa_oob.h" #include "xe_bb.h" #include "xe_bo.h" #include "xe_device.h" @@ -17,6 +18,7 @@ #include "xe_mmio.h" #include "xe_sched_job.h" #include "xe_uc_fw.h" +#include "xe_wa.h" #include "instructions/xe_gsc_commands.h" #include "regs/xe_gsc_regs.h" @@ -300,3 +302,30 @@ void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc) if (xe_uc_fw_is_loadable(&gsc->fw) && gsc->wq) flush_work(&gsc->work); } + +/* + * wa_14015076503: if the GSC FW is loaded, we need to alert it before doing a + * GSC engine reset by writing a notification bit in the GS1 register and then + * triggering an interrupt to GSC; from the interrupt it will take up to 200ms + * for the FW to get prepare for the reset, so we need to wait for that amount + * of time. + * After the reset is complete we need to then clear the GS1 register. + */ +void xe_gsc_wa_14015076503(struct xe_gt *gt, bool prep) +{ + u32 gs1_set = prep ? HECI_H_GS1_ER_PREP : 0; + u32 gs1_clr = prep ? 0 : HECI_H_GS1_ER_PREP; + + /* WA only applies if the GSC is loaded */ + if (!XE_WA(gt, 14015076503) || !gsc_fw_is_loaded(gt)) + return; + + xe_mmio_rmw32(gt, HECI_H_GS1(MTL_GSC_HECI2_BASE), gs1_clr, gs1_set); + + if (prep) { + /* make sure the reset bit is clear when writing the CSR reg */ + xe_mmio_rmw32(gt, HECI_H_CSR(MTL_GSC_HECI2_BASE), + HECI_H_CSR_RST, HECI_H_CSR_IG); + msleep(200); + } +} diff --git a/drivers/gpu/drm/xe/xe_gsc.h b/drivers/gpu/drm/xe/xe_gsc.h index f870eddc77d4..bc1ef7f31ea2 100644 --- a/drivers/gpu/drm/xe/xe_gsc.h +++ b/drivers/gpu/drm/xe/xe_gsc.h @@ -8,9 +8,13 @@ #include "xe_gsc_types.h" +struct xe_gt; + int xe_gsc_init(struct xe_gsc *gsc); int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc); void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc); void xe_gsc_load_start(struct xe_gsc *gsc); +void xe_gsc_wa_14015076503(struct xe_gt *gt, bool prep); + #endif diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 0dddb751c6a4..00193b02a7e5 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -21,6 +21,7 @@ #include "xe_execlist.h" #include "xe_force_wake.h" #include "xe_ggtt.h" +#include "xe_gsc.h" #include "xe_gt_clock.h" #include "xe_gt_idle_sysfs.h" #include "xe_gt_mcr.h" @@ -512,12 +513,16 @@ static int do_gt_reset(struct xe_gt *gt) { int err; + xe_gsc_wa_14015076503(gt, true); + xe_mmio_write32(gt, GDRST, GRDOM_FULL); err = xe_mmio_wait32(gt, GDRST, GRDOM_FULL, 0, 5000, NULL, false); if (err) xe_gt_err(gt, "failed to clear GRDOM_FULL (%pe)\n", ERR_PTR(err)); + xe_gsc_wa_14015076503(gt, false); + return err; } diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules index 752842d734be..c7b7d40b5d57 100644 --- a/drivers/gpu/drm/xe/xe_wa_oob.rules +++ b/drivers/gpu/drm/xe/xe_wa_oob.rules @@ -20,3 +20,4 @@ 16017236439 PLATFORM(PVC) 22010954014 PLATFORM(DG2) 14019821291 MEDIA_VERSION_RANGE(1300, 2000) +14015076503 MEDIA_VERSION(1300) |