[PATCH 172/459] drm/amd/powerplay: introduce smu clk type to handle ppclk for each asic

Alex Deucher alexdeucher at gmail.com
Mon Jun 17 19:26:37 UTC 2019


From: Huang Rui <ray.huang at amd.com>

This patch introduces new smu clk type, it's to handle the different ppclk
defines for each asic with the same smu ip.

Signed-off-by: Huang Rui <ray.huang at amd.com>
Reviewed-by: Kevin Wang <kevin1.wang at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h    | 21 +++++-
 drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h |  3 +
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c    | 26 ++++++++
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c     | 66 ++++++++++---------
 drivers/gpu/drm/amd/powerplay/vega20_ppt.c    | 32 ++++++++-
 5 files changed, 113 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index 2336597c09e0..65990dd700f0 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -227,6 +227,22 @@ enum smu_message_type
 	SMU_MSG_MAX_COUNT,
 };
 
+enum smu_clk_type
+{
+	SMU_GFXCLK,
+	SMU_VCLK,
+	SMU_DCLK,
+	SMU_ECLK,
+	SMU_SOCCLK,
+	SMU_UCLK,
+	SMU_DCEFCLK,
+	SMU_DISPCLK,
+	SMU_PIXCLK,
+	SMU_PHYCLK,
+	SMU_FCLK,
+	SMU_CLK_COUNT,
+};
+
 enum smu_memory_pool_size
 {
     SMU_MEMORY_POOL_SIZE_ZERO   = 0,
@@ -420,6 +436,7 @@ struct pptable_funcs {
 	int (*check_powerplay_table)(struct smu_context *smu);
 	int (*append_powerplay_table)(struct smu_context *smu);
 	int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index);
+	int (*get_smu_clk_index)(struct smu_context *smu, uint32_t index);
 	int (*run_afll_btc)(struct smu_context *smu);
 	int (*get_allowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num);
 	enum amd_pm_state_type (*get_current_power_state)(struct smu_context *smu);
@@ -510,7 +527,7 @@ struct smu_funcs
 	int (*notify_display_change)(struct smu_context *smu);
 	int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool def);
 	int (*set_power_limit)(struct smu_context *smu, uint32_t n);
