]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/amd/pm: modify the fine grain tuning function for Renoir
authorXiaojian Du <Xiaojian.Du@amd.com>
Tue, 29 Dec 2020 10:32:11 +0000 (18:32 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 8 Jan 2021 20:18:45 +0000 (15:18 -0500)
This patch is to improve the fine grain tuning function for Renoir.
The fine grain tuning function uses the sysfs node -- pp_od_clk_voltage
to config gfxclk. Meanwhile, another sysfs
node -- power_dpm_force_perfomance_level also affects the gfx clk.
It will cause confusion when these two sysfs nodes works
together.
And the flag "od_enabled" is used to control the overdrive function for
dGPU, like navi10, navi14 and navi21.
APU like Renior or Vangogh uses this "od_enabled" to configure
the frequency range of gfx clock, but the max value of frequency
range will not be higher than the safe limit, it is not "overdrive".
So this patch adds two new flags -- "fine_grain_enabled" and
"fine_grain_started" to avoid this confusion, the flag will
make these two sysfs nodes work separately.
The flag "fine_grain_enabled" is set as "enabled" by default,
so the fine grain tuning function will be enabled by default.
But the flag "fine_grain_started" is set as "false" by default,
so the fine grain function will not take effect until it is set as
"true".
Only when power_dpm_force_perfomance_level is changed to
"manual" mode, the flag "fine_grain_started" will be set as "true",
and the fine grain tuning function will be started.
In other profile modes, including "auto", "high", "low", "profile_peak",
"profile_standard", "profile_min_sclk", "profile_min_mclk",
the flag "fine_grain_started" will be set as "false", and the od range of
fine grain tuning function will be restored default value.

Signed-off-by: Xiaojian Du <Xiaojian.Du@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/amdgpu_pm.c
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c

index 97c669dd4cac743a0bfae83221b5c8b775fbf912..f5d97b97353a888ba70dc76f09e9f0c0b5c755a0 100644 (file)
@@ -2217,7 +2217,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
        } else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) {
                *states = ATTR_STATE_UNSUPPORTED;
                if ((is_support_sw_smu(adev) && adev->smu.od_enabled) ||
-                   (!is_support_sw_smu(adev) && hwmgr->od_enabled))
+                   (is_support_sw_smu(adev) && adev->smu.fine_grain_enabled) ||
+                       (!is_support_sw_smu(adev) && hwmgr->od_enabled))
                        *states = ATTR_STATE_SUPPORTED;
        } else if (DEVICE_ATTR_IS(mem_busy_percent)) {
                if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10)
index a9622b5e9c7b36c2aa454bac6d69143a64be526f..e2e59fb0f754304c9c7cd70a0f9abec6aa56444c 100644 (file)
@@ -465,6 +465,9 @@ struct smu_context
        uint32_t gfx_default_soft_max_freq;
        uint32_t gfx_actual_hard_min_freq;
        uint32_t gfx_actual_soft_max_freq;
+
+       bool fine_grain_enabled;
+       bool fine_grain_started;
 };
 
 struct i2c_adapter;
index d80f7f8efdcddac87a6de9aca53d407a84385aba..8e1e97e314111a28d09f3ed54ed2929041009ac3 100644 (file)
@@ -402,8 +402,10 @@ static int smu_set_funcs(struct amdgpu_device *adev)
                break;
        case CHIP_RENOIR:
                renoir_set_ppt_funcs(smu);
-               /* enable the OD by default to allow the fine grain tuning function */
-               smu->od_enabled = true;
+               /* enable the fine grain tuning function by default */
+               smu->fine_grain_enabled = true;
+               /* close the fine grain tuning function by default */
+               smu->fine_grain_started = false;
                break;
        case CHIP_VANGOGH:
                vangogh_set_ppt_funcs(smu);
