Suspend is used for S3/S4, GPU reset, and PCI shutdown.  In
each case, we need to put the SMC into the proper state
in order to resume or reload correctly.

Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 4425ff06ecc4..bb4260648a97 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2174,6 +2174,39 @@ static int amdgpu_device_ip_suspend_phase2(struct 
amdgpu_device *adev)
                        DRM_ERROR("suspend of IP block <%s> failed %d\n",
                                  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) {
+                       enum pp_mp1_state mp1_state = PP_MP1_STATE_NONE;
+
+                       if (adev->in_gpu_reset) {
+                               switch (amdgpu_asic_reset_method(adev)) {
+                               case AMD_RESET_METHOD_MODE1:
+                               case AMD_RESET_METHOD_BACO:
+                                       mp1_state = PP_MP1_STATE_SHUTDOWN;
+                                       break;
+                               case AMD_RESET_METHOD_MODE2:
+                                       mp1_state = PP_MP1_STATE_RESET;
+                                       break;
+                               default:
+                                       mp1_state = PP_MP1_STATE_NONE;
+                                       break;
+                               }
+                       } else if (adev->in_gpu_shutdown) {
+                               mp1_state = PP_MP1_STATE_UNLOAD;
+                       }
+                       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,
+                                       mp1_state);
+                               if (r) {
+                                       DRM_ERROR("SMC failed to set mp1 state 
%d, %d\n",
+                                                 mp1_state, r);
+                               }
+                       }
+               }
        }
 
        return 0;
-- 
2.20.1

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to