[PATCH 098/138] drm/amd/powerplay: add interface to request display clock voltage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds interface to request display clock voltage, display will use it
to request current display clock voltage.

Signed-off-by: Huang Rui <ray.huang@xxxxxxx>
Reviewed-by: Alex Deucher <alexander.deucher@xxxxxxx>
Reviewed-by: Evan Quan <evan.quan@xxxxxxx>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c   | 17 ++++++---
 drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h     |  5 +++
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c          | 44 ++++++++++++++++++++++
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index c60722e..06d2b39 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -476,6 +476,10 @@ bool dm_pp_apply_clock_for_voltage_request(
 		ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
 			adev->powerplay.pp_handle,
 			&pp_clock_request);
+	else if (adev->smu.funcs &&
+		 adev->smu.funcs->display_clock_voltage_request)
+		ret = smu_display_clock_voltage_request(&adev->smu,
+							&pp_clock_request);
 	if (ret)
 		return false;
 	return true;
@@ -512,16 +516,19 @@ void pp_rv_set_display_requirement(struct pp_smu *pp,
 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 	struct pp_display_clock_request clock = {0};
 
-	if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
-		return;
-
 	clock.clock_type = amd_pp_dcf_clock;
 	clock.clock_freq_in_khz = req->hard_min_dcefclk_mhz * 1000;
-	pp_funcs->display_clock_voltage_request(pp_handle, &clock);
+	if (pp_funcs && pp_funcs->display_clock_voltage_request)
+		pp_funcs->display_clock_voltage_request(pp_handle, &clock);
+	else if (adev->smu.funcs && adev->smu.funcs->display_clock_voltage_request)
+		smu_display_clock_voltage_request(&adev->smu, &clock);
 
 	clock.clock_type = amd_pp_f_clock;
 	clock.clock_freq_in_khz = req->hard_min_fclk_mhz * 1000;
-	pp_funcs->display_clock_voltage_request(pp_handle, &clock);
+	if (pp_funcs && pp_funcs->display_clock_voltage_request)
+		pp_funcs->display_clock_voltage_request(pp_handle, &clock);
+	else if (adev->smu.funcs && adev->smu.funcs->display_clock_voltage_request)
+		smu_display_clock_voltage_request(&adev->smu, &clock);
 }
 
 void pp_rv_set_wm_ranges(struct pp_smu *pp,
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index 80d6615..82d5773 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -284,6 +284,9 @@ struct smu_funcs
 				 struct amd_pp_clocks *clocks);
 	int (*get_max_high_clocks)(struct smu_context *smu,
 				   struct amd_pp_simple_clock_info *clocks);
+	int (*display_clock_voltage_request)(struct smu_context *smu, struct
+					     pp_display_clock_request
+					     *clock_req);
 };
 
 #define smu_init_microcode(smu) \
@@ -393,6 +396,8 @@ struct smu_funcs
 	((smu)->ppt_funcs->get_clock_by_type_with_latency ? (smu)->ppt_funcs->get_clock_by_type_with_latency((smu), (type), (clocks)) : 0)
 #define smu_get_clock_by_type_with_voltage(smu, type, clocks) \
 	((smu)->ppt_funcs->get_clock_by_type_with_voltage ? (smu)->ppt_funcs->get_clock_by_type_with_voltage((smu), (type), (clocks)) : 0)
+#define smu_display_clock_voltage_request(smu, clock_req) \
+	((smu)->funcs->display_clock_voltage_request ? (smu)->funcs->display_clock_voltage_request((smu), (clock_req)) : 0)
 
 
 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index 17da50f..b5b272f 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1123,6 +1123,49 @@ static int smu_v11_0_read_sensor(struct smu_context *smu,
 	return ret;
 }
 
+static int
+smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
+					struct pp_display_clock_request
+					*clock_req)
+{
+	enum amd_pp_clock_type clk_type = clock_req->clock_type;
+	int ret = 0;
+	PPCLK_e clk_select = 0;
+	uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
+
+	mutex_lock(&smu->mutex);
+	if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
+		switch (clk_type) {
+		case amd_pp_dcef_clock:
+			clk_select = PPCLK_DCEFCLK;
+			break;
+		case amd_pp_disp_clock:
+			clk_select = PPCLK_DISPCLK;
+			break;
+		case amd_pp_pixel_clock:
+			clk_select = PPCLK_PIXCLK;
+			break;
+		case amd_pp_phy_clock:
+			clk_select = PPCLK_PHYCLK;
+			break;
+		default:
+			pr_info("[%s] Invalid Clock Type!", __func__);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret)
+			goto failed;
+
+		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
+						  (clk_select << 16) | clk_freq);
+	}
+
+failed:
+	mutex_unlock(&smu->mutex);
+	return ret;
+}
+
 static const struct smu_funcs smu_v11_0_funcs = {
 	.init_microcode = smu_v11_0_init_microcode,
 	.load_microcode = smu_v11_0_load_microcode,
@@ -1157,6 +1200,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
 	.start_thermal_control = smu_v11_0_start_thermal_control,
 	.read_sensor = smu_v11_0_read_sensor,
 	.set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
+	.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
 };
 
 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
amd-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux