Commit a3a09142 authored by Alex Deucher's avatar Alex Deucher

drm/amdgpu: put the SMC into the proper state on reset/unload

When doing a GPU reset or unloading the driver, we need to
put the SMU into the apprpriate state for the re-init after
the reset or unload to reliably work.

I don't think this is necessary for BACO because the SMU actually
controls the BACO state to it needs to be active.

For suspend (S3), the asic is put into D3 so the SMU would be
powered down so I don't think we need to put the SMU into
any special state.
Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1c074a63
...@@ -990,6 +990,7 @@ struct amdgpu_device { ...@@ -990,6 +990,7 @@ struct amdgpu_device {
/* record last mm index being written through WREG32*/ /* record last mm index being written through WREG32*/
unsigned long last_mm_index; unsigned long last_mm_index;
bool in_gpu_reset; bool in_gpu_reset;
enum pp_mp1_state mp1_state;
struct mutex lock_reset; struct mutex lock_reset;
struct amdgpu_doorbell_index doorbell_index; struct amdgpu_doorbell_index doorbell_index;
......
...@@ -2175,6 +2175,21 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) ...@@ -2175,6 +2175,21 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
DRM_ERROR("suspend of IP block <%s> failed %d\n", DRM_ERROR("suspend of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r); adev->ip_blocks[i].version->funcs->name, r);
} }
/* handle putting the SMC in the appropriate state */
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
if (is_support_sw_smu(adev)) {
/* todo */
} else if (adev->powerplay.pp_funcs &&
adev->powerplay.pp_funcs->set_mp1_state) {
r = adev->powerplay.pp_funcs->set_mp1_state(
adev->powerplay.pp_handle,
adev->mp1_state);
if (r) {
DRM_ERROR("SMC failed to set mp1 state %d, %d\n",
adev->mp1_state, r);
}
}
}
} }
return 0; return 0;
...@@ -3640,6 +3655,17 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev, bool trylock) ...@@ -3640,6 +3655,17 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev, bool trylock)
atomic_inc(&adev->gpu_reset_counter); atomic_inc(&adev->gpu_reset_counter);
adev->in_gpu_reset = 1; adev->in_gpu_reset = 1;
switch (amdgpu_asic_reset_method(adev)) {
case AMD_RESET_METHOD_MODE1:
adev->mp1_state = PP_MP1_STATE_SHUTDOWN;
break;
case AMD_RESET_METHOD_MODE2:
adev->mp1_state = PP_MP1_STATE_RESET;
break;
default:
adev->mp1_state = PP_MP1_STATE_NONE;
break;
}
/* Block kfd: SRIOV would do it separately */ /* Block kfd: SRIOV would do it separately */
if (!amdgpu_sriov_vf(adev)) if (!amdgpu_sriov_vf(adev))
amdgpu_amdkfd_pre_reset(adev); amdgpu_amdkfd_pre_reset(adev);
...@@ -3653,6 +3679,7 @@ static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) ...@@ -3653,6 +3679,7 @@ static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
if (!amdgpu_sriov_vf(adev)) if (!amdgpu_sriov_vf(adev))
amdgpu_amdkfd_post_reset(adev); amdgpu_amdkfd_post_reset(adev);
amdgpu_vf_error_trans_all(adev); amdgpu_vf_error_trans_all(adev);
adev->mp1_state = PP_MP1_STATE_NONE;
adev->in_gpu_reset = 0; adev->in_gpu_reset = 0;
mutex_unlock(&adev->lock_reset); mutex_unlock(&adev->lock_reset);
} }
......
...@@ -1096,7 +1096,9 @@ amdgpu_pci_shutdown(struct pci_dev *pdev) ...@@ -1096,7 +1096,9 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
* unfortunately we can't detect certain * unfortunately we can't detect certain
* hypervisors so just do this all the time. * hypervisors so just do this all the time.
*/ */
adev->mp1_state = PP_MP1_STATE_UNLOAD;
amdgpu_device_ip_suspend(adev); amdgpu_device_ip_suspend(adev);
adev->mp1_state = PP_MP1_STATE_NONE;
} }
static int amdgpu_pmops_suspend(struct device *dev) static int amdgpu_pmops_suspend(struct device *dev)
......
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