[PATCH 066/138] drm/amd/powerplay: set defalut dpm table for smu

Huang Rui ray.huang at amd.com
Fri Jan 25 10:24:33 UTC 2019


From: Likun Gao <Likun.Gao at amd.com>

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 at amd.com>
Reviewed-by: Huang Rui <ray.huang at amd.com>
---
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c     |  18 +-
 drivers/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 47b4611..e03132c 100644
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
@@ -348,15 +348,6 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
 		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.
 	 */
@@ -394,6 +385,15 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
 		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.
 	 */
 	ret = smu_set_tool_table_location(smu);
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index 154f74e..24babb8 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 bfda4a3..66af3e6 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 4b756e8..bca4085 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.7.4



More information about the amd-gfx mailing list