All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: stylon.wang@amd.com, Sunpeng.Li@amd.com, Harry.Wentland@amd.com,
	qingqing.zhuo@amd.com, "Shen, George" <George.Shen@amd.com>,
	Rodrigo.Siqueira@amd.com, roman.li@amd.com,
	Wenjing Liu <Wenjing.Liu@amd.com>,
	solomon.chiu@amd.com, Aurabindo.Pillai@amd.com,
	wayne.lin@amd.com, Bhawanpreet.Lakha@amd.com,
	agustin.gutierrez@amd.com, pavle.kotarac@amd.com
Subject: [PATCH 08/24] drm/amd/display: Add Cable ID support for native DP
Date: Sun, 23 Jan 2022 13:20:05 -0500	[thread overview]
Message-ID: <20220123182021.4154032-9-Rodrigo.Siqueira@amd.com> (raw)
In-Reply-To: <20220123182021.4154032-1-Rodrigo.Siqueira@amd.com>

From: "Shen, George" <George.Shen@amd.com>

[Why/How]
We need to handle cable capabilities for cables that support cable ID.
The cable attributes are intersected with the verified link caps to
determine appropriate max link rate. After determining cable attributes
we update the DP receiver.

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: George Shen <George.Shen@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  5 ++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 59 +++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  2 +
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  | 16 +++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  7 +++
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |  3 +
 6 files changed, 92 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index b826ac9bd85d..d0aba8d7b1c3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1290,6 +1290,8 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 		 *  Clear dongle_max_pix_clk on disconnect to fix this
 		 */
 		link->dongle_max_pix_clk = 0;
+
+		dc_link_dp_clear_rx_status(link);
 	}
 
 	LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
@@ -1969,6 +1971,9 @@ static enum dc_status enable_link_dp(struct dc_state *state,
 	if (link->dpcd_sink_ext_caps.raw != 0)
 		msleep(post_oui_delay);
 
+	// similarly, mode switch can cause loss of cable ID
+	dpcd_update_cable_id(link);
+
 	skip_video_pattern = true;
 
 	if (link_settings.link_rate == LINK_RATE_LOW)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 1730be6c64ed..0033d2a0cfe5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2981,6 +2981,20 @@ static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
 	return lttpr_max_link_rate;
 }
 
+static enum dc_link_rate get_cable_max_link_rate(struct dc_link *link)
+{
+	enum dc_link_rate cable_max_link_rate = LINK_RATE_HIGH3;
+
+	if (link->dpcd_caps.cable_attributes.bits.UHBR10_20_CAPABILITY & DP_UHBR20)
+		cable_max_link_rate = LINK_RATE_UHBR20;
+	else if (link->dpcd_caps.cable_attributes.bits.UHBR13_5_CAPABILITY)
+		cable_max_link_rate = LINK_RATE_UHBR13_5;
+	else if (link->dpcd_caps.cable_attributes.bits.UHBR10_20_CAPABILITY & DP_UHBR10)
+		cable_max_link_rate = LINK_RATE_UHBR10;
+
+	return cable_max_link_rate;
+}
+
 bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
 {
 	struct link_encoder *link_enc = NULL;
@@ -3009,8 +3023,10 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
 {
 	struct dc_link_settings max_link_cap = {0};
 	enum dc_link_rate lttpr_max_link_rate;
+	enum dc_link_rate cable_max_link_rate;
 	struct link_encoder *link_enc = NULL;
 
+
 	link_enc = link_enc_cfg_get_link_enc(link);
 	ASSERT(link_enc);
 
@@ -3029,6 +3045,14 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
 			max_link_cap.link_spread)
 		max_link_cap.link_spread =
 				link->reported_link_cap.link_spread;
+
+	/* Lower link settings based on cable attributes */
+	cable_max_link_rate = get_cable_max_link_rate(link);
+
+	if (!link->dc->debug.ignore_cable_id &&
+			cable_max_link_rate < max_link_cap.link_rate)
+		max_link_cap.link_rate = cable_max_link_rate;
+
 	/*
 	 * account for lttpr repeaters cap
 	 * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
@@ -5059,6 +5083,13 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
 	return is_lttpr_present;
 }
 
+
+static bool is_usbc_connector(struct dc_link *link)
+{
+	return link->link_enc &&
+			link->link_enc->features.flags.bits.DP_IS_USB_C;
+}
+
 static bool retrieve_link_cap(struct dc_link *link)
 {
 	/* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
@@ -5115,6 +5146,9 @@ static bool retrieve_link_cap(struct dc_link *link)
 	 */
 	msleep(post_oui_delay);
 
+	/* Read cable ID and update receiver */
+	dpcd_update_cable_id(link);
+
 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
 		status = core_link_read_dpcd(
 				link,
@@ -6292,6 +6326,26 @@ void dpcd_set_source_specific_data(struct dc_link *link)
 	}
 }
 
+void dpcd_update_cable_id(struct dc_link *link)
+{
+	if (!link->link_enc->features.flags.bits.IS_UHBR10_CAPABLE ||
+			link->dprx_status.cable_id_updated)
+		return;
+
+	/* Retrieve cable attributes */
+	if (!is_usbc_connector(link))
+		core_link_read_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX,
+				&link->dpcd_caps.cable_attributes.raw,
+				sizeof(uint8_t));
+
+	/* Update receiver with cable attributes */
+	core_link_write_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX,
+			&link->dpcd_caps.cable_attributes.raw,
+			sizeof(link->dpcd_caps.cable_attributes.raw));
+
+	link->dprx_status.cable_id_updated = 1;
+}
+
 bool dc_link_set_backlight_level_nits(struct dc_link *link,
 		bool isHDR,
 		uint32_t backlight_millinits,
@@ -6689,3 +6743,8 @@ void edp_panel_backlight_power_on(struct dc_link *link)
 	if (link->dc->hwss.edp_backlight_control)
 		link->dc->hwss.edp_backlight_control(link, true);
 }
+
+void dc_link_dp_clear_rx_status(struct dc_link *link)
+{
+	memset(&link->dprx_status, 0, sizeof(link->dprx_status));
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index ff5093e52f2d..0dc183d6af5d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -687,6 +687,7 @@ struct dc_debug_options {
 	bool set_mst_en_for_sst;
 	bool disable_uhbr;
 	bool force_dp2_lt_fallback_method;
+	bool ignore_cable_id;
 	union mem_low_power_enable_options enable_mem_low_power;
 	union root_clock_optimization_options root_clock_optimization;
 	bool hpo_optimization;
@@ -1234,6 +1235,7 @@ struct dpcd_caps {
 	union dp_main_line_channel_coding_cap channel_coding_cap;
 	union dp_sink_video_fallback_formats fallback_formats;
 	union dp_fec_capability1 fec_cap1;
+	union dp_cable_attributes cable_attributes;
 };
 
 union dpcd_sink_ext_caps {
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index 6d813db6b8dc..ac2c59bd024d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -901,6 +901,9 @@ struct dpcd_usb4_dp_tunneling_info {
 #ifndef DP_LINK_SQUARE_PATTERN
 #define DP_LINK_SQUARE_PATTERN				0x10F
 #endif
+#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX
+#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX		0x110
+#endif
 #ifndef DP_DSC_CONFIGURATION
 #define DP_DSC_CONFIGURATION				0x161
 #endif
@@ -913,6 +916,9 @@ struct dpcd_usb4_dp_tunneling_info {
 #ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL
 #define DP_128b_132b_TRAINING_AUX_RD_INTERVAL		0x2216
 #endif
+#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX
+#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX		0x2217
+#endif
 #ifndef DP_TEST_264BIT_CUSTOM_PATTERN_7_0
 #define DP_TEST_264BIT_CUSTOM_PATTERN_7_0		0X2230
 #endif
@@ -1011,6 +1017,16 @@ union dp_fec_capability1 {
 	uint8_t raw;
 };
 
+union dp_cable_attributes {
+	struct {
+		uint8_t UHBR10_20_CAPABILITY	:2;
+		uint8_t UHBR13_5_CAPABILITY	:1;
+		uint8_t CABLE_TYPE		:3;
+		uint8_t RESERVED		:2;
+	} bits;
+	uint8_t raw;
+};
+
 struct dp_color_depth_caps {
 	uint8_t support_6bpc	:1;
 	uint8_t support_8bpc	:1;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 9014c0a0a63b..b1c79b3f26aa 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -43,6 +43,10 @@ struct dc_link_status {
 	struct dpcd_caps *dpcd_caps;
 };
 
+struct dp_receiver_status {
+	bool cable_id_updated;
+};
+
 /* DP MST stream allocation (payload bandwidth number) */
 struct link_mst_stream_allocation {
 	/* DIG front */
@@ -201,6 +205,7 @@ struct dc_link {
 	struct link_mst_stream_allocation_table mst_stream_alloc_table;
 
 	struct dc_link_status link_status;
+	struct dp_receiver_status dprx_status;
 
 	struct link_trace link_trace;
 	struct gpio *hpd_gpio;
@@ -459,4 +464,6 @@ const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link)
 void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map);
 /* restore link resource allocation state from a snapshot */
 void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
+
+void dc_link_dp_clear_rx_status(struct dc_link *link);
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index b7c5c42d67ed..3ed2dbbf5642 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -112,6 +112,9 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode);
 bool dp_overwrite_extended_receiver_cap(struct dc_link *link);
 
 void dpcd_set_source_specific_data(struct dc_link *link);
+
+void dpcd_update_cable_id(struct dc_link *link);
+
 /* Write DPCD link configuration data. */
 enum dc_status dpcd_set_link_settings(
 	struct dc_link *link,
-- 
2.25.1


  parent reply	other threads:[~2022-01-23 18:21 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-23 18:19 [PATCH 00/24] DC Patches Jan 23, 2022 Rodrigo Siqueira
2022-01-23 18:19 ` [PATCH 01/24] drm/amd/display: add protection in link encoder matching logic Rodrigo Siqueira
2022-01-23 18:19 ` [PATCH 02/24] drm/amd/display: do not compare integers of different widths Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 03/24] drm/amd/display: Driver support for MCLK query tool Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 04/24] drm/amd/display: Change error to warning when hpd remains low for eDP Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 05/24] drm/amd/display: Only set PSR version when valid Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 06/24] drm/amd/display: Change return type of dm_helpers_dp_mst_stop_top_mgr Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 07/24] drm/amd/display: Use PSR version selected during set_psr_caps Rodrigo Siqueira
2022-01-23 18:20 ` Rodrigo Siqueira [this message]
2022-01-23 18:20 ` [PATCH 09/24] drm/amd/display: Add Synaptics Fifo Reset Workaround Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 10/24] drm/amd/display: Retrieve MST Downstream Port Status Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 11/24] drm/amd/display: Add DSC Enable for Synaptics Hub Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 12/24] drm/amd/display: Support synchronized indirect reg access Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 13/24] drm/amd/display: Basic support with device ID Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 14/24] drm/amd/display: remove PHY repeater count check for LTTPR mode Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 15/24] drm/amd/display: Update VSC HDR infoPacket on TF change Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 16/24] drm/amd/display: [FW Promotion] Release 0.0.101.0 Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 17/24] drm/amd/display: Reset preferred training settings immediately Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 18/24] drm/amd/display: 3.2.170 Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 19/24] drm/amd/display: Remove unnecessary function definition Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 20/24] drm/amd/display: allow set dp drive setting when stream is not present Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 21/24] drm/amd/display: Fix disabling dccg clocks Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 22/24] drm/amd/display: Disable physym clock Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 23/24] drm/amd/display: fix zstate allow interface to PMFW Rodrigo Siqueira
2022-01-23 18:20 ` [PATCH 24/24] drm/amd/display: add debug option for z9 disable interface Rodrigo Siqueira
2022-01-24 14:06 ` [PATCH 00/24] DC Patches Jan 23, 2022 Wheeler, Daniel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220123182021.4154032-9-Rodrigo.Siqueira@amd.com \
    --to=rodrigo.siqueira@amd.com \
    --cc=Aurabindo.Pillai@amd.com \
    --cc=Bhawanpreet.Lakha@amd.com \
    --cc=George.Shen@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=Sunpeng.Li@amd.com \
    --cc=Wenjing.Liu@amd.com \
    --cc=agustin.gutierrez@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=pavle.kotarac@amd.com \
    --cc=qingqing.zhuo@amd.com \
    --cc=roman.li@amd.com \
    --cc=solomon.chiu@amd.com \
    --cc=stylon.wang@amd.com \
    --cc=wayne.lin@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.