ret = smu->ppt_funcs->set_soft_freq_limited_range(smu,
clk_type,
min,
- max);
+ max,
+ false);
return ret;
}
* @set_soft_freq_limited_range: Set the soft frequency range of a clock
* domain in MHz.
*/
- int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);
+ int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max,
+ bool automatic);
/**
* @set_power_source: Notify the SMU of the current power source.
uint32_t *min, uint32_t *max);
int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
- uint32_t min, uint32_t max);
+ uint32_t min, uint32_t max, bool automatic);
int smu_v11_0_set_hard_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
int smu_v12_0_mode2_reset(struct smu_context *smu);
int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
- uint32_t min, uint32_t max);
+ uint32_t min, uint32_t max, bool automatic);
int smu_v12_0_set_driver_table_location(struct smu_context *smu);
uint32_t *min, uint32_t *max);
int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
- uint32_t min, uint32_t max);
+ uint32_t min, uint32_t max, bool automatic);
int smu_v13_0_set_hard_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t *min, uint32_t *max);
int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
- uint32_t min, uint32_t max);
+ uint32_t min, uint32_t max, bool automatic);
int smu_v14_0_set_hard_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
if (ret)
return 0;
- ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+ ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
if (ret)
return 0;
break;
if (ret)
goto forec_level_out;
- ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+ ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
if (ret)
goto forec_level_out;
break;
int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t min,
- uint32_t max)
+ uint32_t max,
+ bool automatic)
{
int ret = 0, clk_id = 0;
uint32_t param;
return clk_id;
if (max > 0) {
- param = (uint32_t)((clk_id << 16) | (max & 0xffff));
+ if (automatic)
+ param = (uint32_t)((clk_id << 16) | 0xffff);
+ else
+ param = (uint32_t)((clk_id << 16) | (max & 0xffff));
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
param, NULL);
if (ret)
}
if (min > 0) {
- param = (uint32_t)((clk_id << 16) | (min & 0xffff));
+ if (automatic)
+ param = (uint32_t)((clk_id << 16) | 0);
+ else
+ param = (uint32_t)((clk_id << 16) | (min & 0xffff));
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
param, NULL);
if (ret)
uint32_t mclk_min = 0, mclk_max = 0;
uint32_t socclk_min = 0, socclk_max = 0;
int ret = 0;
+ bool auto_level = false;
switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH:
mclk_max = mem_table->max;
socclk_min = soc_table->min;
socclk_max = soc_table->max;
+ auto_level = true;
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) {
mclk_min = mclk_max = 0;
socclk_min = socclk_max = 0;
+ auto_level = false;
}
if (sclk_min && sclk_max) {
ret = smu_v11_0_set_soft_freq_limited_range(smu,
SMU_GFXCLK,
sclk_min,
- sclk_max);
+ sclk_max,
+ auto_level);
if (ret)
return ret;
}
ret = smu_v11_0_set_soft_freq_limited_range(smu,
SMU_MCLK,
mclk_min,
- mclk_max);
+ mclk_max,
+ auto_level);
if (ret)
return ret;
}
ret = smu_v11_0_set_soft_freq_limited_range(smu,
SMU_SOCCLK,
socclk_min,
- socclk_max);
+ socclk_max,
+ auto_level);
if (ret)
return ret;
}
}
static int vangogh_set_soft_freq_limited_range(struct smu_context *smu,
- enum smu_clk_type clk_type,
- uint32_t min,
- uint32_t max)
+ enum smu_clk_type clk_type,
+ uint32_t min,
+ uint32_t max,
+ bool automatic)
{
int ret = 0;
return ret;
force_freq = highest ? max_freq : min_freq;
- ret = vangogh_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
+ ret = vangogh_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq, false);
if (ret)
return ret;
}
if (ret)
return ret;
- ret = vangogh_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+ ret = vangogh_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
if (ret)
return ret;
if (ret)
return ret;
- ret = vangogh_set_soft_freq_limited_range(smu, SMU_FCLK, fclk_freq, fclk_freq);
+ ret = vangogh_set_soft_freq_limited_range(smu, SMU_FCLK, fclk_freq, fclk_freq, false);
if (ret)
return ret;
if (ret)
return ret;
- ret = vangogh_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk_freq, socclk_freq);
+ ret = vangogh_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk_freq, socclk_freq, false);
if (ret)
return ret;
if (ret)
return ret;
- ret = vangogh_set_soft_freq_limited_range(smu, SMU_VCLK, vclk_freq, vclk_freq);
+ ret = vangogh_set_soft_freq_limited_range(smu, SMU_VCLK, vclk_freq, vclk_freq, false);
if (ret)
return ret;
if (ret)
return ret;
- ret = vangogh_set_soft_freq_limited_range(smu, SMU_DCLK, dclk_freq, dclk_freq);
+ ret = vangogh_set_soft_freq_limited_range(smu, SMU_DCLK, dclk_freq, dclk_freq, false);
if (ret)
return ret;
return ret;
force_freq = highest ? max_freq : min_freq;
- ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, force_freq, force_freq, false);
if (ret)
return ret;
}
if (ret)
return ret;
- ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
if (ret)
return ret;
}
if (ret)
return ret;
- ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_freq, sclk_freq, false);
if (ret)
return ret;
if (ret)
return ret;
- ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_UCLK, uclk_freq, uclk_freq, false);
if (ret)
return ret;
}
if (sclk)
- ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk, sclk);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SCLK, sclk, sclk, false);
if (socclk)
- ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk, socclk);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_SOCCLK, socclk, socclk, false);
if (fclk)
- ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_FCLK, fclk, fclk);
+ ret = smu_v12_0_set_soft_freq_limited_range(smu, SMU_FCLK, fclk, fclk, false);
return ret;
}
}
int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
- uint32_t min, uint32_t max)
+ uint32_t min, uint32_t max, bool automatic)
{
int ret = 0;
}
static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
- enum smu_clk_type clk_type,
- uint32_t min,
- uint32_t max)
+ enum smu_clk_type clk_type,
+ uint32_t min,
+ uint32_t max,
+ bool automatic)
{
struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
return 0;
ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK,
- min, max);
+ min, max, false);
if (!ret) {
pstate_table->gfxclk_pstate.curr.min = min;
pstate_table->gfxclk_pstate.curr.max = max;
/* Restore default min/max clocks and enable determinism */
min_clk = dpm_context->dpm_tables.gfx_table.min;
max_clk = dpm_context->dpm_tables.gfx_table.max;
- ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
+ ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk, false);
if (!ret) {
usleep_range(500, 1000);
ret = smu_cmn_send_smc_msg_with_param(smu,
min_clk = dpm_context->dpm_tables.gfx_table.min;
max_clk = dpm_context->dpm_tables.gfx_table.max;
- return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
+ return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk, false);
}
break;
case PP_OD_COMMIT_DPM_TABLE:
min_clk = pstate_table->gfxclk_pstate.custom.min;
max_clk = pstate_table->gfxclk_pstate.custom.max;
- return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk);
+ return aldebaran_set_soft_freq_limited_range(smu, SMU_GFXCLK, min_clk, max_clk, false);
}
break;
default:
int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t min,
- uint32_t max)
+ uint32_t max,
+ bool automatic)
{
int ret = 0, clk_id = 0;
uint32_t param;
return clk_id;
if (max > 0) {
- param = (uint32_t)((clk_id << 16) | (max & 0xffff));
+ if (automatic)
+ param = (uint32_t)((clk_id << 16) | 0xffff);
+ else
+ param = (uint32_t)((clk_id << 16) | (max & 0xffff));
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
param, NULL);
if (ret)
}
if (min > 0) {
- param = (uint32_t)((clk_id << 16) | (min & 0xffff));
+ if (automatic)
+ param = (uint32_t)((clk_id << 16) | 0);
+ else
+ param = (uint32_t)((clk_id << 16) | (min & 0xffff));
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
param, NULL);
if (ret)
uint32_t dclk_min = 0, dclk_max = 0;
uint32_t fclk_min = 0, fclk_max = 0;
int ret = 0, i;
+ bool auto_level = false;
switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH:
dclk_max = dclk_table->max;
fclk_min = fclk_table->min;
fclk_max = fclk_table->max;
+ auto_level = true;
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
vclk_min = vclk_max = 0;
dclk_min = dclk_max = 0;
fclk_min = fclk_max = 0;
+ auto_level = false;
}
if (sclk_min && sclk_max) {
ret = smu_v13_0_set_soft_freq_limited_range(smu,
SMU_GFXCLK,
sclk_min,
- sclk_max);
+ sclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v13_0_set_soft_freq_limited_range(smu,
SMU_MCLK,
mclk_min,
- mclk_max);
+ mclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v13_0_set_soft_freq_limited_range(smu,
SMU_SOCCLK,
socclk_min,
- socclk_max);
+ socclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v13_0_set_soft_freq_limited_range(smu,
i ? SMU_VCLK1 : SMU_VCLK,
vclk_min,
- vclk_max);
+ vclk_max,
+ auto_level);
if (ret)
return ret;
}
ret = smu_v13_0_set_soft_freq_limited_range(smu,
i ? SMU_DCLK1 : SMU_DCLK,
dclk_min,
- dclk_max);
+ dclk_max,
+ auto_level);
if (ret)
return ret;
}
ret = smu_v13_0_set_soft_freq_limited_range(smu,
SMU_FCLK,
fclk_min,
- fclk_max);
+ fclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v13_0_set_soft_freq_limited_range(smu,
clk_type,
min_freq,
- max_freq);
+ max_freq,
+ false);
break;
case SMU_DCEFCLK:
case SMU_PCIE:
}
static int smu_v13_0_5_set_soft_freq_limited_range(struct smu_context *smu,
- enum smu_clk_type clk_type,
- uint32_t min,
- uint32_t max)
+ enum smu_clk_type clk_type,
+ uint32_t min,
+ uint32_t max,
+ bool automatic)
{
enum smu_message_type msg_set_min, msg_set_max;
uint32_t min_clk = min;
if (ret)
goto force_level_out;
- ret = smu_v13_0_5_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+ ret = smu_v13_0_5_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
if (ret)
goto force_level_out;
break;
if (sclk_min && sclk_max) {
ret = smu_v13_0_5_set_soft_freq_limited_range(smu,
- SMU_SCLK,
- sclk_min,
- sclk_max);
+ SMU_SCLK,
+ sclk_min,
+ sclk_max,
+ false);
if (ret)
return ret;
ret = smu_v13_0_5_set_soft_freq_limited_range(smu,
SMU_VCLK,
vclk_min,
- vclk_max);
+ vclk_max,
+ false);
if (ret)
return ret;
}
ret = smu_v13_0_5_set_soft_freq_limited_range(smu,
SMU_DCLK,
dclk_min,
- dclk_max);
+ dclk_max,
+ false);
if (ret)
return ret;
}
if (uclk_table->max != pstate_table->uclk_pstate.curr.max) {
/* Min UCLK is not expected to be changed */
ret = smu_v13_0_set_soft_freq_limited_range(
- smu, SMU_UCLK, 0, uclk_table->max);
+ smu, SMU_UCLK, 0, uclk_table->max, false);
if (ret)
return ret;
pstate_table->uclk_pstate.curr.max = uclk_table->max;
static int smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
- uint32_t min, uint32_t max)
+ uint32_t min, uint32_t max,
+ bool automatic)
{
struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
return -EOPNOTSUPP;
/* Only max clock limiting is allowed for UCLK */
ret = smu_v13_0_set_soft_freq_limited_range(
- smu, SMU_UCLK, 0, max);
+ smu, SMU_UCLK, 0, max, false);
if (!ret)
pstate_table->uclk_pstate.curr.max = max;
}
max_clk = dpm_context->dpm_tables.gfx_table.max;
ret = smu_v13_0_6_set_soft_freq_limited_range(
- smu, SMU_GFXCLK, min_clk, max_clk);
+ smu, SMU_GFXCLK, min_clk, max_clk, false);
if (ret)
return ret;
min_clk = dpm_context->dpm_tables.uclk_table.min;
max_clk = dpm_context->dpm_tables.uclk_table.max;
ret = smu_v13_0_6_set_soft_freq_limited_range(
- smu, SMU_UCLK, min_clk, max_clk);
+ smu, SMU_UCLK, min_clk, max_clk, false);
if (ret)
return ret;
pstate_table->uclk_pstate.custom.max = 0;
max_clk = pstate_table->gfxclk_pstate.custom.max;
ret = smu_v13_0_6_set_soft_freq_limited_range(
- smu, SMU_GFXCLK, min_clk, max_clk);
+ smu, SMU_GFXCLK, min_clk, max_clk, false);
if (ret)
return ret;
min_clk = pstate_table->uclk_pstate.curr.min;
max_clk = pstate_table->uclk_pstate.custom.max;
return smu_v13_0_6_set_soft_freq_limited_range(
- smu, SMU_UCLK, min_clk, max_clk);
+ smu, SMU_UCLK, min_clk, max_clk, false);
}
break;
default:
ret = smu_v13_0_set_soft_freq_limited_range(smu,
clk_type,
min_freq,
- max_freq);
+ max_freq,
+ false);
break;
case SMU_DCEFCLK:
case SMU_PCIE:
}
static int yellow_carp_set_soft_freq_limited_range(struct smu_context *smu,
- enum smu_clk_type clk_type,
- uint32_t min,
- uint32_t max)
+ enum smu_clk_type clk_type,
+ uint32_t min,
+ uint32_t max,
+ bool automatic)
{
enum smu_message_type msg_set_min, msg_set_max;
uint32_t min_clk = min;
if (ret)
goto force_level_out;
- ret = yellow_carp_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
+ ret = yellow_carp_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
if (ret)
goto force_level_out;
break;
if (sclk_min && sclk_max) {
ret = yellow_carp_set_soft_freq_limited_range(smu,
- SMU_SCLK,
- sclk_min,
- sclk_max);
+ SMU_SCLK,
+ sclk_min,
+ sclk_max,
+ false);
if (ret)
return ret;
if (fclk_min && fclk_max) {
ret = yellow_carp_set_soft_freq_limited_range(smu,
- SMU_FCLK,
- fclk_min,
- fclk_max);
+ SMU_FCLK,
+ fclk_min,
+ fclk_max,
+ false);
if (ret)
return ret;
}
if (socclk_min && socclk_max) {
ret = yellow_carp_set_soft_freq_limited_range(smu,
- SMU_SOCCLK,
- socclk_min,
- socclk_max);
+ SMU_SOCCLK,
+ socclk_min,
+ socclk_max,
+ false);
if (ret)
return ret;
}
ret = yellow_carp_set_soft_freq_limited_range(smu,
SMU_VCLK,
vclk_min,
- vclk_max);
+ vclk_max,
+ false);
if (ret)
return ret;
}
ret = yellow_carp_set_soft_freq_limited_range(smu,
SMU_DCLK,
dclk_min,
- dclk_max);
+ dclk_max,
+ false);
if (ret)
return ret;
}
int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu,
enum smu_clk_type clk_type,
uint32_t min,
- uint32_t max)
+ uint32_t max,
+ bool automatic)
{
int ret = 0, clk_id = 0;
uint32_t param;
return clk_id;
if (max > 0) {
- param = (uint32_t)((clk_id << 16) | (max & 0xffff));
+ if (automatic)
+ param = (uint32_t)((clk_id << 16) | 0xffff);
+ else
+ param = (uint32_t)((clk_id << 16) | (max & 0xffff));
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
param, NULL);
if (ret)
}
if (min > 0) {
- param = (uint32_t)((clk_id << 16) | (min & 0xffff));
+ if (automatic)
+ param = (uint32_t)((clk_id << 16) | 0);
+ else
+ param = (uint32_t)((clk_id << 16) | (min & 0xffff));
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
param, NULL);
if (ret)
uint32_t dclk_min = 0, dclk_max = 0;
uint32_t fclk_min = 0, fclk_max = 0;
int ret = 0, i;
+ bool auto_level = false;
switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH:
dclk_max = dclk_table->max;
fclk_min = fclk_table->min;
fclk_max = fclk_table->max;
+ auto_level = true;
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
ret = smu_v14_0_set_soft_freq_limited_range(smu,
SMU_GFXCLK,
sclk_min,
- sclk_max);
+ sclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v14_0_set_soft_freq_limited_range(smu,
SMU_MCLK,
mclk_min,
- mclk_max);
+ mclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v14_0_set_soft_freq_limited_range(smu,
SMU_SOCCLK,
socclk_min,
- socclk_max);
+ socclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v14_0_set_soft_freq_limited_range(smu,
i ? SMU_VCLK1 : SMU_VCLK,
vclk_min,
- vclk_max);
+ vclk_max,
+ auto_level);
if (ret)
return ret;
}
ret = smu_v14_0_set_soft_freq_limited_range(smu,
i ? SMU_DCLK1 : SMU_DCLK,
dclk_min,
- dclk_max);
+ dclk_max,
+ auto_level);
if (ret)
return ret;
}
ret = smu_v14_0_set_soft_freq_limited_range(smu,
SMU_FCLK,
fclk_min,
- fclk_max);
+ fclk_max,
+ auto_level);
if (ret)
return ret;
ret = smu_v14_0_set_soft_freq_limited_range(smu,
clk_type,
min_freq,
- max_freq);
+ max_freq,
+ false);
break;
case SMU_DCEFCLK:
case SMU_PCIE: