1
0
Fork 0

drm/amd/powerplay: introduce smu clk type to handle ppclk for each asic

This patch introduces new smu clk type, it's to handle the different ppclk
defines for each asic with the same smu ip.

Signed-off-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Kevin Wang <kevin1.wang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
alistair/sunxi64-5.4-dsi
Huang Rui 2019-03-24 19:22:07 +08:00 committed by Alex Deucher
parent 54b998ca8d
commit 0de94acf90
5 changed files with 113 additions and 35 deletions

View File

@ -227,6 +227,22 @@ enum smu_message_type
SMU_MSG_MAX_COUNT,
};
enum smu_clk_type
{
SMU_GFXCLK,
SMU_VCLK,
SMU_DCLK,
SMU_ECLK,
SMU_SOCCLK,
SMU_UCLK,
SMU_DCEFCLK,
SMU_DISPCLK,
SMU_PIXCLK,
SMU_PHYCLK,
SMU_FCLK,
SMU_CLK_COUNT,
};
enum smu_memory_pool_size
{
SMU_MEMORY_POOL_SIZE_ZERO = 0,
@ -420,6 +436,7 @@ struct pptable_funcs {
int (*check_powerplay_table)(struct smu_context *smu);
int (*append_powerplay_table)(struct smu_context *smu);
int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index);
int (*get_smu_clk_index)(struct smu_context *smu, uint32_t index);
int (*run_afll_btc)(struct smu_context *smu);
int (*get_allowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num);
enum amd_pm_state_type (*get_current_power_state)(struct smu_context *smu);
@ -510,7 +527,7 @@ struct smu_funcs
int (*notify_display_change)(struct smu_context *smu);
int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool def);
int (*set_power_limit)(struct smu_context *smu, uint32_t n);
int (*get_current_clk_freq)(struct smu_context *smu, uint32_t clk_id, uint32_t *value);
int (*get_current_clk_freq)(struct smu_context *smu, enum smu_clk_type clk_id, uint32_t *value);
int (*init_max_sustainable_clocks)(struct smu_context *smu);
int (*start_thermal_control)(struct smu_context *smu);
int (*read_sensor)(struct smu_context *smu, enum amd_pp_sensors sensor,
@ -704,6 +721,8 @@ struct smu_funcs
#define smu_msg_get_index(smu, msg) \
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL)
#define smu_clk_get_index(smu, msg) \
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_clk_index? (smu)->ppt_funcs->get_smu_clk_index((smu), (msg)) : -EINVAL) : -EINVAL)
#define smu_run_afll_btc(smu) \
((smu)->ppt_funcs? ((smu)->ppt_funcs->run_afll_btc? (smu)->ppt_funcs->run_afll_btc((smu)) : 0) : 0)
#define smu_get_allowed_feature_mask(smu, feature_mask, num) \

View File

@ -40,6 +40,9 @@
#define TEMP_RANGE_MIN (0)
#define TEMP_RANGE_MAX (80 * 1000)
#define CLK_MAP(clk, index) \
[SMU_##clk] = index
struct smu_11_0_max_sustainable_clocks {
uint32_t display_clock;
uint32_t phy_clock;

View File

@ -99,6 +99,18 @@ static int navi10_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(PrepareMp1ForShutdown, PPSMC_MSG_PrepareMp1ForShutdown),
};
static int navi10_clk_map[SMU_CLK_COUNT] = {
CLK_MAP(GFXCLK, PPCLK_GFXCLK),
CLK_MAP(SOCCLK, PPCLK_SOCCLK),
CLK_MAP(UCLK, PPCLK_UCLK),
CLK_MAP(DCLK, PPCLK_DCLK),
CLK_MAP(VCLK, PPCLK_VCLK),
CLK_MAP(DCEFCLK, PPCLK_DCEFCLK),
CLK_MAP(DISPCLK, PPCLK_DISPCLK),
CLK_MAP(PIXCLK, PPCLK_PIXCLK),
CLK_MAP(PHYCLK, PPCLK_PHYCLK),
};
static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
{
int val;
@ -112,6 +124,19 @@ static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
return val;
}
static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index)
{
int val;
if (index >= SMU_CLK_COUNT)
return -EINVAL;
val = navi10_clk_map[index];
if (val >= PPCLK_COUNT)
return -EINVAL;
return val;
}
#define FEATURE_MASK(feature) (1UL << feature)
static int
navi10_get_allowed_feature_mask(struct smu_context *smu,
@ -327,6 +352,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.check_powerplay_table = navi10_check_powerplay_table,
.append_powerplay_table = navi10_append_powerplay_table,
.get_smu_msg_index = navi10_get_smu_msg_index,
.get_smu_clk_index = navi10_get_smu_clk_index,
.get_allowed_feature_mask = navi10_get_allowed_feature_mask,
.set_default_dpm_table = navi10_set_default_dpm_table,
};

