diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0076-drm-amd-powerplay-correct-force-clock-level-related-.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0076-drm-amd-powerplay-correct-force-clock-level-related-.patch | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0076-drm-amd-powerplay-correct-force-clock-level-related-.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0076-drm-amd-powerplay-correct-force-clock-level-related-.patch new file mode 100644 index 00000000..5f9b9c06 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0076-drm-amd-powerplay-correct-force-clock-level-related-.patch @@ -0,0 +1,234 @@ +From 5d36fe6a46feedb1a92b94ec97d7734cd52c0516 Mon Sep 17 00:00:00 2001 +From: Evan Quan <evan.quan@amd.com> +Date: Tue, 8 May 2018 18:27:03 +0800 +Subject: [PATCH 0076/2940] 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: Evan Quan <evan.quan@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 109 ++++++++++-------- + 1 file changed, 64 insertions(+), 45 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +index a82a3df0e8d9..289e3ee2006d 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +@@ -1015,7 +1015,7 @@ static uint32_t vega20_find_lowest_dpm_level( + static uint32_t vega20_find_highest_dpm_level( + struct vega20_single_dpm_table *table) + { +- uint32_t i = 0; ++ int i = 0; + + PP_ASSERT_WITH_CODE(table != NULL, + "[FindHighestDPMLevel] DPM Table does not exist!", +@@ -1409,14 +1409,20 @@ static int vega20_force_dpm_highest(struct pp_hwmgr *hwmgr) + { + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); ++ uint32_t soft_level; + int ret = 0; + +- data->smc_state_table.gfx_boot_level = +- data->smc_state_table.gfx_max_level = +- vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table)); +- data->smc_state_table.mem_boot_level = +- data->smc_state_table.mem_max_level = +- vega20_find_highest_dpm_level(&(data->dpm_table.mem_table)); ++ soft_level = vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table)); ++ ++ data->dpm_table.gfx_table.dpm_state.soft_min_level = ++ data->dpm_table.gfx_table.dpm_state.soft_max_level = ++ data->dpm_table.gfx_table.dpm_levels[soft_level].value; ++ ++ 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); + PP_ASSERT_WITH_CODE(!ret, +@@ -1435,14 +1441,20 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr) + { + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); ++ uint32_t soft_level; + int ret = 0; + +- data->smc_state_table.gfx_boot_level = +- data->smc_state_table.gfx_max_level = +- vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); +- data->smc_state_table.mem_boot_level = +- data->smc_state_table.mem_max_level = +- vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table)); ++ soft_level = vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); ++ ++ data->dpm_table.gfx_table.dpm_state.soft_min_level = ++ data->dpm_table.gfx_table.dpm_state.soft_max_level = ++ data->dpm_table.gfx_table.dpm_levels[soft_level].value; ++ ++ 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); + PP_ASSERT_WITH_CODE(!ret, +@@ -1475,19 +1487,24 @@ static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr) + return 0; + } + +-#if 0 + 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) + { +- struct phm_ppt_v2_information *table_info = +- (struct phm_ppt_v2_information *)(hwmgr->pptable); ++ struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); ++ 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 && +- table_info->vdd_dep_on_socclk->count > VEGA20_UMD_PSTATE_SOCCLK_LEVEL && +- table_info->vdd_dep_on_mclk->count > VEGA20_UMD_PSTATE_MCLK_LEVEL) { ++ if (gfx_dpm_table->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL && ++ mem_dpm_table->count > VEGA20_UMD_PSTATE_MCLK_LEVEL && ++ soc_dpm_table->count > VEGA20_UMD_PSTATE_SOCCLK_LEVEL) { + *sclk_mask = VEGA20_UMD_PSTATE_GFXCLK_LEVEL; +- *soc_mask = VEGA20_UMD_PSTATE_SOCCLK_LEVEL; + *mclk_mask = VEGA20_UMD_PSTATE_MCLK_LEVEL; ++ *soc_mask = VEGA20_UMD_PSTATE_SOCCLK_LEVEL; + } + + 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 + } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) { + *mclk_mask = 0; + } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { +- *sclk_mask = table_info->vdd_dep_on_sclk->count - 1; +- *soc_mask = table_info->vdd_dep_on_socclk->count - 1; +- *mclk_mask = table_info->vdd_dep_on_mclk->count - 1; ++ *sclk_mask = gfx_dpm_table->count - 1; ++ *mclk_mask = mem_dpm_table->count - 1; ++ *soc_mask = soc_dpm_table->count - 1; + } ++ + return 0; + } +-#endif + + static int vega20_force_clock_level(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, uint32_t mask) + { + struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); ++ uint32_t soft_min_level, soft_max_level; + int ret = 0; + + switch (type) { + case PP_SCLK: +- data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0; +- data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0; ++ soft_min_level = mask ? (ffs(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); + PP_ASSERT_WITH_CODE(!ret, +@@ -1526,8 +1549,13 @@ static int vega20_force_clock_level(struct pp_hwmgr *hwmgr, + break; + + case PP_MCLK: +- data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0; +- data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0; ++ soft_min_level = mask ? (ffs(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); + PP_ASSERT_WITH_CODE(!ret, +@@ -1555,47 +1583,38 @@ static int vega20_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, + enum amd_dpm_forced_level level) + { + int ret = 0; +-#if 0 +- uint32_t sclk_mask = 0; +- uint32_t mclk_mask = 0; +- uint32_t soc_mask = 0; +-#endif ++ uint32_t sclk_mask, mclk_mask, soc_mask; + + switch (level) { + case AMD_DPM_FORCED_LEVEL_HIGH: + ret = vega20_force_dpm_highest(hwmgr); + break; ++ + case AMD_DPM_FORCED_LEVEL_LOW: + ret = vega20_force_dpm_lowest(hwmgr); + break; ++ + case AMD_DPM_FORCED_LEVEL_AUTO: + ret = vega20_unforce_dpm_levels(hwmgr); + break; ++ + case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: + case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: + case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: + case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: +-#if 0 + ret = vega20_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask); + if (ret) + return ret; +- vega20_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask); +- vega20_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask); +-#endif ++ vega20_force_clock_level(hwmgr, PP_SCLK, 1 << sclk_mask); ++ vega20_force_clock_level(hwmgr, PP_MCLK, 1 << mclk_mask); + break; ++ + case AMD_DPM_FORCED_LEVEL_MANUAL: + case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: + default: + 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; + } + +-- +2.17.1 + |