drm/amd/pm: Add link reset for SMU 13.0.6
authorCe Sun <cesun102@amd.com>
Fri, 22 Nov 2024 07:19:16 +0000 (15:19 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 7 Apr 2025 19:18:31 +0000 (15:18 -0400)
Add link reset implementation

Signed-off-by: Ce Sun <cesun102@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
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/smu13/smu_v13_0_6_ppt.c

index 81e9b443ca0adc3ec5016eddf2c3ad4fba9ad805..9f5768fa97dd0e9e12a235a7dfa80f0a61cf8b53 100644 (file)
@@ -329,6 +329,34 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
        return ret;
 }
 
+bool amdgpu_dpm_is_link_reset_supported(struct amdgpu_device *adev)
+{
+       struct smu_context *smu = adev->powerplay.pp_handle;
+       bool support_link_reset = false;
+
+       if (is_support_sw_smu(adev)) {
+               mutex_lock(&adev->pm.mutex);
+               support_link_reset = smu_link_reset_is_support(smu);
+               mutex_unlock(&adev->pm.mutex);
+       }
+
+       return support_link_reset;
+}
+
+int amdgpu_dpm_link_reset(struct amdgpu_device *adev)
+{
+       struct smu_context *smu = adev->powerplay.pp_handle;
+       int ret = -EOPNOTSUPP;
+
+       if (is_support_sw_smu(adev)) {
+               mutex_lock(&adev->pm.mutex);
+               ret = smu_link_reset(smu);
+               mutex_unlock(&adev->pm.mutex);
+       }
+
+       return ret;
+}
+
 int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
                                    enum PP_SMC_POWER_PROFILE type,
                                    bool en)
index f93d287dbf1376bf1257ea57bcdf7a25d4f26b29..747019ed2bf5c58f803cbbbf6ca9994190796b6e 100644 (file)
@@ -414,11 +414,13 @@ int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
 int amdgpu_dpm_baco_reset(struct amdgpu_device *adev);
 
 int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev);
+int amdgpu_dpm_link_reset(struct amdgpu_device *adev);
 int amdgpu_dpm_enable_gfx_features(struct amdgpu_device *adev);
 
 int amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev);
 
 bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev);
+bool amdgpu_dpm_is_link_reset_supported(struct amdgpu_device *adev);
 int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev);
 
 int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
index 033c3229b555f04e94bc1a1e4d2e170c8b88256b..a01b6244d99cd5a1180595e2a4d876db16f10dc7 100644 (file)
@@ -3412,6 +3412,19 @@ bool smu_mode2_reset_is_support(struct smu_context *smu)
        return ret;
 }
 
+bool smu_link_reset_is_support(struct smu_context *smu)
+{
+       bool ret = false;
+
+       if (!smu->pm_enabled)
+               return false;
+
+       if (smu->ppt_funcs && smu->ppt_funcs->link_reset_is_support)
+               ret = smu->ppt_funcs->link_reset_is_support(smu);
+
+       return ret;
+}
+
 int smu_mode1_reset(struct smu_context *smu)
 {
        int ret = 0;
@@ -3442,6 +3455,19 @@ static int smu_mode2_reset(void *handle)
        return ret;
 }
 
