drm/amdgpu/swsmu: add automatic parameter to set_soft_freq_range
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 1 Oct 2024 14:31:26 +0000 (10:31 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 15 Oct 2024 15:27:08 +0000 (11:27 -0400)
On chips that support it, you can specificy 0 and 0xffff for
min and max and the PMFW will use that to determine the optimal
min and max.  This enables optimal performance when the
user manually switches between performance levels using sysfs.
Previously we'd set soft min/max which could limit performance.

Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
21 files changed:
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/inc/smu_v11_0.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v12_0.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c

index 0bd88212ff2520a8e04b3c8684c76957ced83cbb..82b88326117fa17e709a73ee6ec7e5c14ae1ba0d 100644 (file)
@@ -140,7 +140,8 @@ int smu_set_soft_freq_range(struct smu_context *smu,
                ret = smu->ppt_funcs->set_soft_freq_limited_range(smu,
                                                                  clk_type,
                                                                  min,
-                                                                 max);
+                                                                 max,
+                                                                 false);
 
        return ret;
 }
index 727da0c37e065decb50e44c067d9318d1d443409..8bb32b3f0d9c65f2cff8e6b8293427e1f068052c 100644 (file)
@@ -1255,7 +1255,8 @@ struct pptable_funcs {
         * @set_soft_freq_limited_range: Set the soft frequency range of a clock
         *                               domain in MHz.
         */
-       int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);
+       int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max,
+                                          bool automatic);
 
        /**
         * @set_power_source: Notify the SMU of the current power source.
index c2ab336bb53080376629468ca0ab4a3fef000491..ed8304d828314a3efa71e582ab592b6c88fd5ec6 100644 (file)
@@ -255,7 +255,7 @@ int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
                                                 uint32_t *min, uint32_t *max);
 
 int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
-                           uint32_t min, uint32_t max);
+                                         uint32_t min, uint32_t max, bool automatic);
 
 int smu_v11_0_set_hard_freq_limited_range(struct smu_context *smu,
                                          enum smu_clk_type clk_type,
index 1ad2dff71090b06422167ef4c37f1f25b534113e..0886d8cffbd0a649e3ac221f2e4af05c3917a7ef 100644 (file)
@@ -56,7 +56,7 @@ int smu_v12_0_set_default_dpm_tables(struct smu_context *smu);
 int smu_v12_0_mode2_reset(struct smu_context *smu);
 
 int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
-                           uint32_t min, uint32_t max);
+                                         uint32_t min, uint32_t max, bool automatic);
 
 int smu_v12_0_set_driver_table_location(struct smu_context *smu);
 
index e58220a7ee2f708608d781035c2d4050ea1bc50f..044d6893b43e2eaf6d3b5b98b895bf1d0ef85594 100644 (file)
@@ -219,7 +219,7 @@ int smu_v13_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
                                    uint32_t *min, uint32_t *max);
 
 int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
-                                         uint32_t min, uint32_t max);
+                                         uint32_t min, uint32_t max, bool automatic);
 
 int smu_v13_0_set_hard_freq_limited_range(struct smu_context *smu,
                                          enum smu_clk_type clk_type,
index 46b456590a08049b051cbfbae1d725b3e93f6925..6cada19a84822464c3bf0db27d4cd0a897653fef 100644 (file)
@@ -186,7 +186,7 @@ int smu_v14_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
                                    uint32_t *min, uint32_t *max);
 
 int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
-                                         uint32_t min, uint32_t max);
+                                         uint32_t min, uint32_t max, bool automatic);
 
 int smu_v14_0_set_hard_freq_limited_range(struct smu_context *smu,
                                          enum smu_clk_type clk_type,
index 16af1a329621f19007a875ac773ce8efafa27eac..9fa305ba642267b8b6229979102b0990689e13f5 100644 (file)
@@ -1689,7 +1689,7 @@ static int navi10_force_clk_levels(struct smu_context *smu,
                if (ret)
                        return 0;
 
-               ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+               ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
                if (ret)
                        return 0;
                break;
index 3b29cb74c47bce3bee1e48a5f15f87642f800082..77e58eb463280c9d0acead03349013b33423f53e 100644 (file)
@@ -1469,7 +1469,7 @@ static int sienna_cichlid_force_clk_levels(struct smu_context *smu,
                if (ret)
                        goto forec_level_out;
 
-               ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+               ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
                if (ret)
                        goto forec_level_out;
                break;
index 8981302b19c8e1b1d539ab05874f6e81f29ebb64..480cf3cb204d2dc03e62c19bf268ad0e11af69a5 100644 (file)
@@ -1764,7 +1764,8 @@ failed:
 int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu,
                                          enum smu_clk_type clk_type,
                                          uint32_t min,
-                                         uint32_t max)
+                                         uint32_t max,
+                                         bool automatic)
 {
        int ret = 0, clk_id = 0;
        uint32_t param;
@@ -1779,7 +1780,10 @@ int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu,
                return clk_id;
 
        if (max > 0) {
-               param = (uint32_t)((clk_id << 16) | (max & 0xffff));
+               if (automatic)
+                       param = (uint32_t)((clk_id << 16) | 0xffff);
+               else
+                       param = (uint32_t)((clk_id << 16) | (max & 0xffff));
                ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
                                                  param, NULL);
                if (ret)
@@ -1787,7 +1791,10 @@ int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu,
        }
 
        if (min > 0) {
-               param = (uint32_t)((clk_id << 16) | (min & 0xffff));
+               if (automatic)
+                       param = (uint32_t)((clk_id << 16) | 0);
+               else
+                       param = (uint32_t)((clk_id << 16) | (min & 0xffff));
                ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
                                                  param, NULL);
                if (ret)
@@ -1855,6 +1862,7 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
        uint32_t mclk_min = 0, mclk_max = 0;
        uint32_t socclk_min = 0, socclk_max = 0;
        int ret = 0;
+       bool auto_level = false;
 
        switch (level) {
        case AMD_DPM_FORCED_LEVEL_HIGH:
@@ -1874,6 +1882,7 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
                mclk_max = mem_table->max;
                socclk_min = soc_table->min;
                socclk_max = soc_table->max;
+               auto_level = true;
                break;
        case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
                sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
@@ -1906,13 +1915,15 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
        if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) {
                mclk_min = mclk_max = 0;
                socclk_min = socclk_max = 0;
+               auto_level = false;
        }
 
        if (sclk_min && sclk_max) {
                ret = smu_v11_0_set_soft_freq_limited_range(smu,
                                                            SMU_GFXCLK,
                                                            sclk_min,
-                                                           sclk_max);
+                                                           sclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
        }
@@ -1921,7 +1932,8 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
                ret = smu_v11_0_set_soft_freq_limited_range(smu,
                                                            SMU_MCLK,
                                                            mclk_min,
-                                                           mclk_max);
+                                                           mclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
        }
@@ -1930,7 +1942,8 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
                ret = smu_v11_0_set_soft_freq_limited_range(smu,
                                                            SMU_SOCCLK,
                                                            socclk_min,
-                                                           socclk_max);
+                                                           socclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
        }
index 22737b11b1bfb1e761d9cf259b19185344945e56..a333ab827f48aaa01c0e29977b2d20af01ba865f 100644 (file)
@@ -1091,9 +1091,10 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,
 }
 
 static int vangogh_set_soft_freq_limited_range(struct smu_context *smu,
-                                         enum smu_clk_type clk_type,
-                                         uint32_t min,
-                                         uint32_t max)
+                                              enum smu_clk_type clk_type,
+                                              uint32_t min,
+                                              uint32_t max,
+                                              bool automatic)
 {
        int ret = 0;
 
@@ -1299,7 +1300,7 @@ static int vangogh_force_dpm_limit_value(struct smu_context *smu, bool highest)
                        return ret;
 
                force_freq = highest ? max_freq : min_freq;
-               ret = vangogh_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
+               ret = vangogh_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq, false);
                if (ret)
                        return ret;
        }
@@ -1335,7 +1336,7 @@ static int vangogh_unforce_dpm_levels(struct smu_context *smu)
                if (ret)
                        return ret;
 
-               ret = vangogh_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+               ret = vangogh_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
 
                if (ret)
                        return ret;
@@ -1354,7 +1355,7 @@ static int vangogh_set_peak_clock_by_device(struct smu_context *smu)
        if (ret)
                return ret;
 
-       ret = vangogh_set_soft_freq_limited_range(smu, SMU_FCLK, fclk_freq, fclk_freq);
+       ret = vangogh_set_soft_freq_limited_range(smu, SMU_FCLK, fclk_freq, fclk_freq, false);
        if (ret)
                return ret;
 
@@ -1362,7 +1363,7 @@ static int vangogh_set_peak_clock_by_device(struct smu_context *smu)
        if (ret)
                return ret;
 
-       ret = vangogh_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk_freq, socclk_freq);
+       ret = vangogh_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk_freq, socclk_freq, false);
        if (ret)
                return ret;
 
@@ -1370,7 +1371,7 @@ static int vangogh_set_peak_clock_by_device(struct smu_context *smu)
        if (ret)
                return ret;
 
-       ret = vangogh_set_soft_freq_limited_range(smu, SMU_VCLK, vclk_freq, vclk_freq);
+       ret = vangogh_set_soft_freq_limited_range(smu, SMU_VCLK, vclk_freq, vclk_freq, false);
        if (ret)
                return ret;
 
@@ -1378,7 +1379,7 @@ static int vangogh_set_peak_clock_by_device(struct smu_context *smu)
        if (ret)
                return ret;
 
-       ret = vangogh_set_soft_freq_limited_range(smu, SMU_DCLK, dclk_freq, dclk_freq);
+       ret = vangogh_set_soft_freq_limited_range(smu, SMU_DCLK, dclk_freq, dclk_freq, false);
        if (ret)
                return ret;
 
index cc0504b063fa3a2c7454ad5424e4991c569e6507..0b210b1f26285e6a1e92e0a0774f98e6203a8a3f 100644 (file)
@@ -707,7 +707,7 @@ static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest)
                        return ret;
 
                force_freq = highest ? max_freq : min_freq;
-               ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
+               ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq, false);
                if (ret)
                        return ret;
        }
@@ -740,7 +740,7 @@ static int renoir_unforce_dpm_levels(struct smu_context *smu) {
                if (ret)
                        return ret;
 
-               ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+               ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
                if (ret)
                        return ret;
        }
@@ -911,7 +911,7 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
        if (ret)
                return ret;
 
-       ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq);
+       ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq, false);
        if (ret)
                return ret;
 
@@ -919,7 +919,7 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
        if (ret)
                return ret;
 
-       ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq);
+       ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq, false);
        if (ret)
                return ret;
 
@@ -961,13 +961,13 @@ static int renior_set_dpm_profile_freq(struct smu_context *smu,
        }
 
        if (sclk)
-               ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk, sclk);
+               ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk, sclk, false);
 
        if (socclk)
-               ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk, socclk);
+               ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk, socclk, false);
 
        if (fclk)
-               ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_FCLK, fclk, fclk);
+               ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_FCLK, fclk, fclk, false);
 
        return ret;
 }
index ed15f5a0fd119f7f821d8411fde458ddf6771c8f..3d3cd546f0adc425fbbba31e43b4d7662ccab872 100644 (file)
@@ -211,7 +211,7 @@ int smu_v12_0_mode2_reset(struct smu_context *smu)
 }
 
 int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
-                           uint32_t min, uint32_t max)
+                                         uint32_t min, uint32_t max, bool automatic)
 {
        int ret = 0;
 
index 2c35eb31475ab80eac6fc1e99f85ce26eda32c81..f6b0293543275b1bc8ac07daeeefce265e90c94b 100644 (file)
@@ -1297,9 +1297,10 @@ static int aldebaran_set_performance_level(struct smu_context *smu,
 }
 
 static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
-                                         enum smu_clk_type clk_type,
-                                         uint32_t min,
-                                         uint32_t max)
+                                                enum smu_clk_type clk_type,
+                                                uint32_t min,
+                                                uint32_t max,
+                                                bool automatic)
 {
        struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
        struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
@@ -1328,7 +1329,7 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
                        return 0;
 
                ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK,
-                                                           min, max);
+                                                           min, max, false);
                if (!ret) {
                        pstate_table->gfxclk_pstate.curr.min = min;
                        pstate_table->gfxclk_pstate.curr.max = max;
@@ -1348,7 +1349,7 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
                /* Restore default min/max clocks and enable determinism */
                min_clk = dpm_context->dpm_tables.gfx_table.min;
                max_clk = dpm_context->dpm_tables.gfx_table.max;