-	int (*get_current_clk_freq)(struct smu_context *smu, uint32_t clk_id, uint32_t *value);
+	int (*get_current_clk_freq)(struct smu_context *smu, enum smu_clk_type clk_id, uint32_t *value);
 	int (*init_max_sustainable_clocks)(struct smu_context *smu);
 	int (*start_thermal_control)(struct smu_context *smu);
 	int (*read_sensor)(struct smu_context *smu, enum amd_pp_sensors sensor,
@@ -704,6 +721,8 @@ struct smu_funcs
 
 #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)
+#define smu_clk_get_index(smu, msg) \
+	((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_clk_index? (smu)->ppt_funcs->get_smu_clk_index((smu), (msg)) : -EINVAL) : -EINVAL)
 #define smu_run_afll_btc(smu) \
 	((smu)->ppt_funcs? ((smu)->ppt_funcs->run_afll_btc? (smu)->ppt_funcs->run_afll_btc((smu)) : 0) : 0)
 #define smu_get_allowed_feature_mask(smu, feature_mask, num) \
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index cd5e66b82ce1..cae6619d2df5 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -40,6 +40,9 @@
 #define TEMP_RANGE_MIN			(0)
 #define TEMP_RANGE_MAX			(80 * 1000)
 
+#define CLK_MAP(clk, index) \
+	[SMU_##clk] = index
+
 struct smu_11_0_max_sustainable_clocks {
 	uint32_t display_clock;
 	uint32_t phy_clock;
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 961f44e55f35..f45df244013f 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -99,6 +99,18 @@ static int navi10_message_map[SMU_MSG_MAX_COUNT] = {
 	MSG_MAP(PrepareMp1ForShutdown,		PPSMC_MSG_PrepareMp1ForShutdown),
 };
 
+static int navi10_clk_map[SMU_CLK_COUNT] = {
+	CLK_MAP(GFXCLK, PPCLK_GFXCLK),
+	CLK_MAP(SOCCLK, PPCLK_SOCCLK),
+	CLK_MAP(UCLK, PPCLK_UCLK),
+	CLK_MAP(DCLK, PPCLK_DCLK),
+	CLK_MAP(VCLK, PPCLK_VCLK),
+	CLK_MAP(DCEFCLK, PPCLK_DCEFCLK),
+	CLK_MAP(DISPCLK, PPCLK_DISPCLK),
+	CLK_MAP(PIXCLK, PPCLK_PIXCLK),
+	CLK_MAP(PHYCLK, PPCLK_PHYCLK),
+};
+
 static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
 {
 	int val;
@@ -112,6 +124,19 @@ static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
 	return val;
 }
 
+static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index)
+{
+	int val;
+	if (index >= SMU_CLK_COUNT)
+		return -EINVAL;
+
+	val = navi10_clk_map[index];
+	if (val >= PPCLK_COUNT)
+		return -EINVAL;
+
+	return val;
+}
+
 #define FEATURE_MASK(feature) (1UL << feature)
 static int
 navi10_get_allowed_feature_mask(struct smu_context *smu,
@@ -327,6 +352,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
 	.check_powerplay_table = navi10_check_powerplay_table,
 	.append_powerplay_table = navi10_append_powerplay_table,
 	.get_smu_msg_index = navi10_get_smu_msg_index,
+	.get_smu_clk_index = navi10_get_smu_clk_index,
 	.get_allowed_feature_mask = navi10_get_allowed_feature_mask,
 	.set_default_dpm_table = navi10_set_default_dpm_table,
 };
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index d0019b8a68f3..367c9795985c 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -920,14 +920,14 @@ static int smu_v11_0_notify_display_change(struct smu_context *smu)
 
 static int
 smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
-				    PPCLK_e clock_select)
+				    enum smu_clk_type clock_select)
 {
 	int ret = 0;
 
 	if (!smu->pm_enabled)
 		return ret;
 	ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq,
-					  clock_select << 16);
+					  smu_clk_get_index(smu, clock_select) << 16);
 	if (ret) {
 		pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!");
 		return ret;
@@ -942,7 +942,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
 
 	/* if DC limit is zero, return AC limit */
 	ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
-					  clock_select << 16);
+					  smu_clk_get_index(smu, clock_select) << 16);
 	if (ret) {
 		pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!");
 		return ret;
@@ -972,7 +972,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 	if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
 		ret = smu_v11_0_get_max_sustainable_clock(smu,
 							  &(max_sustainable_clocks->uclock),
-							  PPCLK_UCLK);
+							  SMU_UCLK);
 		if (ret) {
 			pr_err("[%s] failed to get max UCLK from SMC!",
 			       __func__);
@@ -983,7 +983,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 	if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
 		ret = smu_v11_0_get_max_sustainable_clock(smu,
 							  &(max_sustainable_clocks->soc_clock),
-							  PPCLK_SOCCLK);
+							  SMU_SOCCLK);
 		if (ret) {
 			pr_err("[%s] failed to get max SOCCLK from SMC!",
 			       __func__);
@@ -994,7 +994,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 	if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
 		ret = smu_v11_0_get_max_sustainable_clock(smu,
 							  &(max_sustainable_clocks->dcef_clock),
-							  PPCLK_DCEFCLK);
+							  SMU_DCEFCLK);
 		if (ret) {
 			pr_err("[%s] failed to get max DCEFCLK from SMC!",
 			       __func__);
@@ -1003,7 +1003,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 
 		ret = smu_v11_0_get_max_sustainable_clock(smu,
 							  &(max_sustainable_clocks->display_clock),
-							  PPCLK_DISPCLK);
+							  SMU_DISPCLK);
 		if (ret) {
 			pr_err("[%s] failed to get max DISPCLK from SMC!",
 			       __func__);
@@ -1011,7 +1011,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 		}
 		ret = smu_v11_0_get_max_sustainable_clock(smu,
 							  &(max_sustainable_clocks->phy_clock),
-							  PPCLK_PHYCLK);
+							  SMU_PHYCLK);
 		if (ret) {
 			pr_err("[%s] failed to get max PHYCLK from SMC!",
 			       __func__);
@@ -1019,7 +1019,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 		}
 		ret = smu_v11_0_get_max_sustainable_clock(smu,
 							  &(max_sustainable_clocks->pixel_clock),
-							  PPCLK_PIXCLK);
+							  SMU_PIXCLK);
 		if (ret) {
 			pr_err("[%s] failed to get max PIXCLK from SMC!",
 			       __func__);
@@ -1086,16 +1086,18 @@ static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
 	return ret;
 }
 