View File

@ -920,14 +920,14 @@ static int smu_v11_0_notify_display_change(struct smu_context *smu)
static int
smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
PPCLK_e clock_select)
enum smu_clk_type clock_select)
{
int ret = 0;
if (!smu->pm_enabled)
return ret;
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq,
clock_select << 16);
smu_clk_get_index(smu, clock_select) << 16);
if (ret) {
pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!");
return ret;
@ -942,7 +942,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
/* if DC limit is zero, return AC limit */
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
clock_select << 16);
smu_clk_get_index(smu, clock_select) << 16);
if (ret) {
pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!");
return ret;
@ -972,7 +972,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
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);
SMU_UCLK);
if (ret) {
pr_err("[%s] failed to get max UCLK from SMC!",
__func__);
@ -983,7 +983,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
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);
SMU_SOCCLK);
if (ret) {
pr_err("[%s] failed to get max SOCCLK from SMC!",
__func__);
@ -994,7 +994,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
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);
SMU_DCEFCLK);
if (ret) {
pr_err("[%s] failed to get max DCEFCLK from SMC!",
__func__);
@ -1003,7 +1003,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
ret = smu_v11_0_get_max_sustainable_clock(smu,
&(max_sustainable_clocks->display_clock),
PPCLK_DISPCLK);
SMU_DISPCLK);
if (ret) {
pr_err("[%s] failed to get max DISPCLK from SMC!",
__func__);
@ -1011,7 +1011,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
}
ret = smu_v11_0_get_max_sustainable_clock(smu,
&(max_sustainable_clocks->phy_clock),
PPCLK_PHYCLK);
SMU_PHYCLK);
if (ret) {
pr_err("[%s] failed to get max PHYCLK from SMC!",
__func__);
@ -1019,7 +1019,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
}
ret = smu_v11_0_get_max_sustainable_clock(smu,
&(max_sustainable_clocks->pixel_clock),
PPCLK_PIXCLK);
SMU_PIXCLK);
if (ret) {
pr_err("[%s] failed to get max PIXCLK from SMC!",
__func__);
@ -1086,16 +1086,18 @@ static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
return ret;
}
static int smu_v11_0_get_current_clk_freq(struct smu_context *smu, uint32_t clk_id, uint32_t *value)
static int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
enum smu_clk_type clk_id,
uint32_t *value)
{
int ret = 0;
uint32_t freq;
if (clk_id >= PPCLK_COUNT || !value)
if (clk_id >= SMU_CLK_COUNT || !value)
return -EINVAL;
ret = smu_send_smc_msg_with_param(smu,
SMU_MSG_GetDpmClockFreq, (clk_id << 16));
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDpmClockFreq,
(smu_clk_get_index(smu, clk_id) << 16));
if (ret)
return ret;
@ -1381,11 +1383,11 @@ static int smu_v11_0_read_sensor(struct smu_context *smu,
*size = 4;
break;
case AMDGPU_PP_SENSOR_GFX_MCLK:
ret = smu_get_current_clk_freq(smu, PPCLK_UCLK, (uint32_t *)data);
ret = smu_get_current_clk_freq(smu, SMU_UCLK, (uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_GFX_SCLK:
ret = smu_get_current_clk_freq(smu, PPCLK_GFXCLK, (uint32_t *)data);
ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, (uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
@ -1432,7 +1434,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
{
enum amd_pp_clock_type clk_type = clock_req->clock_type;
int ret = 0;
PPCLK_e clk_select = 0;
enum smu_clk_type clk_select = 0;
uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
if (!smu->pm_enabled)
@ -1440,16 +1442,16 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
switch (clk_type) {
case amd_pp_dcef_clock:
clk_select = PPCLK_DCEFCLK;
clk_select = SMU_DCEFCLK;
break;
case amd_pp_disp_clock:
clk_select = PPCLK_DISPCLK;
clk_select = SMU_DISPCLK;
break;
case amd_pp_pixel_clock:
clk_select = PPCLK_PIXCLK;
clk_select = SMU_PIXCLK;
break;
case amd_pp_phy_clock:
clk_select = PPCLK_PHYCLK;
clk_select = SMU_PHYCLK;
break;
default:
pr_info("[%s] Invalid Clock Type!", __func__);
@ -1461,7 +1463,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
goto failed;
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
(clk_select << 16) | clk_freq);
(smu_clk_get_index(smu, clk_select) << 16) | clk_freq);
}
failed:
@ -1575,14 +1577,14 @@ static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
static int smu_v11_0_get_clock_ranges(struct smu_context *smu,
uint32_t *clock,
PPCLK_e clock_select,
enum smu_clk_type clock_select,
bool max)
{
int ret;
*clock = 0;
if (max) {
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
(clock_select << 16));
smu_clk_get_index(smu, clock_select) << 16);
if (ret) {
pr_err("[GetClockRanges] Failed to get max clock from SMC!\n");
return ret;
@ -1590,7 +1592,7 @@ static int smu_v11_0_get_clock_ranges(struct smu_context *smu,
smu_read_smc_arg(smu, clock);
} else {
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq,
(clock_select << 16));
smu_clk_get_index(smu, clock_select) << 16);
if (ret) {
pr_err("[GetClockRanges] Failed to get min clock from SMC!\n");
return ret;
@ -1612,15 +1614,15 @@ static uint32_t smu_v11_0_dpm_get_sclk(struct smu_context *smu, bool low)
}
if (low) {
ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, PPCLK_GFXCLK, false);
ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, SMU_GFXCLK, false);
if (ret) {
pr_err("[GetSclks]: fail to get min PPCLK_GFXCLK\n");
pr_err("[GetSclks]: fail to get min SMU_GFXCLK\n");
return ret;
}
} else {
ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, PPCLK_GFXCLK, true);
ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, SMU_GFXCLK, true);
if (ret) {
pr_err("[GetSclks]: fail to get max PPCLK_GFXCLK\n");
pr_err("[GetSclks]: fail to get max SMU_GFXCLK\n");
return ret;
}
}
@ -1639,15 +1641,15 @@ static uint32_t smu_v11_0_dpm_get_mclk(struct smu_context *smu, bool low)
}
if (low) {
ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, PPCLK_UCLK, false);
ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, SMU_UCLK, false);
if (ret) {
pr_err("[GetMclks]: fail to get min PPCLK_UCLK\n");
pr_err("[GetMclks]: fail to get min SMU_UCLK\n");
return ret;
}
} else {
ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, PPCLK_GFXCLK, true);
ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, SMU_GFXCLK, true);
if (ret) {
pr_err("[GetMclks]: fail to get max PPCLK_UCLK\n");
pr_err("[GetMclks]: fail to get max SMU_UCLK\n");
return ret;
}
}

