mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 15:43:35 -04:00
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: Evan Quan <evan.quan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -1607,43 +1607,6 @@ 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, 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,
|
||||
enum amd_dpm_forced_level level,
|
||||
bool skip_display_settings)
|
||||
@@ -1681,11 +1644,8 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
if (smu_dpm_ctx->dpm_level != level) {
|
||||
ret = smu_asic_set_performance_level(smu, level);
|
||||
if (ret) {
|
||||
ret = smu_default_set_performance_level(smu, level);
|
||||
if (ret) {
|
||||
pr_err("Failed to set performance level!");
|
||||
return ret;
|
||||
}
|
||||
pr_err("Failed to set performance level!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* update the saved copy */
|
||||
|
||||
@@ -2237,6 +2237,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
|
||||
.get_profiling_clk_mask = arcturus_get_profiling_clk_mask,
|
||||
.get_power_profile_mode = arcturus_get_power_profile_mode,
|
||||
.set_power_profile_mode = arcturus_set_power_profile_mode,
|
||||
.set_performance_level = smu_v11_0_set_performance_level,
|
||||
/* debug (internal used) */
|
||||
.dump_pptable = arcturus_dump_pptable,
|
||||
.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,
|
||||
|
||||
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
|
||||
|
||||
@@ -1658,19 +1658,43 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu)
|
||||
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;
|
||||
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:
|
||||
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:
|
||||
ret = navi10_set_peak_clock_by_device(smu);
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_MANUAL:
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -708,19 +708,43 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
|
||||
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;
|
||||
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:
|
||||
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:
|
||||
ret = renoir_set_peak_clock_by_device(smu);
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_MANUAL:
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1860,3 +1860,42 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize,
|
||||
}
|
||||
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 = {
|
||||
.get_od_percentage = vega20_get_od_percentage,
|
||||
.get_power_profile_mode = vega20_get_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_default_od_settings = vega20_set_default_od_settings,
|
||||
.od_edit_dpm_table = vega20_odn_edit_dpm_table,
|
||||
|
||||
Reference in New Issue
Block a user