aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1395-drm-amd-powerplay-set-defalut-dpm-table-for-smu.patch
diff options
context:
space:
mode:
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.patch384
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
+