From be15e419c1b8f75543577619727d35a483ee7aec Mon Sep 17 00:00:00 2001 From: jsg Date: Thu, 18 Apr 2024 01:04:41 +0000 Subject: [PATCH] drm/amdgpu: Reset dGPU if suspend got aborted From Lijo Lazar 1520bf605d2ff0d733648713b5485865dde0dea9 in linux-6.6.y/6.6.28 8b2be55f4d6c1099d7f629b0ed7535a5be788c83 in mainline linux --- sys/dev/pci/drm/amd/amdgpu/soc21.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sys/dev/pci/drm/amd/amdgpu/soc21.c b/sys/dev/pci/drm/amd/amdgpu/soc21.c index 5a77ab587b5..10aac1b1643 100644 --- a/sys/dev/pci/drm/amd/amdgpu/soc21.c +++ b/sys/dev/pci/drm/amd/amdgpu/soc21.c @@ -804,10 +804,35 @@ static int soc21_common_suspend(void *handle) return soc21_common_hw_fini(adev); } +static bool soc21_need_reset_on_resume(struct amdgpu_device *adev) +{ + u32 sol_reg1, sol_reg2; + + /* Will reset for the following suspend abort cases. + * 1) Only reset dGPU side. + * 2) S3 suspend got aborted and TOS is active. + */ + if (!(adev->flags & AMD_IS_APU) && adev->in_s3 && + !adev->suspend_complete) { + sol_reg1 = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81); + drm_msleep(100); + sol_reg2 = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81); + + return (sol_reg1 != sol_reg2); + } + + return false; +} + static int soc21_common_resume(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + if (soc21_need_reset_on_resume(adev)) { + dev_info(adev->dev, "S3 suspend aborted, resetting..."); + soc21_asic_reset(adev); + } + return soc21_common_hw_init(adev); } -- 2.20.1