mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/amdgpu: add missing cleanups for more ASICs on UVD/VCE suspend
This is a supplement for commit below: "drm/amdgpu: add missing cleanups for Polaris12 UVD/VCE on suspend". Signed-off-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Guchun Chen <guchun.chen@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									bf756fb833
								
							
						
					
					
						commit
						859e465927
					
				
					 6 changed files with 144 additions and 1 deletions
				
			
		| 
						 | 
					@ -698,6 +698,30 @@ static int uvd_v3_1_hw_fini(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Proper cleanups before halting the HW engine:
 | 
				
			||||||
 | 
						 *   - cancel the delayed idle work
 | 
				
			||||||
 | 
						 *   - enable powergating
 | 
				
			||||||
 | 
						 *   - enable clockgating
 | 
				
			||||||
 | 
						 *   - disable dpm
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * TODO: to align with the VCN implementation, move the
 | 
				
			||||||
 | 
						 * jobs for clockgating/powergating/dpm setting to
 | 
				
			||||||
 | 
						 * ->set_powergating_state().
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cancel_delayed_work_sync(&adev->uvd.idle_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							amdgpu_dpm_enable_uvd(adev, false);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							amdgpu_asic_set_uvd_clocks(adev, 0, 0);
 | 
				
			||||||
 | 
							/* shutdown the UVD block */
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (RREG32(mmUVD_STATUS) != 0)
 | 
						if (RREG32(mmUVD_STATUS) != 0)
 | 
				
			||||||
		uvd_v3_1_stop(adev);
 | 
							uvd_v3_1_stop(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -212,6 +212,30 @@ static int uvd_v4_2_hw_fini(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Proper cleanups before halting the HW engine:
 | 
				
			||||||
 | 
						 *   - cancel the delayed idle work
 | 
				
			||||||
 | 
						 *   - enable powergating
 | 
				
			||||||
 | 
						 *   - enable clockgating
 | 
				
			||||||
 | 
						 *   - disable dpm
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * TODO: to align with the VCN implementation, move the
 | 
				
			||||||
 | 
						 * jobs for clockgating/powergating/dpm setting to
 | 
				
			||||||
 | 
						 * ->set_powergating_state().
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cancel_delayed_work_sync(&adev->uvd.idle_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							amdgpu_dpm_enable_uvd(adev, false);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							amdgpu_asic_set_uvd_clocks(adev, 0, 0);
 | 
				
			||||||
 | 
							/* shutdown the UVD block */
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (RREG32(mmUVD_STATUS) != 0)
 | 
						if (RREG32(mmUVD_STATUS) != 0)
 | 
				
			||||||
		uvd_v4_2_stop(adev);
 | 
							uvd_v4_2_stop(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -210,6 +210,30 @@ static int uvd_v5_0_hw_fini(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Proper cleanups before halting the HW engine:
 | 
				
			||||||
 | 
						 *   - cancel the delayed idle work
 | 
				
			||||||
 | 
						 *   - enable powergating
 | 
				
			||||||
 | 
						 *   - enable clockgating
 | 
				
			||||||
 | 
						 *   - disable dpm
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * TODO: to align with the VCN implementation, move the
 | 
				
			||||||
 | 
						 * jobs for clockgating/powergating/dpm setting to
 | 
				
			||||||
 | 
						 * ->set_powergating_state().
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cancel_delayed_work_sync(&adev->uvd.idle_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							amdgpu_dpm_enable_uvd(adev, false);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							amdgpu_asic_set_uvd_clocks(adev, 0, 0);
 | 
				
			||||||
 | 
							/* shutdown the UVD block */
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (RREG32(mmUVD_STATUS) != 0)
 | 
						if (RREG32(mmUVD_STATUS) != 0)
 | 
				
			||||||
		uvd_v5_0_stop(adev);
 | 
							uvd_v5_0_stop(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,7 +248,6 @@ static int uvd_v5_0_suspend(void *handle)
 | 
				
			||||||
	r = uvd_v5_0_hw_fini(adev);
 | 
						r = uvd_v5_0_hw_fini(adev);
 | 
				
			||||||
	if (r)
 | 
						if (r)
 | 
				
			||||||
		return r;
 | 
							return r;
 | 
				
			||||||
	uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_GATE);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return amdgpu_uvd_suspend(adev);
 | 
						return amdgpu_uvd_suspend(adev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -606,6 +606,30 @@ static int uvd_v7_0_hw_fini(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Proper cleanups before halting the HW engine:
 | 
				
			||||||
 | 
						 *   - cancel the delayed idle work
 | 
				
			||||||
 | 
						 *   - enable powergating
 | 
				
			||||||
 | 
						 *   - enable clockgating
 | 
				
			||||||
 | 
						 *   - disable dpm
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * TODO: to align with the VCN implementation, move the
 | 
				
			||||||
 | 
						 * jobs for clockgating/powergating/dpm setting to
 | 
				
			||||||
 | 
						 * ->set_powergating_state().
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cancel_delayed_work_sync(&adev->uvd.idle_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							amdgpu_dpm_enable_uvd(adev, false);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							amdgpu_asic_set_uvd_clocks(adev, 0, 0);
 | 
				
			||||||
 | 
							/* shutdown the UVD block */
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
 | 
				
			||||||
 | 
											       AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!amdgpu_sriov_vf(adev))
 | 
						if (!amdgpu_sriov_vf(adev))
 | 
				
			||||||
		uvd_v7_0_stop(adev);
 | 
							uvd_v7_0_stop(adev);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -477,6 +477,31 @@ static int vce_v2_0_hw_init(void *handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int vce_v2_0_hw_fini(void *handle)
 | 
					static int vce_v2_0_hw_fini(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Proper cleanups before halting the HW engine:
 | 
				
			||||||
 | 
						 *   - cancel the delayed idle work
 | 
				
			||||||
 | 
						 *   - enable powergating
 | 
				
			||||||
 | 
						 *   - enable clockgating
 | 
				
			||||||
 | 
						 *   - disable dpm
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * TODO: to align with the VCN implementation, move the
 | 
				
			||||||
 | 
						 * jobs for clockgating/powergating/dpm setting to
 | 
				
			||||||
 | 
						 * ->set_powergating_state().
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cancel_delayed_work_sync(&adev->vce.idle_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							amdgpu_dpm_enable_vce(adev, false);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							amdgpu_asic_set_vce_clocks(adev, 0, 0);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
 | 
				
			||||||
 | 
											       AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
 | 
				
			||||||
 | 
											       AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -542,6 +542,29 @@ static int vce_v4_0_hw_fini(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Proper cleanups before halting the HW engine:
 | 
				
			||||||
 | 
						 *   - cancel the delayed idle work
 | 
				
			||||||
 | 
						 *   - enable powergating
 | 
				
			||||||
 | 
						 *   - enable clockgating
 | 
				
			||||||
 | 
						 *   - disable dpm
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * TODO: to align with the VCN implementation, move the
 | 
				
			||||||
 | 
						 * jobs for clockgating/powergating/dpm setting to
 | 
				
			||||||
 | 
						 * ->set_powergating_state().
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cancel_delayed_work_sync(&adev->vce.idle_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							amdgpu_dpm_enable_vce(adev, false);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							amdgpu_asic_set_vce_clocks(adev, 0, 0);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
 | 
				
			||||||
 | 
											       AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
							amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
 | 
				
			||||||
 | 
											       AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!amdgpu_sriov_vf(adev)) {
 | 
						if (!amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
		/* vce_v4_0_wait_for_idle(handle); */
 | 
							/* vce_v4_0_wait_for_idle(handle); */
 | 
				
			||||||
		vce_v4_0_stop(adev);
 | 
							vce_v4_0_stop(adev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue