Commit 6ebdaf20 authored by Lewis Huang's avatar Lewis Huang Committed by Alex Deucher
Browse files

drm/amd/display: Refine aux transaction before retrieve caps



[Why]
LTTPR caps will read fail if aux channel is not active.

[How]
1.Perform 600 read upto 10 retry with 1ms delay in between.
2.If fail, return false and trigger another retry detection.
3.If pass, read LTTPR caps in retrieve link caps.

Reviewed-by: default avatarJimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: default avatarBrian Chang <Brian.Chang@amd.com>
Signed-off-by: default avatarLewis Huang <Lewis.Huang@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9af611f2
Loading
Loading
Loading
Loading
+34 −11
Original line number Diff line number Diff line
@@ -5275,6 +5275,7 @@ static bool retrieve_link_cap(struct dc_link *link)
	union dp_downstream_port_present ds_port = { 0 };
	enum dc_status status = DC_ERROR_UNEXPECTED;
	uint32_t read_dpcd_retry_cnt = 3;
	uint32_t aux_channel_retry_cnt = 0;
	int i;
	struct dp_sink_hw_fw_revision dp_hw_fw_revision;
	const uint32_t post_oui_delay = 30; // 30ms
@@ -5302,10 +5303,7 @@ static bool retrieve_link_cap(struct dc_link *link)
		status = wa_try_to_wake_dprx(link, timeout_ms);
	}

	is_lttpr_present = dp_retrieve_lttpr_cap(link);
	/* Read DP tunneling information. */
	status = dpcd_get_tunneling_device_data(link);

	while (status != DC_OK && aux_channel_retry_cnt < 10) {
		status = core_link_read_dpcd(link, DP_SET_POWER,
				&dpcd_power_state, sizeof(dpcd_power_state));

@@ -5314,8 +5312,33 @@ static bool retrieve_link_cap(struct dc_link *link)
		 * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
		 * signal and may need up to 1 ms before being able to reply.
		 */
	if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
		if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) {
			udelay(1000);
			aux_channel_retry_cnt++;
		}
	}

	/* If aux channel is not active, return false and trigger another detect*/
	if (status != DC_OK) {
		dpcd_power_state = DP_SET_POWER_D0;
		status = core_link_write_dpcd(
				link,
				DP_SET_POWER,
				&dpcd_power_state,
				sizeof(dpcd_power_state));

		dpcd_power_state = DP_SET_POWER_D3;
		status = core_link_write_dpcd(
				link,
				DP_SET_POWER,
				&dpcd_power_state,
				sizeof(dpcd_power_state));
		return false;
	}

	is_lttpr_present = dp_retrieve_lttpr_cap(link);
	/* Read DP tunneling information. */
	status = dpcd_get_tunneling_device_data(link);

	dpcd_set_source_specific_data(link);
	/* Sink may need to configure internals based on vendor, so allow some