Commit 0fc7d79b authored by Bhawanpreet Lakha's avatar Bhawanpreet Lakha Committed by Alex Deucher
Browse files

drm/amd/display: Handle Replay related hpd irq



Handle replay related hpd irqs

Signed-off-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d34fecc6
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -182,6 +182,68 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
	return false;
}

static bool handle_hpd_irq_replay_sink(struct dc_link *link)
{
	union dpcd_replay_configuration replay_configuration;
	/*AMD Replay version reuse DP_PSR_ERROR_STATUS for REPLAY_ERROR status.*/
	union psr_error_status replay_error_status;

	if (!link->replay_settings.replay_feature_enabled)
		return false;

	dm_helpers_dp_read_dpcd(
		link->ctx,
		link,
		DP_SINK_PR_REPLAY_STATUS,
		&replay_configuration.raw,
		sizeof(replay_configuration.raw));

	dm_helpers_dp_read_dpcd(
		link->ctx,
		link,
		DP_PSR_ERROR_STATUS,
		&replay_error_status.raw,
		sizeof(replay_error_status.raw));

	link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR =
		replay_error_status.bits.LINK_CRC_ERROR;
	link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR =
		replay_configuration.bits.DESYNC_ERROR_STATUS;
	link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR =
		replay_configuration.bits.STATE_TRANSITION_ERROR_STATUS;

	if (link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR ||
		link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR ||
		link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR) {
		bool allow_active;

		/* Acknowledge and clear configuration bits */
		dm_helpers_dp_write_dpcd(
			link->ctx,
			link,
			DP_SINK_PR_REPLAY_STATUS,
			&replay_configuration.raw,
			sizeof(replay_configuration.raw));

		/* Acknowledge and clear error bits */
		dm_helpers_dp_write_dpcd(
			link->ctx,
			link,
			DP_PSR_ERROR_STATUS,/*DpcdAddress_REPLAY_Error_Status*/
			&replay_error_status.raw,
			sizeof(replay_error_status.raw));

		/* Replay error, disable and re-enable Replay */
		if (link->replay_settings.replay_allow_active) {
			allow_active = false;
			edp_set_replay_allow_active(link, &allow_active, true, false, NULL);
			allow_active = true;
			edp_set_replay_allow_active(link, &allow_active, true, false, NULL);
		}
	}
	return true;
}

void dp_handle_link_loss(struct dc_link *link)
{
	struct pipe_ctx *pipes[MAX_PIPES];
@@ -360,6 +422,10 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link,
		/* PSR-related error was detected and handled */
		return true;

	if (handle_hpd_irq_replay_sink(link))
		/* Replay-related error was detected and handled */
		return true;

	/* If PSR-related error handled, Main link may be off,
	 * so do not handle as a normal sink status change interrupt.
	 */