-               ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
+               ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk, false);
                if (!ret) {
                        usleep_range(500, 1000);
                        ret = smu_cmn_send_smc_msg_with_param(smu,
@@ -1422,7 +1423,7 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_
                        min_clk = dpm_context->dpm_tables.gfx_table.min;
                        max_clk = dpm_context->dpm_tables.gfx_table.max;
 
-                       return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
+                       return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk, false);
                }
                break;
        case PP_OD_COMMIT_DPM_TABLE:
@@ -1441,7 +1442,7 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_
                        min_clk = pstate_table->gfxclk_pstate.custom.min;
                        max_clk = pstate_table->gfxclk_pstate.custom.max;
 
-                       return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
+                       return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk, false);
                }
                break;
        default:
index e17466cc19522dba266eba7888f2c3b1089c7cee..6cfd663639155de85f98829414db6afe1d367d85 100644 (file)
@@ -1608,7 +1608,8 @@ failed:
 int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu,
                                          enum smu_clk_type clk_type,
                                          uint32_t min,
-                                         uint32_t max)
+                                         uint32_t max,
+                                         bool automatic)
 {
        int ret = 0, clk_id = 0;
        uint32_t param;
@@ -1623,7 +1624,10 @@ int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu,
                return clk_id;
 
        if (max > 0) {
-               param = (uint32_t)((clk_id << 16) | (max & 0xffff));
+               if (automatic)
+                       param = (uint32_t)((clk_id << 16) | 0xffff);
+               else
+                       param = (uint32_t)((clk_id << 16) | (max & 0xffff));
                ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
                                                      param, NULL);
                if (ret)
@@ -1631,7 +1635,10 @@ int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu,
        }
 
        if (min > 0) {
-               param = (uint32_t)((clk_id << 16) | (min & 0xffff));
+               if (automatic)
+                       param = (uint32_t)((clk_id << 16) | 0);
+               else
+                       param = (uint32_t)((clk_id << 16) | (min & 0xffff));
                ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
                                                      param, NULL);
                if (ret)
