[PATCH 12/36] drm/amd/display: Send message to notify the DPIA host router bandwidth

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

 



From: Sung Joon Kim <sungjoon.kim@xxxxxxx>

[why]
Tell the system about the current host router bandwidth to be used to
measure and calculate the right voltage to be used.

[how]
Send SMU message of each DPIA host router bandwidth.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx>
Acked-by: Hamza Mahfooz <hamza.mahfooz@xxxxxxx>
Signed-off-by: Sung Joon Kim <sungjoon.kim@xxxxxxx>
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  | 55 +++++++++++++++++++
 .../amd/display/dc/clk_mgr/dcn35/dcn35_smu.c  | 21 ++++++-
 .../amd/display/dc/clk_mgr/dcn35/dcn35_smu.h  |  2 +
 drivers/gpu/drm/amd/display/dc/dc.h           |  3 +
 .../dc/resource/dcn351/dcn351_resource.c      |  1 +
 5 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 6c9b4e6491a5..9a414f49f15a 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -218,6 +218,57 @@ static void dcn35_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
 		}
 }
 
+static uint8_t get_lowest_dpia_index(const struct dc_link *link)
+{
+	const struct dc *dc_struct = link->dc;
+	uint8_t idx = 0xFF;
+	int i;
+
+	for (i = 0; i < MAX_PIPES * 2; ++i) {
+		if (!dc_struct->links[i] || dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA)
+			continue;
+
+		if (idx > dc_struct->links[i]->link_index)
+			idx = dc_struct->links[i]->link_index;
+	}
+
+	return idx;
+}
+
+static void dcn35_notify_host_router_bw(struct clk_mgr *clk_mgr_base, struct dc_state *context,
+					bool safe_to_lower)
+{
+	struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
+	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+	uint32_t host_router_bw_kbps[MAX_HOST_ROUTERS_NUM] = { 0 };
+	int i;
+
+	for (i = 0; i < context->stream_count; ++i) {
+		const struct dc_stream_state *stream = context->streams[i];
+		const struct dc_link *link = stream->link;
+		uint8_t lowest_dpia_index = 0, hr_index = 0;
+
+		if (!link)
+			continue;
+
+		lowest_dpia_index = get_lowest_dpia_index(link);
+		if (link->link_index < lowest_dpia_index)
+			continue;
+
+		hr_index = (link->link_index - lowest_dpia_index) / 2;
+		host_router_bw_kbps[hr_index] += dc_bandwidth_in_kbps_from_timing(
+			&stream->timing, dc_link_get_highest_encoding_format(link));
+	}
+
+	for (i = 0; i < MAX_HOST_ROUTERS_NUM; ++i) {
+		new_clocks->host_router_bw_kbps[i] = host_router_bw_kbps[i];
+		if (should_set_clock(safe_to_lower, new_clocks->host_router_bw_kbps[i], clk_mgr_base->clks.host_router_bw_kbps[i])) {
+			clk_mgr_base->clks.host_router_bw_kbps[i] = new_clocks->host_router_bw_kbps[i];
+			dcn35_smu_notify_host_router_bw(clk_mgr, i, new_clocks->host_router_bw_kbps[i]);
+		}
+	}
+}
+
 void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
 			struct dc_state *context,
 			bool safe_to_lower)
@@ -342,6 +393,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
 		dcn35_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
 	}
 
+	// notify PMFW of bandwidth per DPIA tunnel
+	if (dc->debug.notify_dpia_hr_bw)
+		dcn35_notify_host_router_bw(clk_mgr_base, context, safe_to_lower);
+
 	// notify DMCUB of latest clocks
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.notify_clocks.header.type = DMUB_CMD__CLK_MGR;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
index 1399b41dfd1c..f6f0e6a33001 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
@@ -89,7 +89,8 @@
 #define VBIOSSMC_MSG_DisableLSdma                 0x1A ///< Disable LSDMA; only sent by VBIOS
 #define VBIOSSMC_MSG_DpControllerPhyStatus        0x1B ///< Inform PMFW about the pre conditions for turning SLDO2 on/off . bit[0]==1 precondition is met, bit[1-2] are for DPPHY number
 #define VBIOSSMC_MSG_QueryIPS2Support             0x1C ///< Return 1: support; else not supported
