|
|
@@ -1437,6 +1437,30 @@ static int amdgpu_fini(struct amdgpu_device *adev)
|
|
|
{
|
|
|
int i, r;
|
|
|
|
|
|
+ /* need to disable SMC first */
|
|
|
+ for (i = 0; i < adev->num_ip_blocks; i++) {
|
|
|
+ if (!adev->ip_block_status[i].hw)
|
|
|
+ continue;
|
|
|
+ if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) {
|
|
|
+ /* ungate blocks before hw fini so that we can shutdown the blocks safely */
|
|
|
+ r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
|
|
|
+ AMD_CG_STATE_UNGATE);
|
|
|
+ if (r) {
|
|
|
+ DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
|
|
|
+ adev->ip_blocks[i].funcs->name, r);
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+ r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
|
|
|
+ /* XXX handle errors */
|
|
|
+ if (r) {
|
|
|
+ DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
|
|
|
+ adev->ip_blocks[i].funcs->name, r);
|
|
|
+ }
|
|
|
+ adev->ip_block_status[i].hw = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
|
|
if (!adev->ip_block_status[i].hw)
|
|
|
continue;
|