drm/amd/powerplay: custom peak clock freq for navi10
authorKevin Wang <kevin1.wang@amd.com>
Fri, 19 Jul 2019 03:39:21 +0000 (11:39 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 22 Jul 2019 20:23:07 +0000 (15:23 -0500)
v2:
add function smu_default_set_performance_level as default dpm level handler.
change function name smu_set_performance_level to smu_asic_set_performance_level

v1:
1.NAVI10_PEAK_SCLK_XTX    1830 Mhz
2.NAVI10_PEAK_SCLK_XT     1755 Mhz
3.NAVI10_PEAK_SCLK_XL     1625 Mhz

Signed-off-by: Kevin Wang <kevin1.wang@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Reviewed-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Jack Gui <Jack.Gui@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
drivers/gpu/drm/amd/powerplay/navi10_ppt.h

index 768aae2..c097113 100644 (file)
@@ -1374,13 +1374,49 @@ static int smu_enable_umd_pstate(void *handle,
        return 0;
 }
 
+static int smu_default_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
+{
+       int ret = 0;
+       uint32_t sclk_mask, mclk_mask, soc_mask;
+
+       switch (level) {
+       case AMD_DPM_FORCED_LEVEL_HIGH:
+               ret = smu_force_dpm_limit_value(smu, true);
+               break;
+       case AMD_DPM_FORCED_LEVEL_LOW:
+               ret = smu_force_dpm_limit_value(smu, false);
+               break;
+       case AMD_DPM_FORCED_LEVEL_AUTO:
+       case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+               ret = smu_unforce_dpm_levels(smu);
+               break;
+       case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
+       case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
+       case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
+               ret = smu_get_profiling_clk_mask(smu, level,
+                                                &sclk_mask,
+                                                &mclk_mask,
+                                                &soc_mask);
+               if (ret)
+                       return ret;
+               smu_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask);
+               smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
+               smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
+               break;
+       case AMD_DPM_FORCED_LEVEL_MANUAL:
+       case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
+       default:
+               break;
+       }
+       return ret;
+}
+
 int smu_adjust_power_state_dynamic(struct smu_context *smu,
                                   enum amd_dpm_forced_level level,
                                   bool skip_display_settings)
 {
        int ret = 0;
        int index = 0;
-       uint32_t sclk_mask, mclk_mask, soc_mask;
        long workload;
        struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
 
@@ -1411,39 +1447,10 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,
        }
 
        if (smu_dpm_ctx->dpm_level != level) {
-               switch (level) {
-               case AMD_DPM_FORCED_LEVEL_HIGH:
-                       ret = smu_force_dpm_limit_value(smu, true);
-                       break;
-               case AMD_DPM_FORCED_LEVEL_LOW:
-                       ret = smu_force_dpm_limit_value(smu, false);
-                       break;
-
-               case AMD_DPM_FORCED_LEVEL_AUTO:
-               case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
-                       ret = smu_unforce_dpm_levels(smu);
-                       break;
-
-               case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
-               case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
-               case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
-                       ret = smu_get_profiling_clk_mask(smu, level,
-                                                        &sclk_mask,
-                                                        &mclk_mask,
-                                                        &soc_mask);
-                       if (ret)
-                               return ret;
-                       smu_force_clk_levels(smu, SMU_SCLK, 1 << sclk_mask);
-                       smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask);
-                       smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
-                       break;
-
-               case AMD_DPM_FORCED_LEVEL_MANUAL:
-               case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
-               default:
-                       break;
+               ret = smu_asic_set_performance_level(smu, level);
+               if (ret) {
+                       ret = smu_default_set_performance_level(smu, level);
                }
-
                if (!ret)
                        smu_dpm_ctx->dpm_level = level;
        }
index 1af992f..564446f 100644 (file)
@@ -621,6 +621,7 @@ struct pptable_funcs {
        int (*get_thermal_temperature_range)(struct smu_context *smu, struct smu_temperature_range *range);
        int (*get_uclk_dpm_states)(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states);
        int (*set_default_od_settings)(struct smu_context *smu, bool initialize);
+       int (*set_performance_level)(struct smu_context *smu, enum amd_dpm_forced_level level);
 };
 
 struct smu_funcs
@@ -918,6 +919,9 @@ struct smu_funcs
        ((smu)->funcs->baco_get_state? (smu)->funcs->baco_get_state((smu), (state)) : 0)
 #define smu_baco_reset(smu) \
        ((smu)->funcs->baco_reset? (smu)->funcs->baco_reset((smu)) : 0)
+#define smu_asic_set_performance_level(smu, level) \
+       ((smu)->ppt_funcs->set_performance_level? (smu)->ppt_funcs->set_performance_level((smu), (level)) : -EINVAL);
+
 
 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
                                   uint16_t *size, uint8_t *frev, uint8_t *crev,
index 8293b52..7b1753f 100644 (file)
@@ -1565,6 +1565,60 @@ static int navi10_set_ppfeature_status(struct smu_context *smu,
        return 0;
 }
 
+static int navi10_set_peak_clock_by_device(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       int ret = 0;
+       uint32_t sclk_freq = 0, uclk_freq = 0;
+       uint32_t uclk_level = 0;
+
+       switch (adev->rev_id) {
+       case 0xf0: /* XTX */
+       case 0xc0:
+               sclk_freq = NAVI10_PEAK_SCLK_XTX;
+               break;
+       case 0xf1: /* XT */
+       case 0xc1:
+               sclk_freq = NAVI10_PEAK_SCLK_XT;
+               break;
+       default: /* XL */
+               sclk_freq = NAVI10_PEAK_SCLK_XL;
+               break;
+       }
+
+       ret = smu_get_dpm_level_count(smu, SMU_UCLK, &uclk_level);
+       if (ret)
+               return ret;
+       ret = smu_get_dpm_freq_by_index(smu, SMU_UCLK, uclk_level - 1, &uclk_freq);
+       if (ret)
+               return ret;
+
+       ret = smu_set_soft_freq_range(smu, SMU_SCLK, sclk_freq, sclk_freq);
+       if (ret)
+               return ret;
+       ret = smu_set_soft_freq_range(smu, SMU_UCLK, uclk_freq, uclk_freq);
+       if (ret)
+               return ret;
+
+       return ret;
+}
+
+static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
+{
+       int ret = 0;
+
+       switch (level) {
+       case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
+               ret = navi10_set_peak_clock_by_device(smu);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
 static const struct pptable_funcs navi10_ppt_funcs = {
        .tables_init = navi10_tables_init,
        .alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1600,6 +1654,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
        .get_uclk_dpm_states = navi10_get_uclk_dpm_states,
        .get_ppfeature_status = navi10_get_ppfeature_status,
        .set_ppfeature_status = navi10_set_ppfeature_status,
+       .set_performance_level = navi10_set_performance_level,
 };
 
 void navi10_set_ppt_funcs(struct smu_context *smu)
index 957288e..620ff17 100644 (file)
 #ifndef __NAVI10_PPT_H__
 #define __NAVI10_PPT_H__
 
+#define NAVI10_PEAK_SCLK_XTX           (1830)
+#define NAVI10_PEAK_SCLK_XT            (1755)
+#define NAVI10_PEAK_SCLK_XL            (1625)
+
 extern void navi10_set_ppt_funcs(struct smu_context *smu);
 
 #endif