Skip to content

Commit

Permalink
drm/amdgpu/swsmu: add automatic parameter to set_soft_freq_range
Browse files Browse the repository at this point in the history
On chips that support it, you can specificy 0 and 0xffff for
min and max and the PMFW will use that to determine the optimal
min and max.  This enables optimal performance when the
user manually switches between performance levels using sysfs.
Previously we'd set soft min/max which could limit performance.

Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Alex Deucher committed Oct 15, 2024
1 parent 9f7e94a commit 3d73327
Show file tree
Hide file tree
Showing 21 changed files with 152 additions and 90 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ int smu_set_soft_freq_range(struct smu_context *smu,
ret = smu->ppt_funcs->set_soft_freq_limited_range(smu,
clk_type,
min,
max);
max,
false);

return ret;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,8 @@ struct pptable_funcs {
* @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.
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
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,
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/inc/smu_v12_0.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int smu_v12_0_set_default_dpm_tables(struct smu_context *smu);
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);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ int smu_v13_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
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,
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ int smu_v14_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
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,
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@ static int navi10_force_clk_levels(struct smu_context *smu,
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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,7 @@ static int sienna_cichlid_force_clk_levels(struct smu_context *smu,
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;
Expand Down
25 changes: 19 additions & 6 deletions drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1764,7 +1764,8 @@ int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c
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;
Expand All @@ -1779,15 +1780,21 @@ int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu,
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)
goto out;
}

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)
Expand Down Expand Up @@ -1855,6 +1862,7 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
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:
Expand All @@ -1874,6 +1882,7 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
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;
Expand Down Expand Up @@ -1906,13 +1915,15 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
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;
}
Expand All @@ -1921,7 +1932,8 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
ret = smu_v11_0_set_soft_freq_limited_range(smu,
SMU_MCLK,
mclk_min,
mclk_max);
mclk_max,
auto_level);
if (ret)
return ret;
}
Expand All @@ -1930,7 +1942,8 @@ int smu_v11_0_set_performance_level(struct smu_context *smu,
ret = smu_v11_0_set_soft_freq_limited_range(smu,
SMU_SOCCLK,
socclk_min,
socclk_max);
socclk_max,
auto_level);
if (ret)
return ret;
}
Expand Down
19 changes: 10 additions & 9 deletions drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1091,9 +1091,10 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,
}

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;

Expand Down Expand Up @@ -1299,7 +1300,7 @@ static int vangogh_force_dpm_limit_value(struct smu_context *smu, bool highest)
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;
}
Expand Down Expand Up @@ -1335,7 +1336,7 @@ static int vangogh_unforce_dpm_levels(struct smu_context *smu)
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;
Expand All @@ -1354,31 +1355,31 @@ static int vangogh_set_peak_clock_by_device(struct smu_context *smu)
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;

ret = vangogh_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_freq);
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;

ret = vangogh_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &vclk_freq);
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;

ret = vangogh_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &dclk_freq);
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;

Expand Down
14 changes: 7 additions & 7 deletions drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest)
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;
}
Expand Down Expand Up @@ -740,7 +740,7 @@ static int renoir_unforce_dpm_levels(struct smu_context *smu) {
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;
}
Expand Down Expand Up @@ -911,15 +911,15 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
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;

ret = renoir_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &uclk_freq);
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;

Expand Down Expand Up @@ -961,13 +961,13 @@ static int renior_set_dpm_profile_freq(struct smu_context *smu,
}

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;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ 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 ret = 0;

Expand Down
15 changes: 8 additions & 7 deletions drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1297,9 +1297,10 @@ static int aldebaran_set_performance_level(struct smu_context *smu,
}

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;
Expand Down Expand Up @@ -1328,7 +1329,7 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
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;
Expand All @@ -1348,7 +1349,7 @@ static int aldebaran_set_soft_freq_limited_range(struct smu_context *smu,
/* 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,
Expand Down Expand Up @@ -1422,7 +1423,7 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_
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:
Expand All @@ -1441,7 +1442,7 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_
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:
Expand Down
Loading

0 comments on commit 3d73327

Please sign in to comment.