diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1395-drm-amd-powerplay-set-defalut-dpm-table-for-smu.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1395-drm-amd-powerplay-set-defalut-dpm-table-for-smu.patch | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1395-drm-amd-powerplay-set-defalut-dpm-table-for-smu.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1395-drm-amd-powerplay-set-defalut-dpm-table-for-smu.patch new file mode 100644 index 00000000..2a2fe707 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1395-drm-amd-powerplay-set-defalut-dpm-table-for-smu.patch @@ -0,0 +1,384 @@ +From 05e7e00c96709c5974026e38dda8c48ad61dd618 Mon Sep 17 00:00:00 2001 +From: Likun Gao <Likun.Gao@amd.com> +Date: Thu, 20 Dec 2018 20:31:55 +0800 +Subject: [PATCH 1395/2940] drm/amd/powerplay: set defalut dpm table for smu + +Add smu_set_default_dpm_table function to set dpm table for smu11. +Modified the sequence to populate smc pptable, as it should be done after +related dpm feature is enabled. + +Signed-off-by: Likun Gao <Likun.Gao@amd.com> +Reviewed-by: Huang Rui <ray.huang@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 18 +- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 3 + + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 38 +-- + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 236 ++++++++++++++++++ + 4 files changed, 251 insertions(+), 44 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +index 47b46115a4f3..e03132c17f4e 100644 +--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +@@ -347,15 +347,6 @@ static int smu_smc_table_hw_init(struct smu_context *smu) + if (ret) + return ret; + +- /* +- * Set initialized values (get from vbios) to dpm tables context such as +- * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each +- * type of clks. +- */ +- ret = smu_populate_smc_pptable(smu); +- if (ret) +- return ret; +- + /* + * Send msg GetDriverIfVersion to check if the return value is equal + * with DRIVER_IF_VERSION of smc header. +@@ -393,6 +384,15 @@ static int smu_smc_table_hw_init(struct smu_context *smu) + if (ret) + return ret; + ++ /* ++ * Set initialized values (get from vbios) to dpm tables context such as ++ * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each ++ * type of clks. ++ */ ++ ret = smu_populate_smc_pptable(smu); ++ if (ret) ++ return ret; ++ + /* + * Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools. + */ +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index 154f74eb9081..24babb836a0c 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -208,6 +208,7 @@ struct pptable_funcs { + int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index); + int (*run_afll_btc)(struct smu_context *smu); + int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num); ++ int (*set_default_dpm_table)(struct smu_context *smu); + }; + + struct smu_funcs +@@ -313,6 +314,8 @@ struct smu_funcs + ((smu)->ppt_funcs->check_powerplay_table ? (smu)->ppt_funcs->check_powerplay_table((smu)) : 0) + #define smu_append_powerplay_table(smu) \ + ((smu)->ppt_funcs->append_powerplay_table ? (smu)->ppt_funcs->append_powerplay_table((smu)) : 0) ++#define smu_set_default_dpm_table(smu) \ ++ ((smu)->ppt_funcs->set_default_dpm_table ? (smu)->ppt_funcs->set_default_dpm_table((smu)) : 0) + + #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) +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index bfda4a30a14f..66af3e61d33a 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -525,43 +525,11 @@ static int smu_v11_0_parse_pptable(struct smu_context *smu) + + static int smu_v11_0_populate_smc_pptable(struct smu_context *smu) + { +- struct smu_dpm_context *smu_dpm = &smu->smu_dpm; +- +- PPTable_t *driver_ppt = (PPTable_t *)&(smu->smu_table.tables[TABLE_PPTABLE]); +- struct smu_11_0_dpm_context *dpm_context = (struct smu_11_0_dpm_context *)smu_dpm->dpm_context; +- +- if (dpm_context && driver_ppt) { +- dpm_context->dpm_tables.soc_table.min = driver_ppt->FreqTableSocclk[0]; +- dpm_context->dpm_tables.soc_table.max = driver_ppt->FreqTableSocclk[NUM_SOCCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.gfx_table.min = driver_ppt->FreqTableGfx[0]; +- dpm_context->dpm_tables.gfx_table.max = driver_ppt->FreqTableGfx[NUM_GFXCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.uclk_table.min = driver_ppt->FreqTableUclk[0]; +- dpm_context->dpm_tables.uclk_table.max = driver_ppt->FreqTableUclk[NUM_UCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.vclk_table.min = driver_ppt->FreqTableVclk[0]; +- dpm_context->dpm_tables.vclk_table.max = driver_ppt->FreqTableVclk[NUM_VCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.dclk_table.min = driver_ppt->FreqTableDclk[0]; +- dpm_context->dpm_tables.dclk_table.max = driver_ppt->FreqTableDclk[NUM_DCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.dcef_table.min = driver_ppt->FreqTableDcefclk[0]; +- dpm_context->dpm_tables.dcef_table.max = driver_ppt->FreqTableDcefclk[NUM_DCEFCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.pixel_table.min = driver_ppt->FreqTablePixclk[0]; +- dpm_context->dpm_tables.pixel_table.max = driver_ppt->FreqTablePixclk[NUM_PIXCLK_DPM_LEVELS - 1]; +- +- dpm_context->dpm_tables.display_table.min = driver_ppt->FreqTableDispclk[0]; +- dpm_context->dpm_tables.display_table.max = driver_ppt->FreqTableDispclk[NUM_DISPCLK_DPM_LEVELS - 1]; ++ int ret; + +- dpm_context->dpm_tables.phy_table.min = driver_ppt->FreqTablePhyclk[0]; +- dpm_context->dpm_tables.phy_table.max = driver_ppt->FreqTablePhyclk[NUM_PHYCLK_DPM_LEVELS - 1]; ++ ret = smu_set_default_dpm_table(smu); + +- return 0; +- } +- +- return -EINVAL; ++ return ret; + } + + static int smu_v11_0_copy_table_to_smc(struct smu_context *smu, +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +index 4b756e84115b..bca4085696d2 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +@@ -291,6 +291,241 @@ vega20_get_unallowed_feature_mask(struct smu_context *smu, + return 0; + } + ++static int ++vega20_set_single_dpm_table(struct smu_context *smu, ++ struct vega20_single_dpm_table *single_dpm_table, ++ PPCLK_e clk_id) ++{ ++ int ret = 0; ++ uint32_t i, num_of_levels, clk; ++ ++ ret = smu_send_smc_msg_with_param(smu, ++ SMU_MSG_GetDpmFreqByIndex, ++ (clk_id << 16 | 0xFF)); ++ if (ret) { ++ pr_err("[GetNumOfDpmLevel] failed to get dpm levels!"); ++ return ret; ++ } ++ ++ smu_read_smc_arg(smu, &num_of_levels); ++ if (!num_of_levels) { ++ pr_err("[GetNumOfDpmLevel] number of clk levels is invalid!"); ++ return -EINVAL; ++ } ++ ++ single_dpm_table->count = num_of_levels; ++ ++ for (i = 0; i < num_of_levels; i++) { ++ ret = smu_send_smc_msg_with_param(smu, ++ SMU_MSG_GetDpmFreqByIndex, ++ (clk_id << 16 | i)); ++ if (ret) { ++ pr_err("[GetDpmFreqByIndex] failed to get dpm freq by index!"); ++ return ret; ++ } ++ smu_read_smc_arg(smu, &clk); ++ if (!clk) { ++ pr_err("[GetDpmFreqByIndex] clk value is invalid!"); ++ return -EINVAL; ++ } ++ single_dpm_table->dpm_levels[i].value = clk; ++ single_dpm_table->dpm_levels[i].enabled = true; ++ } ++ return 0; ++} ++ ++static void vega20_init_single_dpm_state(struct vega20_dpm_state *dpm_state) ++{ ++ dpm_state->soft_min_level = 0x0; ++ dpm_state->soft_max_level = 0xffff; ++ dpm_state->hard_min_level = 0x0; ++ dpm_state->hard_max_level = 0xffff; ++} ++ ++static int vega20_set_default_dpm_table(struct smu_context *smu) ++{ ++ int ret; ++ ++ struct smu_dpm_context *smu_dpm = &smu->smu_dpm; ++ struct vega20_dpm_table *dpm_table = NULL; ++ struct vega20_single_dpm_table *single_dpm_table; ++ ++ dpm_table = smu_dpm->dpm_context; ++ ++ /* socclk */ ++ single_dpm_table = &(dpm_table->soc_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_SOCCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get socclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* gfxclk */ ++ single_dpm_table = &(dpm_table->gfx_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_GFXCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get gfxclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* memclk */ ++ single_dpm_table = &(dpm_table->mem_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_UCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get memclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++#if 0 ++ /* eclk */ ++ single_dpm_table = &(dpm_table->eclk_table); ++ ++ if (feature->fea_enabled[FEATURE_DPM_VCE_BIT]) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_ECLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get eclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.eclock / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* vclk */ ++ single_dpm_table = &(dpm_table->vclk_table); ++ ++ if (feature->fea_enabled[FEATURE_DPM_UVD_BIT]) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_VCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get vclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclock / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* dclk */ ++ single_dpm_table = &(dpm_table->dclk_table); ++ ++ if (feature->fea_enabled[FEATURE_DPM_UVD_BIT]) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_DCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get dclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclock / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++#endif ++ ++ /* dcefclk */ ++ single_dpm_table = &(dpm_table->dcef_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_DCEFCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get dcefclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* pixclk */ ++ single_dpm_table = &(dpm_table->pixel_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_PIXCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get pixclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 0; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* dispclk */ ++ single_dpm_table = &(dpm_table->display_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_DISPCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get dispclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 0; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* phyclk */ ++ single_dpm_table = &(dpm_table->phy_table); ++ ++ if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_PHYCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get phyclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 0; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ /* fclk */ ++ single_dpm_table = &(dpm_table->fclk_table); ++ ++ if (smu_feature_is_enabled(smu,FEATURE_DPM_FCLK_BIT)) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ PPCLK_FCLK); ++ if (ret) { ++ pr_err("[SetupDefaultDpmTable] failed to get fclk dpm levels!"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 0; ++ } ++ vega20_init_single_dpm_state(&(single_dpm_table->dpm_state)); ++ ++ return 0; ++} ++ + static const struct pptable_funcs vega20_ppt_funcs = { + .alloc_dpm_context = vega20_allocate_dpm_context, + .store_powerplay_table = vega20_store_powerplay_table, +@@ -299,6 +534,7 @@ static const struct pptable_funcs vega20_ppt_funcs = { + .get_smu_msg_index = vega20_get_smu_msg_index, + .run_afll_btc = vega20_run_btc_afll, + .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask, ++ .set_default_dpm_table = vega20_set_default_dpm_table, + }; + + void vega20_set_ppt_funcs(struct smu_context *smu) +-- +2.17.1 + |