]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: Fix wait after reset sequence in S3
authorLijo Lazar <lijo.lazar@amd.com>
Mon, 3 Nov 2025 10:51:50 +0000 (16:21 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 6 Nov 2025 16:58:32 +0000 (11:58 -0500)
For a mode-1 reset done at the end of S3 on PSPv11 dGPUs, only check if
TOS is unloaded.

Fixes: 32f73741d6ee ("drm/amdgpu: Wait for bootloader after PSPv11 reset")
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4649
Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1ad25fd272753db14c5d1cc8c68e20ce01f3f888)

drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c

index 61268aa82df4d6ce3ea9118575c7935b48595d7e..7333e19291cf936cfe90f7dfcbfae83392ebf668 100644 (file)
@@ -2632,9 +2632,14 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
        struct amdgpu_device *adev = drm_to_adev(drm_dev);
+       int r;
 
-       if (amdgpu_acpi_should_gpu_reset(adev))
-               return amdgpu_asic_reset(adev);
+       if (amdgpu_acpi_should_gpu_reset(adev)) {
+               amdgpu_device_lock_reset_domain(adev->reset_domain);
+               r = amdgpu_asic_reset(adev);
+               amdgpu_device_unlock_reset_domain(adev->reset_domain);
+               return r;
+       }
 
        return 0;
 }
index 64b240b51f1aa7ddb36a919bcdf51ed91ca00cb3..a9be7a505026833f0a35cda2ec6910b96d4e10a8 100644 (file)
@@ -142,13 +142,37 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
        return err;
 }
 
-static int psp_v11_0_wait_for_bootloader(struct psp_context *psp)
+static int psp_v11_wait_for_tos_unload(struct psp_context *psp)
 {
        struct amdgpu_device *adev = psp->adev;
+       uint32_t sol_reg1, sol_reg2;
+       int retry_loop;
 
+       /* Wait for the TOS to be unloaded */
+       for (retry_loop = 0; retry_loop < 20; retry_loop++) {
+               sol_reg1 = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+               usleep_range(1000, 2000);
+               sol_reg2 = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+               if (sol_reg1 == sol_reg2)
+                       return 0;
+       }
+       dev_err(adev->dev, "TOS unload failed, C2PMSG_33: %x C2PMSG_81: %x",
+               RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_33),
+               RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81));
+
+       return -ETIME;
+}
+
+static int psp_v11_0_wait_for_bootloader(struct psp_context *psp)
+{
+       struct amdgpu_device *adev = psp->adev;
        int ret;
        int retry_loop;
 
+       /* For a reset done at the end of S3, only wait for TOS to be unloaded */
+       if (adev->in_s3 && !(adev->flags & AMD_IS_APU) && amdgpu_in_reset(adev))
+               return psp_v11_wait_for_tos_unload(psp);
+
        for (retry_loop = 0; retry_loop < 20; retry_loop++) {
                /* Wait for bootloader to signify that is
                    ready having bit 31 of C2PMSG_35 set to 1 */