Handle replay related hpd irqs

Signed-off-by: Bhawanpreet Lakha <bhawanpreet.la...@amd.com>
---
 .../dc/link/protocols/link_dp_irq_handler.c   | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
index ba95facc4ee8..a5605cf4449e 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
@@ -175,6 +175,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];
@@ -327,6 +389,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.
         */
-- 
2.25.1

Reply via email to