AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: <sunpeng.li-5C7GfCeVMHo@public.gmane.org>
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: sunpeng.li-5C7GfCeVMHo@public.gmane.org,
	Wenjing Liu <Wenjing.Liu-5C7GfCeVMHo@public.gmane.org>
Subject: [PATCH 41/45] drm/amd/display: verify lane status before exiting verify link cap
Date: Tue, 11 Dec 2018 17:57:47 -0500	[thread overview]
Message-ID: <1544569071-7114-42-git-send-email-sunpeng.li@amd.com> (raw)
In-Reply-To: <1544569071-7114-1-git-send-email-sunpeng.li-5C7GfCeVMHo@public.gmane.org>

From: Wenjing Liu <Wenjing.Liu@amd.com>

[why]
DP LL CTS1.4 4.3.2.1 test failure.

[how]
The failure is caused by not handling DP link loss
hpd short pusle during set mode. The change is to read link status
before set mode link training. If link is lost, re-verify link caps.
Signed-off-by: Wenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   | 243 +++++++++++----------
 drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c |   3 +-
 2 files changed, 127 insertions(+), 119 deletions(-)

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 56a06bb..e979ad1 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
@@ -1089,6 +1089,121 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 	return max_link_cap;
 }
 
+static enum dc_status read_hpd_rx_irq_data(
+	struct dc_link *link,
+	union hpd_irq_data *irq_data)
+{
+	static enum dc_status retval;
+
+	/* The HW reads 16 bytes from 200h on HPD,
+	 * but if we get an AUX_DEFER, the HW cannot retry
+	 * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
+	 * fail, so we now explicitly read 6 bytes which is
+	 * the req from the above mentioned test cases.
+	 *
+	 * For DP 1.4 we need to read those from 2002h range.
+	 */
+	if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
+		retval = core_link_read_dpcd(
+			link,
+			DP_SINK_COUNT,
+			irq_data->raw,
+			sizeof(union hpd_irq_data));
+	else {
+		/* Read 14 bytes in a single read and then copy only the required fields.
+		 * This is more efficient than doing it in two separate AUX reads. */
+
+		uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
+
+		retval = core_link_read_dpcd(
+			link,
+			DP_SINK_COUNT_ESI,
+			tmp,
+			sizeof(tmp));
+
+		if (retval != DC_OK)
+			return retval;
+
+		irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
+		irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
+		irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
+		irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
+		irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
+		irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
+	}
+
+	return retval;
+}
+
+static bool hpd_rx_irq_check_link_loss_status(
+	struct dc_link *link,
+	union hpd_irq_data *hpd_irq_dpcd_data)
+{
+	uint8_t irq_reg_rx_power_state = 0;
+	enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
+	union lane_status lane_status;
+	uint32_t lane;
+	bool sink_status_changed;
+	bool return_code;
+
+	sink_status_changed = false;
+	return_code = false;
+
+	if (link->cur_link_settings.lane_count == 0)
+		return return_code;
+
+	/*1. Check that Link Status changed, before re-training.*/
+
+	/*parse lane status*/
+	for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
+		/* check status of lanes 0,1
+		 * changed DpcdAddress_Lane01Status (0x202)
+		 */
+		lane_status.raw = get_nibble_at_index(
+			&hpd_irq_dpcd_data->bytes.lane01_status.raw,
+			lane);
+
+		if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
+			!lane_status.bits.CR_DONE_0 ||
+			!lane_status.bits.SYMBOL_LOCKED_0) {
+			/* if one of the channel equalization, clock
+			 * recovery or symbol lock is dropped
+			 * consider it as (link has been
+			 * dropped) dp sink status has changed
+			 */
+			sink_status_changed = true;
+			break;
+		}
+	}
+
+	/* Check interlane align.*/
+	if (sink_status_changed ||
+		!hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
+
+		DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
+
+		return_code = true;
+
+		/*2. Check that we can handle interrupt: Not in FS DOS,
+		 *  Not in "Display Timeout" state, Link is trained.
+		 */
+		dpcd_result = core_link_read_dpcd(link,
+			DP_SET_POWER,
+			&irq_reg_rx_power_state,
+			sizeof(irq_reg_rx_power_state));
+
+		if (dpcd_result != DC_OK) {
+			DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
+				__func__);
+		} else {
+			if (irq_reg_rx_power_state != DP_SET_POWER_D0)
+				return_code = false;
+		}
+	}
+
+	return return_code;
+}
+
 bool dp_verify_link_cap(
 	struct dc_link *link,
 	struct dc_link_settings *known_limit_link_setting,
@@ -1104,12 +1219,14 @@ bool dp_verify_link_cap(
 	struct clock_source *dp_cs;
 	enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
 	enum link_training_result status;
+	union hpd_irq_data irq_data;
 
 	if (link->dc->debug.skip_detection_link_training) {
 		link->verified_link_cap = *known_limit_link_setting;
 		return true;
 	}
 
+	memset(&irq_data, 0, sizeof(irq_data));
 	success = false;
 	skip_link_training = false;
 
@@ -1168,9 +1285,15 @@ bool dp_verify_link_cap(
 				(*fail_count)++;
 		}
 
-		if (success)
+		if (success) {
 			link->verified_link_cap = *cur;
-
+			udelay(1000);
+			if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK)
+				if (hpd_rx_irq_check_link_loss_status(
+						link,
+						&irq_data))
+					(*fail_count)++;
+		}
 		/* always disable the link before trying another
 		 * setting or before returning we'll enable it later
 		 * based on the actual mode we're driving
@@ -1572,122 +1695,6 @@ void decide_link_settings(struct dc_stream_state *stream,
 }
 
 /*************************Short Pulse IRQ***************************/
-
-static bool hpd_rx_irq_check_link_loss_status(
-	struct dc_link *link,
-	union hpd_irq_data *hpd_irq_dpcd_data)
-{
-	uint8_t irq_reg_rx_power_state = 0;
-	enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
-	union lane_status lane_status;
-	uint32_t lane;
-	bool sink_status_changed;
-	bool return_code;
-
-	sink_status_changed = false;
-	return_code = false;
-
-	if (link->cur_link_settings.lane_count == 0)
-		return return_code;
-
-	/*1. Check that Link Status changed, before re-training.*/
-
-	/*parse lane status*/
-	for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
-		/* check status of lanes 0,1
-		 * changed DpcdAddress_Lane01Status (0x202)
-		 */
-		lane_status.raw = get_nibble_at_index(
-			&hpd_irq_dpcd_data->bytes.lane01_status.raw,
-			lane);
-
-		if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
-			!lane_status.bits.CR_DONE_0 ||
-			!lane_status.bits.SYMBOL_LOCKED_0) {
-			/* if one of the channel equalization, clock
-			 * recovery or symbol lock is dropped
-			 * consider it as (link has been
-			 * dropped) dp sink status has changed
-			 */
-			sink_status_changed = true;
-			break;
-		}
-	}
-
-	/* Check interlane align.*/
-	if (sink_status_changed ||
-		!hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
-
-		DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
-
-		return_code = true;
-
-		/*2. Check that we can handle interrupt: Not in FS DOS,
-		 *  Not in "Display Timeout" state, Link is trained.
-		 */
-		dpcd_result = core_link_read_dpcd(link,
-			DP_SET_POWER,
-			&irq_reg_rx_power_state,
-			sizeof(irq_reg_rx_power_state));
-
-		if (dpcd_result != DC_OK) {
-			DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
-				__func__);
-		} else {
-			if (irq_reg_rx_power_state != DP_SET_POWER_D0)
-				return_code = false;
-		}
-	}
-
-	return return_code;
-}
-
-static enum dc_status read_hpd_rx_irq_data(
-	struct dc_link *link,
-	union hpd_irq_data *irq_data)
-{
-	static enum dc_status retval;
-
-	/* The HW reads 16 bytes from 200h on HPD,
-	 * but if we get an AUX_DEFER, the HW cannot retry
-	 * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
-	 * fail, so we now explicitly read 6 bytes which is
-	 * the req from the above mentioned test cases.
-	 *
-	 * For DP 1.4 we need to read those from 2002h range.
-	 */
-	if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
-		retval = core_link_read_dpcd(
-			link,
-			DP_SINK_COUNT,
-			irq_data->raw,
-			sizeof(union hpd_irq_data));
-	else {
-		/* Read 14 bytes in a single read and then copy only the required fields.
-		 * This is more efficient than doing it in two separate AUX reads. */
-
-		uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
-
-		retval = core_link_read_dpcd(
-			link,
-			DP_SINK_COUNT_ESI,
-			tmp,
-			sizeof(tmp));
-
-		if (retval != DC_OK)
-			return retval;
-
-		irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
-		irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
-		irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
-		irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
-		irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
-		irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
-	}
-
-	return retval;
-}
-
 static bool allow_hpd_rx_irq(const struct dc_link *link)
 {
 	/*
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index f96fab3..16d441d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -95,6 +95,7 @@ void dp_enable_link_phy(
 						link_settings,
 						clock_source);
 	}
+	link->cur_link_settings = *link_settings;
 
 	dp_receiver_power_ctrl(link, true);
 }
@@ -304,6 +305,7 @@ void dp_retrain_link_dp_test(struct dc_link *link,
 						link->link_enc,
 						link_setting,
 						pipes[i].clock_source->id);
+			link->cur_link_settings = *link_setting;
 
 			dp_receiver_power_ctrl(link, true);
 
@@ -313,7 +315,6 @@ void dp_retrain_link_dp_test(struct dc_link *link,
 					skip_video_pattern,
 					LINK_TRAINING_ATTEMPTS);
 
-			link->cur_link_settings = *link_setting;
 
 			link->dc->hwss.enable_stream(&pipes[i]);
 
-- 
2.7.4

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

  parent reply	other threads:[~2018-12-11 22:57 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-11 22:57 [PATCH 00/45] DC Patches Dec 11, 2018 sunpeng.li-5C7GfCeVMHo
     [not found] ` <1544569071-7114-1-git-send-email-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
2018-12-11 22:57   ` [PATCH 01/45] drm/amd/display: 3.2.09 sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 02/45] drm/amd/display: Add a PP_SMU_VER_MAX enum sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 03/45] drm/amd/display: Expose hubp1_vready_workaround function sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 04/45] drm/amd/display: Fix runtime errors for diagnostic tests sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 05/45] drm/amd/display: fix surface update sequence sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 06/45] drm/amd/display: Add pixel clock values to dtn logs sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 07/45] drm/amd/display: Remove some extra braces sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 08/45] drm/amd/display: implement dc_init_callbacks to assign callback pointers after dc_create sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 09/45] drm/amd/display: add plane size change check condition sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 10/45] drm/amd/display: Fix issue with VLine interrupt not firing sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 11/45] drm/amd/display: update bw formula to v252 sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 12/45] drm/amd/display: Add debug option to force fclk request sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 13/45] drm/amd/display: remove sink reference in dc_stream_state sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 14/45] drm/amd/display: Remove unused headers sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 15/45] drm/amd/display: Detach backlight from stream sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 16/45] drm/amd/display: Raise dispclk value for Polaris sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 17/45] drm/amd/display: Warn instead of error on REG_WAIT timeout sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 18/45] drm/amd/display: update DCN dml calcs sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 19/45] drm/amd/display: fix YCbCr420 blank color sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 20/45] drm/amd/display: Wait edp HPD to high in detect_sink sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 21/45] drm/amd/display: Don't skip link training for empty dongle sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 22/45] drm/amd/display: add stream ID and otg instance in dc_stream_state sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 23/45] drm/amd/display: Add backlight pwm debugfs sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 24/45] drm/amd/display: 3.2.10 sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 25/45] drm/amd/display: Remove stream_status->link sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 26/45] drm/amd/display: Add retry to read ddc_clock pin sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 27/45] drm/amd/display: Fix driver load crash in amdgpu_dm sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 28/45] drm/amd/display: Minor code cleanup sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 29/45] drm/amd/display: Use 100 Hz precision for pipe pixel clocks sunpeng.li-5C7GfCeVMHo
     [not found]     ` <1544569071-7114-30-git-send-email-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
2018-12-12  8:19       ` Christian König
     [not found]         ` <2cf9b879-6c37-6879-e4bb-12fb309f8e94-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2018-12-12 18:29           ` Chalmers, Kenneth
2018-12-11 22:57   ` [PATCH 30/45] drm/amd/display: Improve logging of validation failures during atomic_check sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 31/45] drm/amd/display: Add DCE_VERSION_12_1 enum for Vega 20 sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 32/45] drm/amd/display: Add functionality to get XGMI SS info sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 33/45] drm/amd/display: Use local variable instead of caching global sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 34/45] drm/amd/display: Compensate for XGMI SS downspread on dprefclk sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 35/45] drm/amd/display: 3.2.11 sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 36/45] drm/amd/display: Start using the new pp_smu interface sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 37/45] drm/amd/display: Fix bug with not updating VSP infoframe sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 38/45] drm/amd/display: add dsclk to pipe bw struct sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 39/45] drm/amd/display: move AYCrCb8888 format to video section sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 40/45] drm/amd/display: Don't log error if we have no connectors sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` sunpeng.li-5C7GfCeVMHo [this message]
2018-12-11 22:57   ` [PATCH 42/45] drm/amd/display: Optimize passive update planes sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 43/45] drm/amd/display: Expand set_pixel_clock debug log message sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 44/45] drm/amd/display: validate extended dongle caps sunpeng.li-5C7GfCeVMHo
2018-12-11 22:57   ` [PATCH 45/45] drm/amd/display: Remove unused parameter plane_states sunpeng.li-5C7GfCeVMHo

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=1544569071-7114-42-git-send-email-sunpeng.li@amd.com \
    --to=sunpeng.li-5c7gfcevmho@public.gmane.org \
    --cc=Wenjing.Liu-5C7GfCeVMHo@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox