After a suspend-to-idle cycle, PMFW on SMU 13.0.4 no longer
answers GfxDeviceDriverReset, and the whole SoC hangs when hibernate
sends it before PrepareMp1ForUnload.
Track whether PMFW has been through S0i3 since it was last unloaded.
If it has, skip the GFX reset and MP1 unload for S4. The platform
powers off after the hibernate image is written and PMFW cold-boots
before restore. S0i3 already leaves PMFW running on GFX11 APUs.
Tested on a Redmi Book 15 Pro 2023(Ryzen 7 7840HS, BIOS RMAPH5B0P0909):
s2idle followed by hibernate no longer hangs.
Fixes: fedb6ae49758 ("drm/amd/pm: fixes a random hang in S4 for SMU v13.0.4/11")
Signed-off-by: Maxim Sokolov <[email protected]>
---
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 3 +++
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 2 ++
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c | 11 +++++++++++
3 files changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 86e34e814fe..4988f85526b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -2247,6 +2247,9 @@ static int smu_hw_fini(struct amdgpu_ip_block *ip_block)
adev->pm.dpm_enabled = false;
+ if (adev->in_s0ix)
+ smu->pmfw_s0ix_since_unload = true;
+
ret = smu_smc_hw_cleanup(smu);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 2a0cdc6e805..b0232ccbe1e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -766,6 +766,8 @@ struct smu_context {
long *custom_profile_params;
bool pm_enabled;
bool is_apu;
+ /* PMFW has been through S0i3 since it was last unloaded */
+ bool pmfw_s0ix_since_unload;
/* Power dependency link from an integrated xHCI controller to the GPU
*/
struct device_link *usb_power_link;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
index a9d558f5b73..35274c5c67d 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
@@ -230,6 +230,15 @@ static int smu_v13_0_4_system_features_control(struct
smu_context *smu, bool en)
int ret = 0;
if (!en && !adev->in_s0ix) {
+ /*
+ * After an S0i3 cycle PMFW does not answer
GfxDeviceDriverReset.
+ * Leave PMFW running, as is already done for S0i3 on GFX11
APUs.
+ */
+ if (adev->in_s4 && smu->pmfw_s0ix_since_unload) {
+ dev_dbg(adev->dev, "Skipping MP1 unload for S4 after
S0i3\n");
+ return 0;
+ }
+
if (adev->in_s4) {
/* Adds a GFX reset as workaround just before sending
the
* MP1_UNLOAD message to prevent GC/RLC/PMFW from
entering
@@ -242,6 +251,8 @@ static int smu_v13_0_4_system_features_control(struct
smu_context *smu, bool en)
}
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload,
NULL);
+ if (!ret)
+ smu->pmfw_s0ix_since_unload = false;
}
return ret;
--
2.56.0