Commit 62498733 authored by Alex Deucher's avatar Alex Deucher

drm/amdgpu: rework S3/S4/S0ix state handling

Set flags at the top level pmops callbacks to track
state.  This cleans up the current set of flags and
properly handles S4 on S0ix capable systems.
Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e5192f7b
...@@ -1030,13 +1030,9 @@ struct amdgpu_device { ...@@ -1030,13 +1030,9 @@ struct amdgpu_device {
/* s3/s4 mask */ /* s3/s4 mask */
bool in_suspend; bool in_suspend;
bool in_hibernate; bool in_s3;
bool in_s4;
/* bool in_s0ix;
* The combination flag in_poweroff_reboot_com used to identify the poweroff
* and reboot opt in the s0i3 system-wide suspend.
*/
bool in_poweroff_reboot_com;
atomic_t in_gpu_reset; atomic_t in_gpu_reset;
enum pp_mp1_state mp1_state; enum pp_mp1_state mp1_state;
......
...@@ -2685,8 +2685,7 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev) ...@@ -2685,8 +2685,7 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
{ {
int i, r; int i, r;
if (adev->in_poweroff_reboot_com || adev->in_hibernate || if (!adev->in_s0ix || amdgpu_in_reset(adev)) {
!amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) {
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
} }
...@@ -3766,12 +3765,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) ...@@ -3766,12 +3765,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
amdgpu_fence_driver_suspend(adev); amdgpu_fence_driver_suspend(adev);
/* if (!adev->in_s0ix || amdgpu_in_reset(adev))
* TODO: Need figure out the each GNB IP idle off dependency and then
* improve the AMDGPU suspend/resume sequence for system-wide Sx entry/exit.
*/
if (adev->in_poweroff_reboot_com || adev->in_hibernate ||
!amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev))
r = amdgpu_device_ip_suspend_phase2(adev); r = amdgpu_device_ip_suspend_phase2(adev);
else else
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry); amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
...@@ -3805,7 +3799,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) ...@@ -3805,7 +3799,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0; return 0;
if (amdgpu_acpi_is_s0ix_supported(adev)) if (adev->in_s0ix)
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry); amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry);
/* post card */ /* post card */
......
...@@ -1335,9 +1335,7 @@ amdgpu_pci_shutdown(struct pci_dev *pdev) ...@@ -1335,9 +1335,7 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
*/ */
if (!amdgpu_passthrough(adev)) if (!amdgpu_passthrough(adev))
adev->mp1_state = PP_MP1_STATE_UNLOAD; adev->mp1_state = PP_MP1_STATE_UNLOAD;
adev->in_poweroff_reboot_com = true;
amdgpu_device_ip_suspend(adev); amdgpu_device_ip_suspend(adev);
adev->in_poweroff_reboot_com = false;
adev->mp1_state = PP_MP1_STATE_NONE; adev->mp1_state = PP_MP1_STATE_NONE;
} }
...@@ -1426,15 +1424,28 @@ static void amdgpu_pmops_complete(struct device *dev) ...@@ -1426,15 +1424,28 @@ static void amdgpu_pmops_complete(struct device *dev)
static int amdgpu_pmops_suspend(struct device *dev) static int amdgpu_pmops_suspend(struct device *dev)
{ {
struct drm_device *drm_dev = dev_get_drvdata(dev); struct drm_device *drm_dev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(drm_dev);
int r;
return amdgpu_device_suspend(drm_dev, true); if (amdgpu_acpi_is_s0ix_supported(adev))
adev->in_s0ix = true;
adev->in_s3 = true;
r = amdgpu_device_suspend(drm_dev, true);
adev->in_s3 = false;
return r;
} }
static int amdgpu_pmops_resume(struct device *dev) static int amdgpu_pmops_resume(struct device *dev)
{ {
struct drm_device *drm_dev = dev_get_drvdata(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);
if (amdgpu_acpi_is_s0ix_supported(adev))
adev->in_s0ix = false;
return r;
} }
static int amdgpu_pmops_freeze(struct device *dev) static int amdgpu_pmops_freeze(struct device *dev)
...@@ -1443,9 +1454,9 @@ static int amdgpu_pmops_freeze(struct device *dev) ...@@ -1443,9 +1454,9 @@ static int amdgpu_pmops_freeze(struct device *dev)
struct amdgpu_device *adev = drm_to_adev(drm_dev); struct amdgpu_device *adev = drm_to_adev(drm_dev);
int r; int r;
adev->in_hibernate = true; adev->in_s4 = true;
r = amdgpu_device_suspend(drm_dev, true); r = amdgpu_device_suspend(drm_dev, true);
adev->in_hibernate = false; adev->in_s4 = false;
if (r) if (r)
return r; return r;
return amdgpu_asic_reset(adev); return amdgpu_asic_reset(adev);
...@@ -1461,13 +1472,8 @@ static int amdgpu_pmops_thaw(struct device *dev) ...@@ -1461,13 +1472,8 @@ static int amdgpu_pmops_thaw(struct device *dev)
static int amdgpu_pmops_poweroff(struct device *dev) static int amdgpu_pmops_poweroff(struct device *dev)
{ {
struct drm_device *drm_dev = dev_get_drvdata(dev); struct drm_device *drm_dev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(drm_dev);
int r;
adev->in_poweroff_reboot_com = true; return amdgpu_device_suspend(drm_dev, true);
r = amdgpu_device_suspend(drm_dev, true);
adev->in_poweroff_reboot_com = false;
return r;
} }
static int amdgpu_pmops_restore(struct device *dev) static int amdgpu_pmops_restore(struct device *dev)
......
...@@ -1337,7 +1337,7 @@ static int smu_disable_dpms(struct smu_context *smu) ...@@ -1337,7 +1337,7 @@ static int smu_disable_dpms(struct smu_context *smu)
bool use_baco = !smu->is_apu && bool use_baco = !smu->is_apu &&
((amdgpu_in_reset(adev) && ((amdgpu_in_reset(adev) &&
(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) ||
((adev->in_runpm || adev->in_hibernate) && amdgpu_asic_supports_baco(adev))); ((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev)));
/* /*
* For custom pptable uploading, skip the DPM features * For custom pptable uploading, skip the DPM features
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment