forked from Minki/linux
drm/amd/powerplay: update the common API for performance level setting
So that it can be more widely shared around SMU v11 ASICs. Signed-off-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
62cc9dd182
commit
768bb9010a
@ -1874,38 +1874,101 @@ int smu_v11_0_override_pcie_parameters(struct smu_context *smu)
|
||||
int smu_v11_0_set_performance_level(struct smu_context *smu,
|
||||
enum amd_dpm_forced_level level)
|
||||
{
|
||||
struct smu_11_0_dpm_context *dpm_context =
|
||||
smu->smu_dpm.dpm_context;
|
||||
struct smu_11_0_dpm_table *gfx_table =
|
||||
&dpm_context->dpm_tables.gfx_table;
|
||||
struct smu_11_0_dpm_table *mem_table =
|
||||
&dpm_context->dpm_tables.uclk_table;
|
||||
struct smu_11_0_dpm_table *soc_table =
|
||||
&dpm_context->dpm_tables.soc_table;
|
||||
struct smu_umd_pstate_table *pstate_table =
|
||||
&smu->pstate_table;
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
uint32_t sclk_min = 0, sclk_max = 0;
|
||||
uint32_t mclk_min = 0, mclk_max = 0;
|
||||
uint32_t socclk_min = 0, socclk_max = 0;
|
||||
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);
|
||||
sclk_min = sclk_max = gfx_table->max;
|
||||
mclk_min = mclk_max = mem_table->max;
|
||||
socclk_min = socclk_max = soc_table->max;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_LOW:
|
||||
ret = smu_force_dpm_limit_value(smu, false);
|
||||
sclk_min = sclk_max = gfx_table->min;
|
||||
mclk_min = mclk_max = mem_table->min;
|
||||
socclk_min = socclk_max = soc_table->min;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_AUTO:
|
||||
sclk_min = gfx_table->min;
|
||||
sclk_max = gfx_table->max;
|
||||
mclk_min = mem_table->min;
|
||||
mclk_max = mem_table->max;
|
||||
socclk_min = soc_table->min;
|
||||
socclk_max = soc_table->max;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
|
||||
ret = smu_unforce_dpm_levels(smu);
|
||||
sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
|
||||
mclk_min = mclk_max = pstate_table->uclk_pstate.standard;
|
||||
socclk_min = socclk_max = pstate_table->socclk_pstate.standard;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
|
||||
sclk_min = sclk_max = pstate_table->gfxclk_pstate.min;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
|
||||
mclk_min = mclk_max = pstate_table->uclk_pstate.min;
|
||||
break;
|
||||
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);
|
||||
sclk_min = sclk_max = pstate_table->gfxclk_pstate.peak;
|
||||
mclk_min = mclk_max = pstate_table->uclk_pstate.peak;
|
||||
socclk_min = socclk_max = pstate_table->socclk_pstate.peak;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_MANUAL:
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
dev_err(adev->dev, "Invalid performance level %d\n", level);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Separate MCLK and SOCCLK soft min/max settings are not allowed
|
||||
* on Arcturus.
|
||||
*/
|
||||
if (adev->asic_type == CHIP_ARCTURUS) {
|
||||
mclk_min = mclk_max = 0;
|
||||
socclk_min = socclk_max = 0;
|
||||
}
|
||||
|
||||
if (sclk_min && sclk_max) {
|
||||
ret = smu_v11_0_set_soft_freq_limited_range(smu,
|
||||
SMU_GFXCLK,
|
||||
sclk_min,
|
||||
sclk_max);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mclk_min && mclk_max) {
|
||||
ret = smu_v11_0_set_soft_freq_limited_range(smu,
|
||||
SMU_MCLK,
|
||||
mclk_min,
|
||||
mclk_max);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (socclk_min && socclk_max) {
|
||||
ret = smu_v11_0_set_soft_freq_limited_range(smu,
|
||||
SMU_SOCCLK,
|
||||
socclk_min,
|
||||
socclk_max);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user