Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: add missing cleanups for Polaris12 UVD/VCE on suspend

Perform proper cleanups on UVD/VCE suspend: powergate enablement,
clockgating enablement and dpm disablement. This can fix some hangs
observed on suspending when UVD/VCE still using(e.g. issue
"pm-suspend" when video is still playing).

Signed-off-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: xinhui pan <xinhui.pan@amd.com>
Reviewed-by: Guchun Chen <guchun.chen@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Evan Quan and committed by
Alex Deucher
bf756fb8 2f617f4d

+47
+24
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
··· 543 543 { 544 544 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 545 545 546 + /* 547 + * Proper cleanups before halting the HW engine: 548 + * - cancel the delayed idle work 549 + * - enable powergating 550 + * - enable clockgating 551 + * - disable dpm 552 + * 553 + * TODO: to align with the VCN implementation, move the 554 + * jobs for clockgating/powergating/dpm setting to 555 + * ->set_powergating_state(). 556 + */ 557 + cancel_delayed_work_sync(&adev->uvd.idle_work); 558 + 559 + if (adev->pm.dpm_enabled) { 560 + amdgpu_dpm_enable_uvd(adev, false); 561 + } else { 562 + amdgpu_asic_set_uvd_clocks(adev, 0, 0); 563 + /* shutdown the UVD block */ 564 + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, 565 + AMD_PG_STATE_GATE); 566 + amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD, 567 + AMD_CG_STATE_GATE); 568 + } 569 + 546 570 if (RREG32(mmUVD_STATUS) != 0) 547 571 uvd_v6_0_stop(adev); 548 572
+23
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
··· 490 490 int r; 491 491 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 492 492 493 + /* 494 + * Proper cleanups before halting the HW engine: 495 + * - cancel the delayed idle work 496 + * - enable powergating 497 + * - enable clockgating 498 + * - disable dpm 499 + * 500 + * TODO: to align with the VCN implementation, move the 501 + * jobs for clockgating/powergating/dpm setting to 502 + * ->set_powergating_state(). 503 + */ 504 + cancel_delayed_work_sync(&adev->vce.idle_work); 505 + 506 + if (adev->pm.dpm_enabled) { 507 + amdgpu_dpm_enable_vce(adev, false); 508 + } else { 509 + amdgpu_asic_set_vce_clocks(adev, 0, 0); 510 + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, 511 + AMD_PG_STATE_GATE); 512 + amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, 513 + AMD_CG_STATE_GATE); 514 + } 515 + 493 516 r = vce_v3_0_wait_for_idle(handle); 494 517 if (r) 495 518 return r;