@@ -1708,6 +1715,7 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
        uint32_t dclk_min = 0, dclk_max = 0;
        uint32_t fclk_min = 0, fclk_max = 0;
        int ret = 0, i;
+       bool auto_level = false;
 
        switch (level) {
        case AMD_DPM_FORCED_LEVEL_HIGH:
@@ -1739,6 +1747,7 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                dclk_max = dclk_table->max;
                fclk_min = fclk_table->min;
                fclk_max = fclk_table->max;
+               auto_level = true;
                break;
        case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
                sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
@@ -1780,13 +1789,15 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                vclk_min = vclk_max = 0;
                dclk_min = dclk_max = 0;
                fclk_min = fclk_max = 0;
+               auto_level = false;
        }
 
        if (sclk_min && sclk_max) {
                ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                            SMU_GFXCLK,
                                                            sclk_min,
-                                                           sclk_max);
+                                                           sclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
@@ -1798,7 +1809,8 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                            SMU_MCLK,
                                                            mclk_min,
-                                                           mclk_max);
+                                                           mclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
@@ -1810,7 +1822,8 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                            SMU_SOCCLK,
                                                            socclk_min,
-                                                           socclk_max);
+                                                           socclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
@@ -1825,7 +1838,8 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                        ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                                    i ? SMU_VCLK1 : SMU_VCLK,
                                                                    vclk_min,