View File

@ -139,6 +139,33 @@ static int vega20_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(GetAVFSVoltageByDpm),
};
static int vega20_clk_map[SMU_CLK_COUNT] = {
CLK_MAP(GFXCLK, PPCLK_GFXCLK),
CLK_MAP(VCLK, PPCLK_VCLK),
CLK_MAP(DCLK, PPCLK_DCLK),
CLK_MAP(ECLK, PPCLK_ECLK),
CLK_MAP(SOCCLK, PPCLK_SOCCLK),
CLK_MAP(UCLK, PPCLK_UCLK),
CLK_MAP(DCEFCLK, PPCLK_DCEFCLK),
CLK_MAP(DISPCLK, PPCLK_DISPCLK),
CLK_MAP(PIXCLK, PPCLK_PIXCLK),
CLK_MAP(PHYCLK, PPCLK_PHYCLK),
CLK_MAP(FCLK, PPCLK_FCLK),
};
static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index)
{
int val;
if (index >= SMU_CLK_COUNT)
return -EINVAL;
val = vega20_clk_map[index];
if (val >= PPCLK_COUNT)
return -EINVAL;
return val;
}
static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index)
{
int val;
@ -776,7 +803,7 @@ static int vega20_print_clk_levels(struct smu_context *smu,
switch (type) {
case PP_SCLK:
ret = smu_get_current_clk_freq(smu, PPCLK_GFXCLK, &now);
ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, &now);
if (ret) {
pr_err("Attempt to get current gfx clk Failed!");
return ret;
@ -797,7 +824,7 @@ static int vega20_print_clk_levels(struct smu_context *smu,
break;
case PP_MCLK:
ret = smu_get_current_clk_freq(smu, PPCLK_UCLK, &now);
ret = smu_get_current_clk_freq(smu, SMU_UCLK, &now);
if (ret) {
pr_err("Attempt to get current mclk Failed!");
return ret;
@ -2847,6 +2874,7 @@ static const struct pptable_funcs vega20_ppt_funcs = {
.check_powerplay_table = vega20_check_powerplay_table,
.append_powerplay_table = vega20_append_powerplay_table,
.get_smu_msg_index = vega20_get_smu_msg_index,
.get_smu_clk_index = vega20_get_smu_clk_index,
.run_afll_btc = vega20_run_btc_afll,
.get_allowed_feature_mask = vega20_get_allowed_feature_mask,
.get_current_power_state = vega20_get_current_power_state,