On Tue, Apr 8, 2025 at 2:10 PM Mario Limonciello <supe...@kernel.org> wrote: > > From: Mario Limonciello <mario.limoncie...@amd.com> > > On systems that default to 'deep' some userspace software likes > to try to suspend in 'deep' first. If there is a failure for any > reason (such as -ENOMEM) the failure is ignored and then it will > try to use 's2idle' as a fallback. This fails, but more importantly > it leads to graphical problems. > > Forbid this behavior and only allow suspending in the last state > supported by the system. > > Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4093 > Signed-off-by: Mario Limonciello <mario.limoncie...@amd.com>
Acked-by: Alex Deucher <alexander.deuc...@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 +++++++++++++- > 2 files changed, 14 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 6d83ccfa42eeb..d79fd557b2d6c 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1124,6 +1124,7 @@ struct amdgpu_device { > bool in_s3; > bool in_s4; > bool in_s0ix; > + suspend_state_t last_suspend_state; > > enum pp_mp1_state mp1_state; > struct amdgpu_doorbell_index doorbell_index; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 26bf896f1444e..24ee4710f807f 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -2548,8 +2548,20 @@ static int amdgpu_pmops_suspend(struct device *dev) > adev->in_s0ix = true; > else if (amdgpu_acpi_is_s3_active(adev)) > adev->in_s3 = true; > - if (!adev->in_s0ix && !adev->in_s3) > + if (!adev->in_s0ix && !adev->in_s3) { > + /* don't allow going deep first time followed by s2idle the > next time */ > + if (adev->last_suspend_state != PM_SUSPEND_ON && > + adev->last_suspend_state != pm_suspend_target_state) { > + drm_err_once(drm_dev, "Unsupported suspend state > %d\n", > + pm_suspend_target_state); > + return -EINVAL; > + } > return 0; > + } > + > + /* cache the state last used for suspend */ > + adev->last_suspend_state = pm_suspend_target_state; > + > return amdgpu_device_suspend(drm_dev, true); > } > > -- > 2.43.0 >