drm/amd/display: Handle Replay related hpd irq

Handle replay related hpd irqs

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Bhawanpreet Lakha 2023-06-28 11:56:45 -04:00 committed by Alex Deucher
parent d34fecc6e9
commit 0fc7d79b45
1 changed files with 66 additions and 0 deletions

View File

@ -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.
*/