drm/amdgpu: optimize RLC powerdown notification on Vangogh
authorPerry Yuan <perry.yuan@amd.com>
Tue, 1 Aug 2023 14:37:41 +0000 (10:37 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 29 Nov 2023 21:48:58 +0000 (16:48 -0500)
The smu needs to get the rlc power down message to sync the rlc state
with smu, the rlc state updating message need to be sent at while smu
begin suspend sequence , otherwise SMU will crash while RLC state is not
notified by driver, and rlc state probally changed after that
notification, so it needs to notify rlc state to smu at the end of the
suspend sequence in amdgpu_device_suspend() that can make sure the rlc
state  is correctly set to SMU.

[  101.000590] amdgpu 0000:03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0000001E SMN_C2PMSG_82:0x00000000
[  101.000598] amdgpu 0000:03:00.0: amdgpu: Failed to disable gfxoff!
[  110.838026] amdgpu 0000:03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0000001E SMN_C2PMSG_82:0x00000000
[  110.838035] amdgpu 0000:03:00.0: amdgpu: Failed to disable smu features.
[  110.838039] amdgpu 0000:03:00.0: amdgpu: Fail to disable dpm features!
[  110.838040] [drm:amdgpu_device_ip_suspend_phase2 [amdgpu]] *ERROR* suspend of IP block <smu> failed -62
[  110.884394] PM: suspend of devices aborted after 21213.620 msecs
[  110.884402] PM: start suspend of devices aborted after 21213.882 msecs
[  110.884405] PM: Some devices failed to suspend, or early wake event detected

Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/include/kgd_pp_interface.h
drivers/gpu/drm/amd/pm/amdgpu_dpm.c
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu_internal.h

index b5edf40b5d03f8ab44079281bf738240ccfb1357..5d3a83193115f242fd7f05673277ca9b97314121 100644 (file)
@@ -4549,6 +4549,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
        if (amdgpu_sriov_vf(adev))
                amdgpu_virt_release_full_gpu(adev, false);
 
+       r = amdgpu_dpm_notify_rlc_state(adev, false);
+       if (r)
+               return r;
+
        return 0;
 }
 
index 6a1d31e8fdd1f7451ae641cf1c2b5c7ac3806d0a..8ebba87f42891d7a30a5b93a8897040fa7890ca9 100644 (file)
@@ -445,6 +445,7 @@ struct amd_pm_funcs {
                                   struct dpm_clocks *clock_table);
        int (*get_smu_prv_buf_details)(void *handle, void **addr, size_t *size);
        void (*pm_compute_clocks)(void *handle);
+       int (*notify_rlc_state)(void *handle, bool en);
 };
 
 struct metrics_table_header {
index 4717884a2bc4c6bbe6b7748ff437a43cd9f3eeaf..97b40c5fa1ff62e0e18be89b5bf8e32cb6983ad9 100644 (file)
@@ -181,6 +181,24 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
        return ret;
 }
 
+int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en)
+{
+       int ret = 0;
+       const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+       if (pp_funcs && pp_funcs->notify_rlc_state) {
+               mutex_lock(&adev->pm.mutex);
+
+               ret = pp_funcs->notify_rlc_state(
+                               adev->powerplay.pp_handle,
+                               en);
+
+               mutex_unlock(&adev->pm.mutex);
+       }
+
+       return ret;
+}
+
 bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
 {
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
index 9b3fef5474b118171b33649267cad5b2f021e932..d76b0a60db4432aa8d1700ba4940e7fcfd74fc72 100644 (file)
@@ -415,6 +415,8 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev);
 int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
                             enum pp_mp1_state mp1_state);
 
+int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en);
+
 int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev);
 
 int amdgpu_dpm_baco_exit(struct amdgpu_device *adev);
index 930e7e3532ad36cd6d83c7fe654f32a5924b0623..f464610a959f68f5ddc1f0630eaf7e1d1b5bd5bd 100644 (file)
@@ -1710,6 +1710,16 @@ static int smu_disable_dpms(struct smu_context *smu)
                }
        }
 
+       /* Notify SMU RLC is going to be off, stop RLC and SMU interaction.
+        * otherwise SMU will hang while interacting with RLC if RLC is halted
+        * this is a WA for Vangogh asic which fix the SMU hang issue.
+        */
+       ret = smu_notify_rlc_state(smu, false);
+       if (ret) {
+               dev_err(adev->dev, "Fail to notify rlc status!\n");
+               return ret;
+       }
+
        if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2) &&
            !((adev->flags & AMD_IS_APU) && adev->gfx.imu.funcs) &&
            !amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->stop)
index 32600ba74bf121d2898817ed0007d5b25f777b86..c125253df20b817390414179284d70ff414608cc 100644 (file)
@@ -1370,6 +1370,11 @@ struct pptable_funcs {
         *                       management.
         */
        int (*dpm_set_umsch_mm_enable)(struct smu_context *smu, bool enable);
+
+       /**
+        * @notify_rlc_state: Notify RLC power state to SMU.
+        */
+       int (*notify_rlc_state)(struct smu_context *smu, bool en);
 };
 
 typedef enum {
index 762b31455a0b6c794ec85579ce7dfc28cdde4055..2ff6deedef955ec3a77cc4f2edf0884ed518c535 100644 (file)
@@ -2193,8 +2193,7 @@ static int vangogh_get_dpm_clock_table(struct smu_context *smu, struct dpm_clock
        return 0;
 }
 
-
-static int vangogh_system_features_control(struct smu_context *smu, bool en)
+static int vangogh_notify_rlc_state(struct smu_context *smu, bool en)
 {
        struct amdgpu_device *adev = smu->adev;
        int ret = 0;
@@ -2523,7 +2522,7 @@ static const struct pptable_funcs vangogh_ppt_funcs = {
        .print_clk_levels = vangogh_common_print_clk_levels,
        .set_default_dpm_table = vangogh_set_default_dpm_tables,
        .set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters,
-       .system_features_control = vangogh_system_features_control,
+       .notify_rlc_state = vangogh_notify_rlc_state,
        .feature_is_enabled = smu_cmn_feature_is_enabled,
        .set_power_profile_mode = vangogh_set_power_profile_mode,
        .get_power_profile_mode = vangogh_get_power_profile_mode,
index 80b3c3efc006deb320d54babfdb4536799bc1b8e..64766ac69c53bf7fa91f0b6e62f204b68a435059 100644 (file)
@@ -97,6 +97,7 @@
 #define smu_get_default_config_table_settings(smu, config_table)       smu_ppt_funcs(get_default_config_table_settings, -EOPNOTSUPP, smu, config_table)
 #define smu_set_config_table(smu, config_table)                                smu_ppt_funcs(set_config_table, -EOPNOTSUPP, smu, config_table)
 #define smu_init_pptable_microcode(smu)                                        smu_ppt_funcs(init_pptable_microcode, 0, smu)
+#define smu_notify_rlc_state(smu, en)                                  smu_ppt_funcs(notify_rlc_state, 0, smu, en)
 
 #endif
 #endif