Commit 0de94acf authored by Huang Rui's avatar Huang Rui Committed by Alex Deucher

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: default avatarHuang Rui <ray.huang@amd.com>
Reviewed-by: default avatarKevin Wang <kevin1.wang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 54b998ca
......@@ -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) \
......
......@@ -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;
......
......@@ -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,
};
......
......@@ -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;
}
}
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment