Commit 8914089a authored by Alex Deucher's avatar Alex Deucher
Browse files

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 9aa26019
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -1007,13 +1007,9 @@ struct amdgpu_device {

	/* s3/s4 mask */
	bool                            in_suspend;
	bool				in_hibernate;

	/*
	 * 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;
	bool				in_s3;
	bool				in_s4;
	bool				in_s0ix;

	atomic_t 			in_gpu_reset;
	enum pp_mp1_state               mp1_state;
+3 −9
Original line number Diff line number Diff line
@@ -2678,8 +2678,7 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
{
	int i, r;

	if (adev->in_poweroff_reboot_com || adev->in_hibernate ||
	    !amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) {
	if (!adev->in_s0ix || amdgpu_in_reset(adev)) {
		amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
		amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
	}
@@ -3742,12 +3741,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)

	amdgpu_fence_driver_suspend(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))
	if (!adev->in_s0ix || amdgpu_in_reset(adev))
		r = amdgpu_device_ip_suspend_phase2(adev);
	else
		amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
@@ -3781,7 +3775,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	if (amdgpu_acpi_is_s0ix_supported(adev))
	if (adev->in_s0ix)
		amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry);

	/* post card */
+18 −12
Original line number Diff line number Diff line
@@ -1274,24 +1274,35 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
	 */
	if (!amdgpu_passthrough(adev))
		adev->mp1_state = PP_MP1_STATE_UNLOAD;
	adev->in_poweroff_reboot_com = true;
	amdgpu_device_ip_suspend(adev);
	adev->in_poweroff_reboot_com = false;
	adev->mp1_state = PP_MP1_STATE_NONE;
}

static int amdgpu_pmops_suspend(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_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)
{
	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)
@@ -1300,9 +1311,9 @@ static int amdgpu_pmops_freeze(struct device *dev)
	struct amdgpu_device *adev = drm_to_adev(drm_dev);
	int r;

	adev->in_hibernate = true;
	adev->in_s4 = true;
	r = amdgpu_device_suspend(drm_dev, true);
	adev->in_hibernate = false;
	adev->in_s4 = false;
	if (r)
		return r;
	return amdgpu_asic_reset(adev);
@@ -1318,13 +1329,8 @@ static int amdgpu_pmops_thaw(struct device *dev)
static int amdgpu_pmops_poweroff(struct device *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;
	r =  amdgpu_device_suspend(drm_dev, true);
	adev->in_poweroff_reboot_com = false;
	return r;
	return amdgpu_device_suspend(drm_dev, true);
}

static int amdgpu_pmops_restore(struct device *dev)
+1 −1
Original line number Diff line number Diff line
@@ -1294,7 +1294,7 @@ static int smu_disable_dpms(struct smu_context *smu)
	bool use_baco = !smu->is_apu &&
		((amdgpu_in_reset(adev) &&
		  (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