-                                                                   vclk_max);
+                                                                   vclk_max,
+                                                                   auto_level);
                        if (ret)
                                return ret;
                }
@@ -1840,7 +1854,8 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                        ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                                    i ? SMU_DCLK1 : SMU_DCLK,
                                                                    dclk_min,
-                                                                   dclk_max);
+                                                                   dclk_max,
+                                                                   auto_level);
                        if (ret)
                                return ret;
                }
@@ -1852,7 +1867,8 @@ int smu_v13_0_set_performance_level(struct smu_context *smu,
                ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                            SMU_FCLK,
                                                            fclk_min,
-                                                           fclk_max);
+                                                           fclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
index 4e658abe3a20a30162caec6cfacf69ae389a8277..3e2277abc75468dcba785218784637943a958d74 100644 (file)
@@ -1962,7 +1962,8 @@ static int smu_v13_0_0_force_clk_levels(struct smu_context *smu,
                ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                            clk_type,
                                                            min_freq,
-                                                           max_freq);
+                                                           max_freq,
+                                                           false);
                break;
        case SMU_DCEFCLK:
        case SMU_PCIE:
index 9c2c43bfed0bbad20b695f3030183e32743fc7f9..a71b7c0803f1897d57a921fa7ed8fbd06192a609 100644 (file)
@@ -811,9 +811,10 @@ failed:
 }
 
 static int smu_v13_0_5_set_soft_freq_limited_range(struct smu_context *smu,
-                                                       enum smu_clk_type clk_type,
-                                                       uint32_t min,
-                                                       uint32_t max)
+                                                  enum smu_clk_type clk_type,
+                                                  uint32_t min,
+                                                  uint32_t max,
+                                                  bool automatic)
 {
        enum smu_message_type msg_set_min, msg_set_max;
        uint32_t min_clk = min;
@@ -950,7 +951,7 @@ static int smu_v13_0_5_force_clk_levels(struct smu_context *smu,
                if (ret)
                        goto force_level_out;
 
-               ret = smu_v13_0_5_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+               ret = smu_v13_0_5_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
                if (ret)
                        goto force_level_out;
                break;
@@ -1046,9 +1047,10 @@ static int smu_v13_0_5_set_performance_level(struct smu_context *smu,
 
        if (sclk_min && sclk_max) {
                ret = smu_v13_0_5_set_soft_freq_limited_range(smu,
-                                                           SMU_SCLK,
-                                                           sclk_min,
-                                                           sclk_max);
+                                                             SMU_SCLK,
+                                                             sclk_min,
+                                                             sclk_max,
+                                                             false);
                if (ret)
                        return ret;
 
@@ -1060,7 +1062,8 @@ static int smu_v13_0_5_set_performance_level(struct smu_context *smu,
                ret = smu_v13_0_5_set_soft_freq_limited_range(smu,
                                                              SMU_VCLK,
                                                              vclk_min,
-                                                             vclk_max);
+                                                             vclk_max,
+                                                             false);
                if (ret)
                        return ret;
        }
@@ -1069,7 +1072,8 @@ static int smu_v13_0_5_set_performance_level(struct smu_context *smu,
                ret = smu_v13_0_5_set_soft_freq_limited_range(smu,
                                                              SMU_DCLK,
                                                              dclk_min,
-                                                             dclk_max);
+                                                             dclk_max,
+                                                             false);
                if (ret)
                        return ret;
        }
index 91297590f006936f2c7e933d8ce03ca36cb1b9c7..7ebb675c5786a8168ab7cc5b0a1e256d0b823d9c 100644 (file)
@@ -1758,7 +1758,7 @@ static int smu_v13_0_6_set_performance_level(struct smu_context *smu,
                if (uclk_table->max != pstate_table->uclk_pstate.curr.max) {
                        /* Min UCLK is not expected to be changed */
                        ret = smu_v13_0_set_soft_freq_limited_range(
-                               smu, SMU_UCLK, 0, uclk_table->max);
+                               smu, SMU_UCLK, 0, uclk_table->max, false);
                        if (ret)
                                return ret;
                        pstate_table->uclk_pstate.curr.max = uclk_table->max;
@@ -1777,7 +1777,8 @@ static int smu_v13_0_6_set_performance_level(struct smu_context *smu,
 
 static int smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu,
                                                   enum smu_clk_type clk_type,
-                                                  uint32_t min, uint32_t max)
+                                                  uint32_t min, uint32_t max,
+                                                  bool automatic)
 {
        struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
        struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
@@ -1825,7 +1826,7 @@ static int smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu,
                                return -EOPNOTSUPP;
                        /* Only max clock limiting is allowed for UCLK */
                        ret = smu_v13_0_set_soft_freq_limited_range(
-                               smu, SMU_UCLK, 0, max);
+                               smu, SMU_UCLK, 0, max, false);
                        if (!ret)
                                pstate_table->uclk_pstate.curr.max = max;
                }