-static int smu_v11_0_get_current_clk_freq(struct smu_context *smu, uint32_t clk_id, uint32_t *value)
+static int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
+					  enum smu_clk_type clk_id,
+					  uint32_t *value)
 {
 	int ret = 0;
 	uint32_t freq;
 
-	if (clk_id >= PPCLK_COUNT || !value)
+	if (clk_id >= SMU_CLK_COUNT || !value)
 		return -EINVAL;
 
-	ret = smu_send_smc_msg_with_param(smu,
-			SMU_MSG_GetDpmClockFreq, (clk_id << 16));
+	ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDpmClockFreq,
+					  (smu_clk_get_index(smu, clk_id) << 16));
 	if (ret)
 		return ret;
 
@@ -1381,11 +1383,11 @@ static int smu_v11_0_read_sensor(struct smu_context *smu,
 		*size = 4;
 		break;
 	case AMDGPU_PP_SENSOR_GFX_MCLK:
-		ret = smu_get_current_clk_freq(smu, PPCLK_UCLK, (uint32_t *)data);
+		ret = smu_get_current_clk_freq(smu, SMU_UCLK, (uint32_t *)data);
 		*size = 4;
 		break;
 	case AMDGPU_PP_SENSOR_GFX_SCLK:
-		ret = smu_get_current_clk_freq(smu, PPCLK_GFXCLK, (uint32_t *)data);
+		ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, (uint32_t *)data);
 		*size = 4;
 		break;
 	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
@@ -1432,7 +1434,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
 {
 	enum amd_pp_clock_type clk_type = clock_req->clock_type;
 	int ret = 0;
-	PPCLK_e clk_select = 0;
+	enum smu_clk_type clk_select = 0;
 	uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
 
 	if (!smu->pm_enabled)
@@ -1440,16 +1442,16 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
 	if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
 		switch (clk_type) {
 		case amd_pp_dcef_clock:
-			clk_select = PPCLK_DCEFCLK;
+			clk_select = SMU_DCEFCLK;
 			break;
 		case amd_pp_disp_clock:
-			clk_select = PPCLK_DISPCLK;
+			clk_select = SMU_DISPCLK;
 			break;
 		case amd_pp_pixel_clock:
-			clk_select = PPCLK_PIXCLK;
+			clk_select = SMU_PIXCLK;
 			break;
 		case amd_pp_phy_clock:
-			clk_select = PPCLK_PHYCLK;
+			clk_select = SMU_PHYCLK;
 			break;
 		default:
 			pr_info("[%s] Invalid Clock Type!", __func__);
@@ -1461,7 +1463,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
 			goto failed;
 
 		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
-						  (clk_select << 16) | clk_freq);
+			(smu_clk_get_index(smu, clk_select) << 16) | clk_freq);
 	}
 
 failed:
@@ -1575,14 +1577,14 @@ static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
 
 static int smu_v11_0_get_clock_ranges(struct smu_context *smu,
 				      uint32_t *clock,
-				      PPCLK_e clock_select,
+				      enum smu_clk_type clock_select,
 				      bool max)
 {
 	int ret;
 	*clock = 0;
 	if (max) {
 		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
-					    (clock_select << 16));
+				smu_clk_get_index(smu, clock_select) << 16);
 		if (ret) {
 			pr_err("[GetClockRanges] Failed to get max clock from SMC!\n");
 			return ret;
@@ -1590,7 +1592,7 @@ static int smu_v11_0_get_clock_ranges(struct smu_context *smu,
 		smu_read_smc_arg(smu, clock);
 	} else {
 		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq,
-					    (clock_select << 16));
+				smu_clk_get_index(smu, clock_select) << 16);
 		if (ret) {
 			pr_err("[GetClockRanges] Failed to get min clock from SMC!\n");
 			return ret;
@@ -1612,15 +1614,15 @@ static uint32_t smu_v11_0_dpm_get_sclk(struct smu_context *smu, bool low)
 	}
 
 	if (low) {
-		ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, PPCLK_GFXCLK, false);
+		ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, SMU_GFXCLK, false);
 		if (ret) {
-			pr_err("[GetSclks]: fail to get min PPCLK_GFXCLK\n");
+			pr_err("[GetSclks]: fail to get min SMU_GFXCLK\n");
 			return ret;
 		}
 	} else {
-		ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, PPCLK_GFXCLK, true);
+		ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, SMU_GFXCLK, true);
 		if (ret) {
-			pr_err("[GetSclks]: fail to get max PPCLK_GFXCLK\n");
+			pr_err("[GetSclks]: fail to get max SMU_GFXCLK\n");
 			return ret;
 		}
 	}
@@ -1639,15 +1641,15 @@ static uint32_t smu_v11_0_dpm_get_mclk(struct smu_context *smu, bool low)
 	}
 
 	if (low) {
-		ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, PPCLK_UCLK, false);
+		ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, SMU_UCLK, false);
 		if (ret) {
-			pr_err("[GetMclks]: fail to get min PPCLK_UCLK\n");
+			pr_err("[GetMclks]: fail to get min SMU_UCLK\n");
 			return ret;
 		}
 	} else {
-		ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, PPCLK_GFXCLK, true);
+		ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, SMU_GFXCLK, true);
 		if (ret) {
-			pr_err("[GetMclks]: fail to get max PPCLK_UCLK\n");
+			pr_err("[GetMclks]: fail to get max SMU_UCLK\n");
 			return ret;
 		}
 	}
diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
index 7e6148ab134b..b3fc9c034aa0 100644
--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
@@ -139,6 +139,33 @@ static int vega20_message_map[SMU_MSG_MAX_COUNT] = {
 	MSG_MAP(GetAVFSVoltageByDpm),
 };
 
+static int vega20_clk_map[SMU_CLK_COUNT] = {
+	CLK_MAP(GFXCLK, PPCLK_GFXCLK),
+	CLK_MAP(VCLK, PPCLK_VCLK),
+	CLK_MAP(DCLK, PPCLK_DCLK),
+	CLK_MAP(ECLK, PPCLK_ECLK),
+	CLK_MAP(SOCCLK, PPCLK_SOCCLK),
+	CLK_MAP(UCLK, PPCLK_UCLK),
+	CLK_MAP(DCEFCLK, PPCLK_DCEFCLK),
+	CLK_MAP(DISPCLK, PPCLK_DISPCLK),
+	CLK_MAP(PIXCLK, PPCLK_PIXCLK),
+	CLK_MAP(PHYCLK, PPCLK_PHYCLK),
+	CLK_MAP(FCLK, PPCLK_FCLK),
+};
+
+static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index)
+{
+	int val;
+	if (index >= SMU_CLK_COUNT)
+		return -EINVAL;
+
+	val = vega20_clk_map[index];
+	if (val >= PPCLK_COUNT)
+		return -EINVAL;
+
+	return val;
+}
+
 static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index)
 {
 	int val;
@@ -776,7 +803,7 @@ static int vega20_print_clk_levels(struct smu_context *smu,
 
 	switch (type) {
 	case PP_SCLK:
-		ret = smu_get_current_clk_freq(smu, PPCLK_GFXCLK, &now);
+		ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, &now);
 		if (ret) {
 			pr_err("Attempt to get current gfx clk Failed!");
 			return ret;
@@ -797,7 +824,7 @@ static int vega20_print_clk_levels(struct smu_context *smu,
 		break;
 
 	case PP_MCLK:
-		ret = smu_get_current_clk_freq(smu, PPCLK_UCLK, &now);
+		ret = smu_get_current_clk_freq(smu, SMU_UCLK, &now);
 		if (ret) {
 			pr_err("Attempt to get current mclk Failed!");
 			return ret;
@@ -2847,6 +2874,7 @@ static const struct pptable_funcs vega20_ppt_funcs = {
 	.check_powerplay_table = vega20_check_powerplay_table,
 	.append_powerplay_table = vega20_append_powerplay_table,
 	.get_smu_msg_index = vega20_get_smu_msg_index,
+	.get_smu_clk_index = vega20_get_smu_clk_index,
 	.run_afll_btc = vega20_run_btc_afll,
 	.get_allowed_feature_mask = vega20_get_allowed_feature_mask,
 	.get_current_power_state = vega20_get_current_power_state,
-- 
2.20.1



More information about the amd-gfx mailing list