On 10/23/26 09:48, Deucher, Alexander wrote:
Public
+ Mario
-----Original Message-----
From: Patel, Maharshii <[email protected]>
Sent: Thursday, September 24, 2026 4:38 PM
To: [email protected]
Cc: Deucher, Alexander <[email protected]>; Koenig, Christian
<[email protected]>; Feng, Kenneth <[email protected]>;
Patel, Maharshii <[email protected]>
Subject: [PATCH] drm/amdgpu: reset dGPU on resume if it kept power across
s2idle
dGPUs take the S3 suspend path even when the platform suspends to idle, but
amdgpu_pmops_suspend_noirq() skips the ASIC reset for s2idle. On desktops
the GPU also keeps power in s2idle, so it resumes without having been reset or
powered off.
SMU 13.0.0/7/10 and 14.0.2/3 skip smu_disable_dpms() on suspend and rely on
the PMFW to clean up on reset or power loss. With neither, the PMFW still
holds its pre-suspend DPM state and stops responding when resume sends
EnableAllSmuFeatures:
amdgpu 0000:03:00.0: SMU: No response msg_reg: 6 resp_reg: 0
amdgpu 0000:03:00.0: resume of IP block <smu> failed -62
SDMA ring resets and mode1 recovery then fail as well, leaving the GPU
unusable until a power cycle. soc24_need_reset_on_resume() does not catch
this, as it only detects aborted suspends.
Do the skipped reset in amdgpu_pmops_resume() when the VBIOS init state
survived suspend, i.e. the GPU kept power. S3, and s2idle platforms that cut
power to the GPU, are unaffected.
Tested with this change applied to the amdgpu 6.19.4 DKMS driver on two
Radeon AI PRO R9700 (gfx1201) on an Intel Z390 system: s2idle failed on the
first cycle without it and passed 16/16 with it; S3 passed 10/10 with no extra
reset.
Can you please check /sys/power/suspend_stats/last_hw_sleep after you've
resumed with and without your patch?
I am guessing it's 0 without and non-zero with?
This should probably use the runtime pm path for dGPUs, otherwise the GPU will
be on the whole time consuming power if the platform doesn't power off the
port. Can you try these patches?
https://gitlab.freedesktop.org/agd5f/linux/-/commits/dgpu_s0i3?ref_type=heads
Makes sense to me.
Alex
Closes: https://github.com/ROCm/legacy-rocm-build/issues/6684
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Maharshii Patel <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 9c5e93c..b9be88e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2703,6 +2703,24 @@ static int amdgpu_pmops_resume(struct device
*dev)
if (!pci_device_is_present(adev->pdev))
adev->no_hw_access = true;
+ /*
+ * A dGPU takes the S3 path even for s2idle, but suspend_noirq skips
+ * the reset there. If the platform also kept the GPU powered (VBIOS
+ * init state survived), the PMFW still holds its pre-suspend DPM
+ * state and times out when resume re-enables features. Do the
+ * skipped reset now; resume will POST the card afterwards if needed.
+ */
+ if (!(adev->flags & AMD_IS_APU) && !amdgpu_sriov_vf(adev) &&
+ !adev->no_hw_access && !amdgpu_acpi_should_gpu_reset(adev)
&&
+ !amdgpu_device_need_post(adev)) {
+ dev_info(adev->dev, "GPU kept power across suspend,
resetting\n");
+ amdgpu_device_lock_reset_domain(adev->reset_domain);
+ r = amdgpu_asic_reset(adev);
+ amdgpu_device_unlock_reset_domain(adev->reset_domain);
+ if (r)
+ dev_err(adev->dev, "reset on resume failed (%d)\n", r);
+ }
+
r = amdgpu_device_resume(drm_dev, true);
if (amdgpu_acpi_is_s0ix_active(adev))
adev->in_s0ix = false;
--
2.43.0