@@ -1965,7 +1966,7 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu,
                        max_clk = dpm_context->dpm_tables.gfx_table.max;
 
                        ret = smu_v13_0_6_set_soft_freq_limited_range(
-                               smu, SMU_GFXCLK, min_clk, max_clk);
+                               smu, SMU_GFXCLK, min_clk, max_clk, false);
 
                        if (ret)
                                return ret;
@@ -1973,7 +1974,7 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu,
                        min_clk = dpm_context->dpm_tables.uclk_table.min;
                        max_clk = dpm_context->dpm_tables.uclk_table.max;
                        ret = smu_v13_0_6_set_soft_freq_limited_range(
-                               smu, SMU_UCLK, min_clk, max_clk);
+                               smu, SMU_UCLK, min_clk, max_clk, false);
                        if (ret)
                                return ret;
                        pstate_table->uclk_pstate.custom.max = 0;
@@ -1997,7 +1998,7 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu,
                        max_clk = pstate_table->gfxclk_pstate.custom.max;
 
                        ret = smu_v13_0_6_set_soft_freq_limited_range(
-                               smu, SMU_GFXCLK, min_clk, max_clk);
+                               smu, SMU_GFXCLK, min_clk, max_clk, false);
 
                        if (ret)
                                return ret;
@@ -2008,7 +2009,7 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu,
                        min_clk = pstate_table->uclk_pstate.curr.min;
                        max_clk = pstate_table->uclk_pstate.custom.max;
                        return smu_v13_0_6_set_soft_freq_limited_range(
-                               smu, SMU_UCLK, min_clk, max_clk);
+                               smu, SMU_UCLK, min_clk, max_clk, false);
                }
                break;
        default:
