}
}
-static void handle_hpd_irq_replay_sink(struct dc_link *link)
+static void handle_hpd_irq_replay_sink(struct dc_link *link, bool *need_re_enable)
{
union dpcd_replay_configuration replay_configuration = {0};
+ union dpcd_replay_configuration replay_sink_status = {0};
/*AMD Replay version reuse DP_PSR_ERROR_STATUS for REPLAY_ERROR status.*/
union psr_error_status replay_error_status = {0};
bool ret = false;
&replay_error_status.raw,
sizeof(replay_error_status.raw));
+ dm_helpers_dp_read_dpcd(
+ link->ctx,
+ link,
+ DP_PR_REPLAY_SINK_STATUS,
+ &replay_sink_status.raw,
+ 1);
+
if (replay_error_status.bits.LINK_CRC_ERROR ||
replay_configuration.bits.DESYNC_ERROR_STATUS ||
- replay_configuration.bits.STATE_TRANSITION_ERROR_STATUS) {
+ replay_configuration.bits.STATE_TRANSITION_ERROR_STATUS ||
+ replay_sink_status.bits.SINK_DEVICE_REPLAY_STATUS == 0x7) {
bool allow_active;
link->replay_settings.config.replay_error_status.raw |= replay_error_status.raw;
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);
+ *need_re_enable = true;
}
}
}
union device_service_irq device_service_clear = {0};
enum dc_status result;
bool status = false;
+ bool replay_re_enable_needed = false;
if (out_link_loss)
*out_link_loss = false;
/* PSR-related error was detected and handled */
return true;
- handle_hpd_irq_replay_sink(link);
+ handle_hpd_irq_replay_sink(link, &replay_re_enable_needed);
/* If PSR-related error handled, Main link may be off,
* so do not handle as a normal sink status change interrupt.
return false;
}
- /* For now we only handle 'Downstream port status' case.
+ /* Handle 'Downstream port status' case for all DP link types.
* If we got sink count changed it means
* Downstream port status changed,
* then DM should call DC to do the detection.
- * NOTE: Do not handle link loss on eDP since it is internal link
+ * NOTE: Now includes eDP link loss detection and retraining
*/
- if ((link->connector_signal != SIGNAL_TYPE_EDP) &&
- dp_parse_link_loss_status(
- link,
- &hpd_irq_dpcd_data)) {
+
+ if (dp_parse_link_loss_status(
+ link,
+ &hpd_irq_dpcd_data)) {
/* Connectivity log: link loss */
CONN_DATA_LINK_LOSS(link,
hpd_irq_dpcd_data.raw,
!= link->dpcd_sink_count)
status = true;
+ if (replay_re_enable_needed) {
+ bool allow_active = true;
+
+ edp_set_replay_allow_active(link, &allow_active, true, false, NULL);
+ }
/* reasons for HPD RX:
* 1. Link Loss - ie Re-train the Link
* 2. MST sideband message