On 2025-03-06 13:51, Mario Limonciello wrote: > When userspace invokes S4 the flow is: > > 1) amdgpu_pmops_prepare() > 2) amdgpu_pmops_freeze() > 3) Create hibernation image > 4) amdgpu_pmops_thaw() > 5) Write out image to disk > 6) Turn off system > > Then on resume amdgpu_pmops_restore() is called. > > This flow has a problem that because amdgpu_pmops_thaw() is called > it will call amdgpu_device_resume() which will resume all of the GPU. > > This includes turning the display hardware back on and discovering > connectors again. > > This is an unexpected experience for the display to turn back on. > Adjust the flow so that during the S4 sequence display hardware is > not turned back on. > > Reported-by: Xaver Hugl <xaver.hugl@xxxxxxxxx> > Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2038 > Cc: Muhammad Usama Anjum <usama.anjum@xxxxxxxxxxxxx> > Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> Acked-by: Harry Wentland <harry.wentland@xxxxxxx> Harry > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 11 +++++++++-- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++ > 2 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index b161daa90019..b54c4b2f3f7f 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -2565,7 +2565,6 @@ static int amdgpu_pmops_freeze(struct device *dev) > int r; > > r = amdgpu_device_suspend(drm_dev, true); > - adev->in_s4 = false; > if (r) > return r; > > @@ -2577,8 +2576,13 @@ static int amdgpu_pmops_freeze(struct device *dev) > static int amdgpu_pmops_thaw(struct device *dev) > { > struct drm_device *drm_dev = dev_get_drvdata(dev); > + struct amdgpu_device *adev = drm_to_adev(drm_dev); > + int r; > > - return amdgpu_device_resume(drm_dev, true); > + r = amdgpu_device_resume(drm_dev, true); > + adev->in_s4 = false; > + > + return r; > } > > static int amdgpu_pmops_poweroff(struct device *dev) > @@ -2591,6 +2595,9 @@ static int amdgpu_pmops_poweroff(struct device *dev) > static int amdgpu_pmops_restore(struct device *dev) > { > struct drm_device *drm_dev = dev_get_drvdata(dev); > + struct amdgpu_device *adev = drm_to_adev(drm_dev); > + > + adev->in_s4 = false; > > return amdgpu_device_resume(drm_dev, true); > } > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index 6f9331fe91c3..5939796db74c 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -3431,6 +3431,11 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) > > return 0; > } > + > + /* leave display off for S4 sequence */ > + if (adev->in_s4) > + return 0; > + > /* Recreate dc_state - DC invalidates it when setting power state to S3. */ > dc_state_release(dm_state->context); > dm_state->context = dc_state_create(dm->dc, NULL);