Commit 337443d0 authored by Alex Deucher's avatar Alex Deucher

drm/amdgpu/smu: make the set_performance_level logic easier to follow

Have every asic provide a callback for this rather than a mix
of generic and asic specific code.
Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c00ca07f
...@@ -1607,43 +1607,6 @@ static int smu_enable_umd_pstate(void *handle, ...@@ -1607,43 +1607,6 @@ static int smu_enable_umd_pstate(void *handle,
return 0; 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, false);
smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
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, int smu_adjust_power_state_dynamic(struct smu_context *smu,
enum amd_dpm_forced_level level, enum amd_dpm_forced_level level,
bool skip_display_settings) bool skip_display_settings)
...@@ -1680,13 +1643,10 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu, ...@@ -1680,13 +1643,10 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,
if (smu_dpm_ctx->dpm_level != level) { if (smu_dpm_ctx->dpm_level != level) {
ret = smu_asic_set_performance_level(smu, level); ret = smu_asic_set_performance_level(smu, level);
if (ret) {
ret = smu_default_set_performance_level(smu, level);
if (ret) { if (ret) {
pr_err("Failed to set performance level!"); pr_err("Failed to set performance level!");
return ret; return ret;
} }
}
/* update the saved copy */ /* update the saved copy */
smu_dpm_ctx->dpm_level = level; smu_dpm_ctx->dpm_level = level;
......
...@@ -2237,6 +2237,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { ...@@ -2237,6 +2237,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
.get_profiling_clk_mask = arcturus_get_profiling_clk_mask, .get_profiling_clk_mask = arcturus_get_profiling_clk_mask,
.get_power_profile_mode = arcturus_get_power_profile_mode, .get_power_profile_mode = arcturus_get_power_profile_mode,
.set_power_profile_mode = arcturus_set_power_profile_mode, .set_power_profile_mode = arcturus_set_power_profile_mode,
.set_performance_level = smu_v11_0_set_performance_level,
/* debug (internal used) */ /* debug (internal used) */
.dump_pptable = arcturus_dump_pptable, .dump_pptable = arcturus_dump_pptable,
.get_power_limit = arcturus_get_power_limit, .get_power_limit = arcturus_get_power_limit,
......
...@@ -262,4 +262,7 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, ...@@ -262,4 +262,7 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize,
uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu); uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu);
int smu_v11_0_set_performance_level(struct smu_context *smu,
enum amd_dpm_forced_level level);
#endif #endif
...@@ -1658,19 +1658,43 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu) ...@@ -1658,19 +1658,43 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu)
return ret; return ret;
} }
static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) static int navi10_set_performance_level(struct smu_context *smu,
enum amd_dpm_forced_level level)
{ {
int ret = 0; int ret = 0;
uint32_t sclk_mask, mclk_mask, soc_mask;
switch (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:
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, false);
smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
ret = navi10_set_peak_clock_by_device(smu); ret = navi10_set_peak_clock_by_device(smu);
break; break;
case AMD_DPM_FORCED_LEVEL_MANUAL:
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
default: default:
ret = -EINVAL;
break; break;
} }
return ret; return ret;
} }
......
...@@ -708,19 +708,43 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu) ...@@ -708,19 +708,43 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
return ret; return ret;
} }
static int renoir_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) static int renoir_set_performance_level(struct smu_context *smu,
enum amd_dpm_forced_level level)
{ {
int ret = 0; int ret = 0;
uint32_t sclk_mask, mclk_mask, soc_mask;
switch (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:
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, false);
smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
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_PROFILE_EXIT:
default: default:
ret = -EINVAL;
break; break;
} }
return ret; return ret;
} }
......
...@@ -1860,3 +1860,42 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, ...@@ -1860,3 +1860,42 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize,
} }
return ret; return ret;
} }
int smu_v11_0_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, false);
smu_force_clk_levels(smu, SMU_MCLK, 1 << mclk_mask, false);
smu_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask, false);
break;
case AMD_DPM_FORCED_LEVEL_MANUAL:
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
default:
break;
}
return ret;
}
...@@ -3194,6 +3194,7 @@ static const struct pptable_funcs vega20_ppt_funcs = { ...@@ -3194,6 +3194,7 @@ static const struct pptable_funcs vega20_ppt_funcs = {
.get_od_percentage = vega20_get_od_percentage, .get_od_percentage = vega20_get_od_percentage,
.get_power_profile_mode = vega20_get_power_profile_mode, .get_power_profile_mode = vega20_get_power_profile_mode,
.set_power_profile_mode = vega20_set_power_profile_mode, .set_power_profile_mode = vega20_set_power_profile_mode,
.set_performance_level = smu_v11_0_set_performance_level,
.set_od_percentage = vega20_set_od_percentage, .set_od_percentage = vega20_set_od_percentage,
.set_default_od_settings = vega20_set_default_od_settings, .set_default_od_settings = vega20_set_default_od_settings,
.od_edit_dpm_table = vega20_odn_edit_dpm_table, .od_edit_dpm_table = vega20_odn_edit_dpm_table,
......
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