index f7d7cae16d9baa0ed230e3a0d48073b78cb31642..23f13388455fe499559c6be45440af8e70ff7f06 100644 (file)
@@ -1951,7 +1951,8 @@ static int smu_v13_0_7_force_clk_levels(struct smu_context *smu,
                ret = smu_v13_0_set_soft_freq_limited_range(smu,
                                                            clk_type,
                                                            min_freq,
-                                                           max_freq);
+                                                           max_freq,
+                                                           false);
                break;
        case SMU_DCEFCLK:
        case SMU_PCIE:
index 260c339f89c5dce9be986a992234351535ecb754..71d58c8c8cc041e57d4c3a91f9c947d3842fd044 100644 (file)
@@ -945,9 +945,10 @@ failed:
 }
 
 static int yellow_carp_set_soft_freq_limited_range(struct smu_context *smu,
-                                                       enum smu_clk_type clk_type,
-                                                       uint32_t min,
-                                                       uint32_t max)
+                                                  enum smu_clk_type clk_type,
+                                                  uint32_t min,
+                                                  uint32_t max,
+                                                  bool automatic)
 {
        enum smu_message_type msg_set_min, msg_set_max;
        uint32_t min_clk = min;
@@ -1134,7 +1135,7 @@ static int yellow_carp_force_clk_levels(struct smu_context *smu,
                if (ret)
                        goto force_level_out;
 
-               ret = yellow_carp_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+               ret = yellow_carp_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
                if (ret)
                        goto force_level_out;
                break;
@@ -1254,9 +1255,10 @@ static int yellow_carp_set_performance_level(struct smu_context *smu,
 
        if (sclk_min && sclk_max) {
                ret = yellow_carp_set_soft_freq_limited_range(smu,
-                                                           SMU_SCLK,
-                                                           sclk_min,
-                                                           sclk_max);
+                                                             SMU_SCLK,
+                                                             sclk_min,
+                                                             sclk_max,
+                                                             false);
                if (ret)
                        return ret;
 
@@ -1266,18 +1268,20 @@ static int yellow_carp_set_performance_level(struct smu_context *smu,
 
        if (fclk_min && fclk_max) {
                ret = yellow_carp_set_soft_freq_limited_range(smu,
-                                                           SMU_FCLK,
-                                                           fclk_min,
-                                                           fclk_max);
+                                                             SMU_FCLK,
+                                                             fclk_min,
+                                                             fclk_max,
+                                                             false);
                if (ret)
                        return ret;
        }
 
        if (socclk_min && socclk_max) {
                ret = yellow_carp_set_soft_freq_limited_range(smu,
-                                                           SMU_SOCCLK,
-                                                           socclk_min,
-                                                           socclk_max);
+                                                             SMU_SOCCLK,
+                                                             socclk_min,
+                                                             socclk_max,
+                                                             false);
                if (ret)
                        return ret;
        }
@@ -1286,7 +1290,8 @@ static int yellow_carp_set_performance_level(struct smu_context *smu,
                ret = yellow_carp_set_soft_freq_limited_range(smu,
                                                              SMU_VCLK,
                                                              vclk_min,
-                                                             vclk_max);
+                                                             vclk_max,
+                                                             false);
                if (ret)
                        return ret;
        }
@@ -1295,7 +1300,8 @@ static int yellow_carp_set_performance_level(struct smu_context *smu,
                ret = yellow_carp_set_soft_freq_limited_range(smu,
                                                              SMU_DCLK,
                                                              dclk_min,
-                                                             dclk_max);
+                                                             dclk_max,
+                                                             false);
                if (ret)
                        return ret;
        }