+int smu_link_reset(struct smu_context *smu)
+{
+       int ret = 0;
+
+       if (!smu->pm_enabled)
+               return -EOPNOTSUPP;
+
+       if (smu->ppt_funcs->link_reset)
+               ret = smu->ppt_funcs->link_reset(smu);
+
+       return ret;
+}
+
 static int smu_enable_gfx_features(void *handle)
 {
        struct smu_context *smu = handle;
index 3ba169639f546061d0a5f13e3f91c531bc9ea3af..27cecf9688ccbb3605abd3321450c73ae95b4a91 100644 (file)
@@ -438,9 +438,11 @@ struct mclock_latency_table {
 };
 
 enum smu_reset_mode {
-    SMU_RESET_MODE_0,
-    SMU_RESET_MODE_1,
-    SMU_RESET_MODE_2,
+       SMU_RESET_MODE_0,
+       SMU_RESET_MODE_1,
+       SMU_RESET_MODE_2,
+       SMU_RESET_MODE_3,
+       SMU_RESET_MODE_4,
 };
 
 enum smu_baco_state {
@@ -1228,11 +1230,17 @@ struct pptable_funcs {
         * @mode1_reset_is_support: Check if GPU supports mode1 reset.
         */
        bool (*mode1_reset_is_support)(struct smu_context *smu);
+
        /**
         * @mode2_reset_is_support: Check if GPU supports mode2 reset.
         */
        bool (*mode2_reset_is_support)(struct smu_context *smu);
 
+       /**
+        * @link_reset_is_support: Check if GPU supports link reset.
+        */
+       bool (*link_reset_is_support)(struct smu_context *smu);
+
        /**
         * @mode1_reset: Perform mode1 reset.
         *
@@ -1250,6 +1258,13 @@ struct pptable_funcs {
        /* for gfx feature enablement after mode2 reset */
        int (*enable_gfx_features)(struct smu_context *smu);
 
+       /**
+        * @link_reset: Perform link reset.
+        *
+        * The gfx device driver reset
+        */
+       int (*link_reset)(struct smu_context *smu);
+
        /**
         * @get_dpm_ultimate_freq: Get the hard frequency range of a clock
         *                         domain in MHz.
@@ -1601,7 +1616,9 @@ int smu_get_power_limit(void *handle,
 
 bool smu_mode1_reset_is_support(struct smu_context *smu);
 bool smu_mode2_reset_is_support(struct smu_context *smu);
+bool smu_link_reset_is_support(struct smu_context *smu);
 int smu_mode1_reset(struct smu_context *smu);
+int smu_link_reset(struct smu_context *smu);
 
 extern const struct amd_ip_funcs smu_ip_funcs;
 
index c478b3be37af1ec2ec30577632ee3bc2a22f3cf4..9264dc33ee7e940c92a7a5a3dd29a4f329cc09ed 100644 (file)
@@ -2844,6 +2844,15 @@ static int smu_v13_0_6_mode1_reset(struct smu_context *smu)
        return ret;
 }
 
+static int smu_v13_0_6_link_reset(struct smu_context *smu)
+{
+       int ret = 0;
+
+       ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
+                                             SMU_RESET_MODE_4, NULL);
+       return ret;
+}
+
 static bool smu_v13_0_6_is_mode1_reset_supported(struct smu_context *smu)
 {
        return true;
@@ -2854,6 +2863,17 @@ static bool smu_v13_0_6_is_mode2_reset_supported(struct smu_context *smu)
        return true;
 }
 
+static inline bool smu_v13_0_6_is_link_reset_supported(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       int var = (adev->pdev->device & 0xF);
+
+       if (var == 0x1)
+               return true;
+
+       return false;
+}
+
 static int smu_v13_0_6_smu_send_hbm_bad_page_num(struct smu_context *smu,
                                                 uint32_t size)
 {
@@ -3587,8 +3607,10 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = {
        .get_thermal_temperature_range = smu_v13_0_6_get_thermal_temperature_range,
        .mode1_reset_is_support = smu_v13_0_6_is_mode1_reset_supported,
        .mode2_reset_is_support = smu_v13_0_6_is_mode2_reset_supported,
+       .link_reset_is_support = smu_v13_0_6_is_link_reset_supported,
        .mode1_reset = smu_v13_0_6_mode1_reset,
        .mode2_reset = smu_v13_0_6_mode2_reset,
+       .link_reset = smu_v13_0_6_link_reset,
        .wait_for_event = smu_v13_0_wait_for_event,
        .i2c_init = smu_v13_0_6_i2c_control_init,
        .i2c_fini = smu_v13_0_6_i2c_control_fini,