-#define VBIOSSMC_Message_Count                    0x1D
+#define VBIOSSMC_MSG_NotifyHostRouterBW           0x1D
+#define VBIOSSMC_Message_Count                    0x1E
 
 #define VBIOSSMC_Status_BUSY                      0x0
 #define VBIOSSMC_Result_OK                        0x1
@@ -98,6 +99,14 @@
 #define VBIOSSMC_Result_CmdRejectedPrereq         0xFD
 #define VBIOSSMC_Result_CmdRejectedBusy           0xFC
 
+union dcn35_dpia_host_router_bw {
+	struct {
+		uint32_t hr_id : 16;
+		uint32_t bw_mbps : 16;
+	} bits;
+	uint32_t all;
+};
+
 /*
  * Function to be used instead of REG_WAIT macro because the wait ends when
  * the register is NOT EQUAL to zero, and because `the translation in msg_if.h
@@ -487,3 +496,13 @@ int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr)
 	//smu_print("%s: VBIOSSMC_MSG_QueryIPS2Support return = %x\n", __func__, retv);
 	return retv;
 }
+
+void dcn35_smu_notify_host_router_bw(struct clk_mgr_internal *clk_mgr, uint32_t hr_id, uint32_t bw_kbps)
+{
+	union dcn35_dpia_host_router_bw msg_data = { 0 };
+
+	msg_data.bits.hr_id = hr_id;
+	msg_data.bits.bw_mbps = bw_kbps / 1000;
+
+	dcn35_smu_send_msg_with_param(clk_mgr, VBIOSSMC_MSG_NotifyHostRouterBW, msg_data.all);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h
index 06cd3cc6d36e..3fae13c73934 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.h
@@ -198,4 +198,6 @@ int dcn35_smu_exit_low_power_state(struct clk_mgr_internal *clk_mgr);
 int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr);
 int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr);
 int dcn35_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr);
+void dcn35_smu_notify_host_router_bw(struct clk_mgr_internal *clk_mgr, uint32_t hr_id, uint32_t bw_kbps);
+
 #endif /* DAL_DC_35_SMU_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index b9c67bac7beb..fa4e6b09409e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -62,6 +62,7 @@ struct dmub_notification;
 #define MAX_STREAMS 6
 #define MIN_VIEWPORT_SIZE 12
 #define MAX_NUM_EDP 2
+#define MAX_HOST_ROUTERS_NUM 2
 
 /* Display Core Interfaces */
 struct dc_versions {
@@ -594,6 +595,7 @@ struct dc_clocks {
 	bool prev_p_state_change_support;
 	bool fclk_prev_p_state_change_support;
 	int num_ways;
+	int host_router_bw_kbps[MAX_HOST_ROUTERS_NUM];
 
 	/*
 	 * @fw_based_mclk_switching
@@ -1045,6 +1047,7 @@ struct dc_debug_options {
 	unsigned int force_easf;
 	unsigned int force_sharpness;
 	unsigned int force_lls;
+	bool notify_dpia_hr_bw;
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
index 30b40ba0c324..4c5e722baa3a 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
@@ -765,6 +765,7 @@ static const struct dc_debug_options debug_defaults_drv = {
 	.ips2_entry_delay_us = 800,
 	.disable_dmub_reallow_idle = false,
 	.static_screen_wait_frames = 2,
+	.notify_dpia_hr_bw = true,
 };
 
 static const struct dc_panel_config panel_config_defaults = {
-- 
2.45.1




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

  Powered by Linux