| From 8b2be55f4d6c1099d7f629b0ed7535a5be788c83 Mon Sep 17 00:00:00 2001 |
| From: Lijo Lazar <lijo.lazar@amd.com> |
| Date: Wed, 14 Feb 2024 17:55:54 +0530 |
| Subject: drm/amdgpu: Reset dGPU if suspend got aborted |
| |
| From: Lijo Lazar <lijo.lazar@amd.com> |
| |
| commit 8b2be55f4d6c1099d7f629b0ed7535a5be788c83 upstream. |
| |
| For SOC21 ASICs, there is an issue in re-enabling PM features if a |
| suspend got aborted. In such cases, reset the device during resume |
| phase. This is a workaround till a proper solution is finalized. |
| |
| Signed-off-by: Lijo Lazar <lijo.lazar@amd.com> |
| Reviewed-by: Alex Deucher <alexander.deucher@amd.com> |
| Reviewed-by: Yang Wang <kevinyang.wang@amd.com> |
| Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/amd/amdgpu/soc21.c | 25 +++++++++++++++++++++++++ |
| 1 file changed, 25 insertions(+) |
| |
| --- a/drivers/gpu/drm/amd/amdgpu/soc21.c |
| +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c |
| @@ -832,10 +832,35 @@ static int soc21_common_suspend(void *ha |
| 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); |
| + 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); |
| } |
| |