index 865e916fc42544afd5d85efef7285f28110bde25..f7745eaf118e05f04ea6afa7e9b7445eddc28f3c 100644 (file)
@@ -1102,7 +1102,8 @@ failed:
 int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu,
                                          enum smu_clk_type clk_type,
                                          uint32_t min,
-                                         uint32_t max)
+                                         uint32_t max,
+                                         bool automatic)
 {
        int ret = 0, clk_id = 0;
        uint32_t param;
@@ -1117,7 +1118,10 @@ int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu,
                return clk_id;
 
        if (max > 0) {
-               param = (uint32_t)((clk_id << 16) | (max & 0xffff));
+               if (automatic)
+                       param = (uint32_t)((clk_id << 16) | 0xffff);
+               else
+                       param = (uint32_t)((clk_id << 16) | (max & 0xffff));
                ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
                                                      param, NULL);
                if (ret)
@@ -1125,7 +1129,10 @@ int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu,
        }
 
        if (min > 0) {
-               param = (uint32_t)((clk_id << 16) | (min & 0xffff));
+               if (automatic)
+                       param = (uint32_t)((clk_id << 16) | 0);
+               else
+                       param = (uint32_t)((clk_id << 16) | (min & 0xffff));
                ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
                                                      param, NULL);
                if (ret)
@@ -1202,6 +1209,7 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
        uint32_t dclk_min = 0, dclk_max = 0;
        uint32_t fclk_min = 0, fclk_max = 0;
        int ret = 0, i;
+       bool auto_level = false;
 
        switch (level) {
        case AMD_DPM_FORCED_LEVEL_HIGH:
@@ -1233,6 +1241,7 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                dclk_max = dclk_table->max;
                fclk_min = fclk_table->min;
                fclk_max = fclk_table->max;
+               auto_level = true;
                break;
        case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
                sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
@@ -1268,7 +1277,8 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                            SMU_GFXCLK,
                                                            sclk_min,
-                                                           sclk_max);
+                                                           sclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
@@ -1280,7 +1290,8 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                            SMU_MCLK,
                                                            mclk_min,
-                                                           mclk_max);
+                                                           mclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
@@ -1292,7 +1303,8 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                            SMU_SOCCLK,
                                                            socclk_min,
-                                                           socclk_max);
+                                                           socclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
@@ -1307,7 +1319,8 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                        ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                                    i ? SMU_VCLK1 : SMU_VCLK,
                                                                    vclk_min,
-                                                                   vclk_max);
+                                                                   vclk_max,
+                                                                   auto_level);
                        if (ret)
                                return ret;
                }
@@ -1322,7 +1335,8 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                        ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                                    i ? SMU_DCLK1 : SMU_DCLK,
                                                                    dclk_min,
-                                                                   dclk_max);
+                                                                   dclk_max,
+                                                                   auto_level);
                        if (ret)
                                return ret;
                }
@@ -1334,7 +1348,8 @@ int smu_v14_0_set_performance_level(struct smu_context *smu,
                ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                            SMU_FCLK,
                                                            fclk_min,
-                                                           fclk_max);
+                                                           fclk_max,
+                                                           auto_level);
                if (ret)
                        return ret;
 
index ade3ee398e3d812bf867871925784aea7011a811..27f4e0ce447dbd5809c93f6246d73e2dafb4fc9e 100644 (file)
@@ -1503,7 +1503,8 @@ static int smu_v14_0_2_force_clk_levels(struct smu_context *smu,
                ret = smu_v14_0_set_soft_freq_limited_range(smu,
                                                            clk_type,
                                                            min_freq,
-                                                           max_freq);
+                                                           max_freq,
+                                                           false);
                break;
        case SMU_DCEFCLK:
        case SMU_PCIE: