Commit 08da4fcd authored by Xiaojian Du's avatar Xiaojian Du Committed by Alex Deucher

drm/amd/pm: modify the fine grain tuning function for Renoir

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: default avatarXiaojian Du <Xiaojian.Du@amd.com>
Reviewed-by: default avatarHuang Rui <ray.huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 307f049b
...@@ -2217,7 +2217,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ ...@@ -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)) { } else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) {
*states = ATTR_STATE_UNSUPPORTED; *states = ATTR_STATE_UNSUPPORTED;
if ((is_support_sw_smu(adev) && adev->smu.od_enabled) || 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; *states = ATTR_STATE_SUPPORTED;
} else if (DEVICE_ATTR_IS(mem_busy_percent)) { } else if (DEVICE_ATTR_IS(mem_busy_percent)) {
if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10) if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10)
......
...@@ -465,6 +465,9 @@ struct smu_context ...@@ -465,6 +465,9 @@ struct smu_context
uint32_t gfx_default_soft_max_freq; uint32_t gfx_default_soft_max_freq;
uint32_t gfx_actual_hard_min_freq; uint32_t gfx_actual_hard_min_freq;
uint32_t gfx_actual_soft_max_freq; uint32_t gfx_actual_soft_max_freq;
bool fine_grain_enabled;
bool fine_grain_started;
}; };
struct i2c_adapter; struct i2c_adapter;
......
...@@ -402,8 +402,10 @@ static int smu_set_funcs(struct amdgpu_device *adev) ...@@ -402,8 +402,10 @@ static int smu_set_funcs(struct amdgpu_device *adev)
break; break;
case CHIP_RENOIR: case CHIP_RENOIR:
renoir_set_ppt_funcs(smu); renoir_set_ppt_funcs(smu);
/* enable the OD by default to allow the fine grain tuning function */ /* enable the fine grain tuning function by default */
smu->od_enabled = true; smu->fine_grain_enabled = true;
/* close the fine grain tuning function by default */
smu->fine_grain_started = false;
break; break;
case CHIP_VANGOGH: case CHIP_VANGOGH:
vangogh_set_ppt_funcs(smu); vangogh_set_ppt_funcs(smu);
......
...@@ -350,11 +350,16 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu, ...@@ -350,11 +350,16 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
{ {
int ret = 0; int ret = 0;
if (!smu->od_enabled) { if (!smu->fine_grain_enabled) {
dev_warn(smu->adev->dev, "Fine grain is not enabled!\n"); dev_warn(smu->adev->dev, "Fine grain is not enabled!\n");
return -EINVAL; return -EINVAL;
} }
if (!smu->fine_grain_started) {
dev_warn(smu->adev->dev, "Fine grain is enabled but not started!\n");
return -EINVAL;
}
switch (type) { switch (type) {
case PP_OD_EDIT_SCLK_VDDC_TABLE: case PP_OD_EDIT_SCLK_VDDC_TABLE:
if (size != 2) { if (size != 2) {
...@@ -364,14 +369,16 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu, ...@@ -364,14 +369,16 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
if (input[0] == 0) { if (input[0] == 0) {
if (input[1] < smu->gfx_default_hard_min_freq) { 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); input[1], smu->gfx_default_hard_min_freq);
return -EINVAL; return -EINVAL;
} }
smu->gfx_actual_hard_min_freq = input[1]; smu->gfx_actual_hard_min_freq = input[1];
} else if (input[0] == 1) { } else if (input[0] == 1) {
if (input[1] > smu->gfx_default_soft_max_freq) { 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); input[1], smu->gfx_default_soft_max_freq);
return -EINVAL; return -EINVAL;
} }
...@@ -412,8 +419,10 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu, ...@@ -412,8 +419,10 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
return -EINVAL; return -EINVAL;
} else { } else {
if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) { 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", dev_err(smu->adev->dev,
smu->gfx_actual_hard_min_freq, smu->gfx_actual_soft_max_freq); "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; return -EINVAL;
} }
...@@ -483,7 +492,7 @@ static int renoir_print_clk_levels(struct smu_context *smu, ...@@ -483,7 +492,7 @@ static int renoir_print_clk_levels(struct smu_context *smu,
switch (clk_type) { switch (clk_type) {
case SMU_OD_RANGE: case SMU_OD_RANGE:
if (smu->od_enabled) { if (smu->fine_grain_enabled) {
ret = smu_cmn_send_smc_msg_with_param(smu, ret = smu_cmn_send_smc_msg_with_param(smu,
SMU_MSG_GetMinGfxclkFrequency, SMU_MSG_GetMinGfxclkFrequency,
0, &min); 0, &min);
...@@ -498,11 +507,13 @@ static int renoir_print_clk_levels(struct smu_context *smu, ...@@ -498,11 +507,13 @@ static int renoir_print_clk_levels(struct smu_context *smu,
} }
break; break;
case SMU_OD_SCLK: 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; 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; 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, "OD_SCLK\n");
size += sprintf(buf + size, "0:%10uMhz\n", min); size += sprintf(buf + size, "0:%10uMhz\n", min);
size += sprintf(buf + size, "1:%10uMhz\n", max); size += sprintf(buf + size, "1:%10uMhz\n", max);
}
break; break;
case SMU_GFXCLK: case SMU_GFXCLK:
case SMU_SCLK: case SMU_SCLK:
...@@ -882,15 +893,31 @@ static int renoir_set_performance_level(struct smu_context *smu, ...@@ -882,15 +893,31 @@ static int renoir_set_performance_level(struct smu_context *smu,
switch (level) { switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH: 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); ret = renoir_force_dpm_limit_value(smu, true);
break; break;
case AMD_DPM_FORCED_LEVEL_LOW: 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); ret = renoir_force_dpm_limit_value(smu, false);
break; break;
case AMD_DPM_FORCED_LEVEL_AUTO: 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); ret = renoir_unforce_dpm_levels(smu);
break; break;
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: 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, ret = smu_cmn_send_smc_msg_with_param(smu,
SMU_MSG_SetHardMinGfxClk, SMU_MSG_SetHardMinGfxClk,
RENOIR_UMD_PSTATE_GFXCLK, RENOIR_UMD_PSTATE_GFXCLK,
...@@ -943,6 +970,10 @@ static int renoir_set_performance_level(struct smu_context *smu, ...@@ -943,6 +970,10 @@ static int renoir_set_performance_level(struct smu_context *smu,
break; break;
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 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, ret = renoir_get_profiling_clk_mask(smu, level,
&sclk_mask, &sclk_mask,
&mclk_mask, &mclk_mask,
...@@ -954,9 +985,14 @@ static int renoir_set_performance_level(struct smu_context *smu, ...@@ -954,9 +985,14 @@ static int renoir_set_performance_level(struct smu_context *smu,
renoir_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask); renoir_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
break; break;
case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 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); ret = renoir_set_peak_clock_by_device(smu);
break; break;
case AMD_DPM_FORCED_LEVEL_MANUAL: case AMD_DPM_FORCED_LEVEL_MANUAL:
smu->fine_grain_started = 1;
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
default: default:
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment