Commit e7f2c80c authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher
Browse files

drm/amd/display: check hpd before retry verify link cap



[why]
During detection link training if a display is disconnected,
the current code will retry 3 times of link training
on disconnected link before giving up.

[how]
Before each retry check for HPD status, only retry
verify link cap when HPD is still high.
Also put a 10ms delay between each retry to improve
the chance of success.

Signed-off-by: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarAbdoulaye Berthe <Abdoulaye.Berthe@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 79e00520
Loading
Loading
Loading
Loading
+6 −21
Original line number Diff line number Diff line
@@ -854,16 +854,9 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
					dc_sink_release(prev_sink);
				} else {
					/* Empty dongle plug in */
					for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
						int fail_count = 0;

						dp_verify_link_cap(link,
					dp_verify_link_cap_with_retries(link,
							&link->reported_link_cap,
								  &fail_count);

						if (fail_count == 0)
							break;
					}
							LINK_TRAINING_MAX_VERIFY_RETRY);
				}
				return true;
			}
@@ -967,17 +960,9 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
			 */

			/* deal with non-mst cases */
			for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
				int fail_count = 0;

				dp_verify_link_cap(link,
			dp_verify_link_cap_with_retries(link,
					&link->reported_link_cap,
						  &fail_count);

				if (fail_count == 0)
					break;
			}

					LINK_TRAINING_MAX_VERIFY_RETRY);
		} else {
			// If edid is the same, then discard new sink and revert back to original sink
			if (same_edid) {
+27 −0
Original line number Diff line number Diff line
@@ -1643,6 +1643,33 @@ bool dp_verify_link_cap(
	return success;
}

bool dp_verify_link_cap_with_retries(
	struct dc_link *link,
	struct dc_link_settings *known_limit_link_setting,
	int attempts)
{
	uint8_t i = 0;
	bool success = false;

	for (i = 0; i < attempts; i++) {
		int fail_count = 0;
		enum dc_connection_type type;

		memset(&link->verified_link_cap, 0,
				sizeof(struct dc_link_settings));
		if (!dc_link_detect_sink(link, &type)) {
			break;
		} else if (dp_verify_link_cap(link,
				&link->reported_link_cap,
				&fail_count) && fail_count == 0) {
			success = true;
			break;
		}
		msleep(10);
	}
	return success;
}

static struct dc_link_settings get_common_supported_link_settings(
		struct dc_link_settings link_setting_a,
		struct dc_link_settings link_setting_b)
+5 −0
Original line number Diff line number Diff line
@@ -38,6 +38,11 @@ bool dp_verify_link_cap(
	struct dc_link_settings *known_limit_link_setting,
	int *fail_count);

bool dp_verify_link_cap_with_retries(
	struct dc_link *link,
	struct dc_link_settings *known_limit_link_setting,
	int attempts);

bool dp_validate_mode_timing(
	struct dc_link *link,
	const struct dc_crtc_timing *timing);