index e44fd23ffe0608acd714926f9788a0554f817f26..1f6a774278b1466a2030bd70331163c33772de8c 100644 (file)
@@ -350,11 +350,16 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
 {
        int ret = 0;
 
-       if (!smu->od_enabled) {
+       if (!smu->fine_grain_enabled) {
                dev_warn(smu->adev->dev, "Fine grain is not enabled!\n");
                return -EINVAL;
        }
 
+       if (!smu->fine_grain_started) {
+               dev_warn(smu->adev->dev, "Fine grain is enabled but not started!\n");
+               return -EINVAL;
+       }
+
        switch (type) {
        case PP_OD_EDIT_SCLK_VDDC_TABLE:
                if (size != 2) {
@@ -364,14 +369,16 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
 
                if (input[0] == 0) {
                        if (input[1] < smu->gfx_default_hard_min_freq) {
-                               dev_warn(smu->adev->dev, "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
+                               dev_warn(smu->adev->dev,
+                                       "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
                                        input[1], smu->gfx_default_hard_min_freq);
                                return -EINVAL;
                        }
                        smu->gfx_actual_hard_min_freq = input[1];
                } else if (input[0] == 1) {
                        if (input[1] > smu->gfx_default_soft_max_freq) {
-                               dev_warn(smu->adev->dev, "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
+                               dev_warn(smu->adev->dev,
+                                       "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
                                        input[1], smu->gfx_default_soft_max_freq);
                                return -EINVAL;
                        }
@@ -412,8 +419,10 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
                        return -EINVAL;
                } else {
                        if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) {
-                               dev_err(smu->adev->dev, "The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
-                               smu->gfx_actual_hard_min_freq, smu->gfx_actual_soft_max_freq);
+                               dev_err(smu->adev->dev,
+                                       "The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
+                                       smu->gfx_actual_hard_min_freq,
+                                       smu->gfx_actual_soft_max_freq);
                                return -EINVAL;
                        }
 
@@ -483,7 +492,7 @@ static int renoir_print_clk_levels(struct smu_context *smu,
 
        switch (clk_type) {
        case SMU_OD_RANGE:
-               if (smu->od_enabled) {
+               if (smu->fine_grain_enabled) {
                        ret = smu_cmn_send_smc_msg_with_param(smu,
                                                SMU_MSG_GetMinGfxclkFrequency,
                                                0, &min);
@@ -498,11 +507,13 @@ static int renoir_print_clk_levels(struct smu_context *smu,
                }
                break;
        case SMU_OD_SCLK:
+               if (smu->fine_grain_enabled) {
                        min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
                        max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
                        size += sprintf(buf + size, "OD_SCLK\n");
                        size += sprintf(buf + size, "0:%10uMhz\n", min);
                        size += sprintf(buf + size, "1:%10uMhz\n", max);
+               }
                break;
        case SMU_GFXCLK:
        case SMU_SCLK:
@@ -882,15 +893,31 @@ static int renoir_set_performance_level(struct smu_context *smu,
 
        switch (level) {
        case AMD_DPM_FORCED_LEVEL_HIGH:
+               smu->fine_grain_started = 0;
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+
                ret = renoir_force_dpm_limit_value(smu, true);
                break;
        case AMD_DPM_FORCED_LEVEL_LOW:
+               smu->fine_grain_started = 0;
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+
                ret = renoir_force_dpm_limit_value(smu, false);
                break;
        case AMD_DPM_FORCED_LEVEL_AUTO:
+               smu->fine_grain_started = 0;
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+
                ret = renoir_unforce_dpm_levels(smu);
                break;
        case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+               smu->fine_grain_started = 0;
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+
                ret = smu_cmn_send_smc_msg_with_param(smu,
                                                      SMU_MSG_SetHardMinGfxClk,
                                                      RENOIR_UMD_PSTATE_GFXCLK,
@@ -943,6 +970,10 @@ static int renoir_set_performance_level(struct smu_context *smu,
                break;
        case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
        case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
+               smu->fine_grain_started = 0;
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+
                ret = renoir_get_profiling_clk_mask(smu, level,
                                                    &sclk_mask,
                                                    &mclk_mask,
@@ -954,9 +985,14 @@ static int renoir_set_performance_level(struct smu_context *smu,
                renoir_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
                break;
        case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
+               smu->fine_grain_started = 0;
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+
                ret = renoir_set_peak_clock_by_device(smu);
                break;
        case AMD_DPM_FORCED_LEVEL_MANUAL:
+               smu->fine_grain_started = 1;
        case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
        default:
                break;