mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 00:45:13 +07:00
drm/amd/powerplay: add get_max_sustainable_clock function
This patch adds get_max_sustainable_clock function for smu11. Signed-off-by: Huang Rui <ray.huang@amd.com> Reviewed-by: Kevin Wang <Kevin1.Wang@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
86ac880307
commit
7457cf0254
@ -393,6 +393,10 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_init_max_sustainable_clocks(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_populate_umd_state_clk(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -539,6 +543,11 @@ static int smu_hw_fini(void *handle)
|
||||
return -EINVAL;
|
||||
kfree(table_context->driver_pptable);
|
||||
|
||||
if (table_context->max_sustainable_clocks) {
|
||||
kfree(table_context->max_sustainable_clocks);
|
||||
table_context->max_sustainable_clocks = NULL;
|
||||
}
|
||||
|
||||
ret = smu_fini_fb_allocations(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -158,6 +158,7 @@ struct smu_table_context
|
||||
void *power_play_table;
|
||||
uint32_t power_play_table_size;
|
||||
|
||||
void *max_sustainable_clocks;
|
||||
struct smu_bios_boot_up_values boot_values;
|
||||
void *driver_pptable;
|
||||
struct smu_table *tables;
|
||||
@ -253,6 +254,7 @@ struct smu_funcs
|
||||
int (*notify_display_change)(struct smu_context *smu);
|
||||
int (*get_power_limit)(struct smu_context *smu);
|
||||
int (*get_current_clk_freq)(struct smu_context *smu, uint32_t clk_id, uint32_t *value);
|
||||
int (*init_max_sustainable_clocks)(struct smu_context *smu);
|
||||
};
|
||||
|
||||
#define smu_init_microcode(smu) \
|
||||
@ -297,6 +299,8 @@ struct smu_funcs
|
||||
((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0)
|
||||
#define smu_system_features_control(smu, en) \
|
||||
((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
|
||||
#define smu_init_max_sustainable_clocks(smu) \
|
||||
((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
|
||||
#define smu_send_smc_msg(smu, msg) \
|
||||
((smu)->funcs->send_smc_msg? (smu)->funcs->send_smc_msg((smu), (msg)) : 0)
|
||||
#define smu_send_smc_msg_with_param(smu, msg, param) \
|
||||
|
@ -36,6 +36,14 @@
|
||||
#define smnMP0_FW_INTF 0x30101c0
|
||||
#define smnMP1_PUB_CTRL 0x3010b14
|
||||
|
||||
struct smu_11_0_max_sustainable_clocks {
|
||||
uint32_t display_clock;
|
||||
uint32_t phy_clock;
|
||||
uint32_t pixel_clock;
|
||||
uint32_t uclock;
|
||||
uint32_t dcef_clock;
|
||||
uint32_t soc_clock;
|
||||
};
|
||||
|
||||
struct smu_11_0_dpm_table {
|
||||
uint32_t min; /* MHz */
|
||||
|
@ -738,6 +738,119 @@ static int smu_v11_0_notify_display_change(struct smu_context *smu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
|
||||
PPCLK_e clock_select)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq,
|
||||
clock_select << 16);
|
||||
if (ret) {
|
||||
pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = smu_read_smc_arg(smu, clock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (*clock != 0)
|
||||
return 0;
|
||||
|
||||
/* if DC limit is zero, return AC limit */
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
|
||||
clock_select << 16);
|
||||
if (ret) {
|
||||
pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = smu_read_smc_arg(smu, clock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
|
||||
{
|
||||
struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks;
|
||||
int ret = 0;
|
||||
|
||||
max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks),
|
||||
GFP_KERNEL);
|
||||
smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks;
|
||||
|
||||
max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100;
|
||||
max_sustainable_clocks->soc_clock = smu->smu_table.boot_values.socclk / 100;
|
||||
max_sustainable_clocks->dcef_clock = smu->smu_table.boot_values.dcefclk / 100;
|
||||
max_sustainable_clocks->display_clock = 0xFFFFFFFF;
|
||||
max_sustainable_clocks->phy_clock = 0xFFFFFFFF;
|
||||
max_sustainable_clocks->pixel_clock = 0xFFFFFFFF;
|
||||
|
||||
if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
|
||||
ret = smu_v11_0_get_max_sustainable_clock(smu,
|
||||
&(max_sustainable_clocks->uclock),
|
||||
PPCLK_UCLK);
|
||||
if (ret) {
|
||||
pr_err("[%s] failed to get max UCLK from SMC!",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
|
||||
ret = smu_v11_0_get_max_sustainable_clock(smu,
|
||||
&(max_sustainable_clocks->soc_clock),
|
||||
PPCLK_SOCCLK);
|
||||
if (ret) {
|
||||
pr_err("[%s] failed to get max SOCCLK from SMC!",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
|
||||
ret = smu_v11_0_get_max_sustainable_clock(smu,
|
||||
&(max_sustainable_clocks->dcef_clock),
|
||||
PPCLK_DCEFCLK);
|
||||
if (ret) {
|
||||
pr_err("[%s] failed to get max DCEFCLK from SMC!",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = smu_v11_0_get_max_sustainable_clock(smu,
|
||||
&(max_sustainable_clocks->display_clock),
|
||||
PPCLK_DISPCLK);
|
||||
if (ret) {
|
||||
pr_err("[%s] failed to get max DISPCLK from SMC!",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
ret = smu_v11_0_get_max_sustainable_clock(smu,
|
||||
&(max_sustainable_clocks->phy_clock),
|
||||
PPCLK_PHYCLK);
|
||||
if (ret) {
|
||||
pr_err("[%s] failed to get max PHYCLK from SMC!",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
ret = smu_v11_0_get_max_sustainable_clock(smu,
|
||||
&(max_sustainable_clocks->pixel_clock),
|
||||
PPCLK_PIXCLK);
|
||||
if (ret) {
|
||||
pr_err("[%s] failed to get max PIXCLK from SMC!",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_sustainable_clocks->soc_clock < max_sustainable_clocks->uclock)
|
||||
max_sustainable_clocks->uclock = max_sustainable_clocks->soc_clock;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_v11_0_get_power_limit(struct smu_context *smu)
|
||||
{
|
||||
int ret;
|
||||
@ -810,6 +923,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
|
||||
.notify_display_change = smu_v11_0_notify_display_change,
|
||||
.get_power_limit = smu_v11_0_get_power_limit,
|
||||
.get_current_clk_freq = smu_v11_0_get_current_clk_freq,
|
||||
.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
|
||||
};
|
||||
|
||||
void smu_v11_0_set_smu_funcs(struct smu_context *smu)
|
||||
|
Loading…
Reference in New Issue
Block a user