drm/amd/display: Handle Replay related hpd irq
authorBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Wed, 28 Jun 2023 15:56:45 +0000 (11:56 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 16 Aug 2023 15:33:59 +0000 (11:33 -0400)
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>
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c

index ef8739d..e047bbe 100644 (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.
         */