Commit fff7e3e0 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

drm/amd/powerplay: correct force clock level related settings for vega20 (v2)

1. The min/max level is determined by soft_min_level/soft_max_level.
2. Vega20 comes with pptable v3 which has no vdd related
table(vdd_dep_on_socclk, vdd_dep_on_mclk) support.
3. Vega20 does not support separate fan feature control(enable or
disable).

v2: squash in fixes:
- bug fix for force dpm level settings
- fix wrong data type
Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7c2912a2
...@@ -1015,7 +1015,7 @@ static uint32_t vega20_find_lowest_dpm_level( ...@@ -1015,7 +1015,7 @@ static uint32_t vega20_find_lowest_dpm_level(
static uint32_t vega20_find_highest_dpm_level( static uint32_t vega20_find_highest_dpm_level(
struct vega20_single_dpm_table *table) struct vega20_single_dpm_table *table)
{ {
uint32_t i = 0; int i = 0;
PP_ASSERT_WITH_CODE(table != NULL, PP_ASSERT_WITH_CODE(table != NULL,
"[FindHighestDPMLevel] DPM Table does not exist!", "[FindHighestDPMLevel] DPM Table does not exist!",
...@@ -1409,14 +1409,20 @@ static int vega20_force_dpm_highest(struct pp_hwmgr *hwmgr) ...@@ -1409,14 +1409,20 @@ static int vega20_force_dpm_highest(struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data = struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); (struct vega20_hwmgr *)(hwmgr->backend);
uint32_t soft_level;
int ret = 0; int ret = 0;
data->smc_state_table.gfx_boot_level = soft_level = vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table));
data->smc_state_table.gfx_max_level =
vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table)); data->dpm_table.gfx_table.dpm_state.soft_min_level =
data->smc_state_table.mem_boot_level = data->dpm_table.gfx_table.dpm_state.soft_max_level =
data->smc_state_table.mem_max_level = data->dpm_table.gfx_table.dpm_levels[soft_level].value;
vega20_find_highest_dpm_level(&(data->dpm_table.mem_table));
soft_level = vega20_find_highest_dpm_level(&(data->dpm_table.mem_table));
data->dpm_table.mem_table.dpm_state.soft_min_level =
data->dpm_table.mem_table.dpm_state.soft_max_level =
data->dpm_table.mem_table.dpm_levels[soft_level].value;
ret = vega20_upload_dpm_min_level(hwmgr); ret = vega20_upload_dpm_min_level(hwmgr);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
...@@ -1435,14 +1441,20 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr) ...@@ -1435,14 +1441,20 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data = struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); (struct vega20_hwmgr *)(hwmgr->backend);
uint32_t soft_level;
int ret = 0; int ret = 0;
data->smc_state_table.gfx_boot_level = soft_level = vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
data->smc_state_table.gfx_max_level =
vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); data->dpm_table.gfx_table.dpm_state.soft_min_level =
data->smc_state_table.mem_boot_level = data->dpm_table.gfx_table.dpm_state.soft_max_level =
data->smc_state_table.mem_max_level = data->dpm_table.gfx_table.dpm_levels[soft_level].value;
vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table));
soft_level = vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table));
data->dpm_table.mem_table.dpm_state.soft_min_level =
data->dpm_table.mem_table.dpm_state.soft_max_level =
data->dpm_table.mem_table.dpm_levels[soft_level].value;
ret = vega20_upload_dpm_min_level(hwmgr); ret = vega20_upload_dpm_min_level(hwmgr);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
...@@ -1475,19 +1487,24 @@ static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr) ...@@ -1475,19 +1487,24 @@ static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
return 0; return 0;
} }
#if 0
static int vega20_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level, static int vega20_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level,
uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask) uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask)
{ {
struct phm_ppt_v2_information *table_info = struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
(struct phm_ppt_v2_information *)(hwmgr->pptable); struct vega20_single_dpm_table *gfx_dpm_table = &(data->dpm_table.gfx_table);
struct vega20_single_dpm_table *mem_dpm_table = &(data->dpm_table.mem_table);
struct vega20_single_dpm_table *soc_dpm_table = &(data->dpm_table.soc_table);
*sclk_mask = 0;
*mclk_mask = 0;
*soc_mask = 0;
if (table_info->vdd_dep_on_sclk->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL && if (gfx_dpm_table->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL &&
table_info->vdd_dep_on_socclk->count > VEGA20_UMD_PSTATE_SOCCLK_LEVEL && mem_dpm_table->count > VEGA20_UMD_PSTATE_MCLK_LEVEL &&
table_info->vdd_dep_on_mclk->count > VEGA20_UMD_PSTATE_MCLK_LEVEL) { soc_dpm_table->count > VEGA20_UMD_PSTATE_SOCCLK_LEVEL) {
*sclk_mask = VEGA20_UMD_PSTATE_GFXCLK_LEVEL; *sclk_mask = VEGA20_UMD_PSTATE_GFXCLK_LEVEL;
*soc_mask = VEGA20_UMD_PSTATE_SOCCLK_LEVEL;
*mclk_mask = VEGA20_UMD_PSTATE_MCLK_LEVEL; *mclk_mask = VEGA20_UMD_PSTATE_MCLK_LEVEL;
*soc_mask = VEGA20_UMD_PSTATE_SOCCLK_LEVEL;
} }
if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
...@@ -1495,24 +1512,30 @@ static int vega20_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_fo ...@@ -1495,24 +1512,30 @@ static int vega20_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_fo
} else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) { } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
*mclk_mask = 0; *mclk_mask = 0;
} else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
*sclk_mask = table_info->vdd_dep_on_sclk->count - 1; *sclk_mask = gfx_dpm_table->count - 1;
*soc_mask = table_info->vdd_dep_on_socclk->count - 1; *mclk_mask = mem_dpm_table->count - 1;
*mclk_mask = table_info->vdd_dep_on_mclk->count - 1; *soc_mask = soc_dpm_table->count - 1;
} }
return 0; return 0;
} }
#endif
static int vega20_force_clock_level(struct pp_hwmgr *hwmgr, static int vega20_force_clock_level(struct pp_hwmgr *hwmgr,
enum pp_clock_type type, uint32_t mask) enum pp_clock_type type, uint32_t mask)
{ {
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
uint32_t soft_min_level, soft_max_level;
int ret = 0; int ret = 0;
switch (type) { switch (type) {
case PP_SCLK: case PP_SCLK:
data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0; soft_min_level = mask ? (ffs(mask) - 1) : 0;
data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0; soft_max_level = mask ? (fls(mask) - 1) : 0;
data->dpm_table.gfx_table.dpm_state.soft_min_level =
data->dpm_table.gfx_table.dpm_levels[soft_min_level].value;
data->dpm_table.gfx_table.dpm_state.soft_max_level =
data->dpm_table.gfx_table.dpm_levels[soft_max_level].value;
ret = vega20_upload_dpm_min_level(hwmgr); ret = vega20_upload_dpm_min_level(hwmgr);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
...@@ -1526,8 +1549,13 @@ static int vega20_force_clock_level(struct pp_hwmgr *hwmgr, ...@@ -1526,8 +1549,13 @@ static int vega20_force_clock_level(struct pp_hwmgr *hwmgr,
break; break;
case PP_MCLK: case PP_MCLK:
data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0; soft_min_level = mask ? (ffs(mask) - 1) : 0;
data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0; soft_max_level = mask ? (fls(mask) - 1) : 0;
data->dpm_table.mem_table.dpm_state.soft_min_level =
data->dpm_table.mem_table.dpm_levels[soft_min_level].value;
data->dpm_table.mem_table.dpm_state.soft_max_level =
data->dpm_table.mem_table.dpm_levels[soft_max_level].value;
ret = vega20_upload_dpm_min_level(hwmgr); ret = vega20_upload_dpm_min_level(hwmgr);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
...@@ -1555,47 +1583,38 @@ static int vega20_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, ...@@ -1555,47 +1583,38 @@ static int vega20_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
enum amd_dpm_forced_level level) enum amd_dpm_forced_level level)
{ {
int ret = 0; int ret = 0;
#if 0 uint32_t sclk_mask, mclk_mask, soc_mask;
uint32_t sclk_mask = 0;
uint32_t mclk_mask = 0;
uint32_t soc_mask = 0;
#endif
switch (level) { switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH: case AMD_DPM_FORCED_LEVEL_HIGH:
ret = vega20_force_dpm_highest(hwmgr); ret = vega20_force_dpm_highest(hwmgr);
break; break;
case AMD_DPM_FORCED_LEVEL_LOW: case AMD_DPM_FORCED_LEVEL_LOW:
ret = vega20_force_dpm_lowest(hwmgr); ret = vega20_force_dpm_lowest(hwmgr);
break; break;
case AMD_DPM_FORCED_LEVEL_AUTO: case AMD_DPM_FORCED_LEVEL_AUTO:
ret = vega20_unforce_dpm_levels(hwmgr); ret = vega20_unforce_dpm_levels(hwmgr);
break; break;
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
#if 0
ret = vega20_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask); ret = vega20_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask);
if (ret) if (ret)
return ret; return ret;
vega20_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask); vega20_force_clock_level(hwmgr, PP_SCLK, 1 << sclk_mask);
vega20_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask); vega20_force_clock_level(hwmgr, PP_MCLK, 1 << mclk_mask);
#endif
break; break;
case AMD_DPM_FORCED_LEVEL_MANUAL: case AMD_DPM_FORCED_LEVEL_MANUAL:
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
default: default:
break; break;
} }
#if 0
if (!ret) {
if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
vega20_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE);
else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
vega20_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_AUTO);
}
#endif
return ret; return ret;
} }
......
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