]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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 22:55:47 +0000 (17:55 -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 7eeaf0aa7f8121fc59dcd30e48a00dc9750d5e5f..5c0817cbc7c2b1b10ab4e22b19f89d8ef120c5f0 100644 (file)
@@ -4538,6 +4538,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 cd3c40a860293c2430efbf26c9832fc82533de34..0d1209f2cf313bb2b4244cab48ba808aa9dba027 100644 (file)
@@ -444,6 +444,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 08cb79401410ad0768a7bf9d95bea93c2ba2916b..8ec11da0319ffdc86bf075bee860434fcb7d1c62 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 feccd2a7120dcdf82e8f0492050f1f9b87f172e6..482ea30147ab644da66c13e2642c9be3d74b4065 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 1ead323f1c78138b0176ec55032fd990239e94fa..e1a5ee911dbbc6cdefa33045e29f98ad4b8fce87 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 8def291b18bcdaa3db86ec4ef2545f154f70c098..23fa71cafb145fba9fba66274e2ddcb080e5be7d 100644 (file)
@@ -1360,6 +1360,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