Commit 97011249 authored by Hersen Wu's avatar Hersen Wu Committed by Alex Deucher

drm/amd/display: USB-C / thunderbolt dock specific workaround

reading dpcd 0x600 cause link loss for a particular USB-C dock with
thurderbolt.  workaround by avoiding dcpd 0x600 read unless it's
necessary.
Signed-off-by: default avatarHersen Wu <hersenxs.wu@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 320a1274
...@@ -1512,7 +1512,7 @@ static bool hpd_rx_irq_check_link_loss_status( ...@@ -1512,7 +1512,7 @@ static bool hpd_rx_irq_check_link_loss_status(
struct dc_link *link, struct dc_link *link,
union hpd_irq_data *hpd_irq_dpcd_data) union hpd_irq_data *hpd_irq_dpcd_data)
{ {
uint8_t irq_reg_rx_power_state; uint8_t irq_reg_rx_power_state = 0;
enum dc_status dpcd_result = DC_ERROR_UNEXPECTED; enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
union lane_status lane_status; union lane_status lane_status;
uint32_t lane; uint32_t lane;
...@@ -1524,33 +1524,14 @@ static bool hpd_rx_irq_check_link_loss_status( ...@@ -1524,33 +1524,14 @@ static bool hpd_rx_irq_check_link_loss_status(
if (link->cur_link_settings.lane_count == 0) if (link->cur_link_settings.lane_count == 0)
return return_code; return return_code;
/*1. Check that we can handle interrupt: Not in FS DOS,
* Not in "Display Timeout" state, Link is trained.
*/
dpcd_result = core_link_read_dpcd(link, /*1. Check that Link Status changed, before re-training.*/
DP_SET_POWER,
&irq_reg_rx_power_state,
sizeof(irq_reg_rx_power_state));
if (dpcd_result != DC_OK) {
irq_reg_rx_power_state = DP_SET_POWER_D0;
dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
"%s: DPCD read failed to obtain power state.\n",
__func__);
}
if (irq_reg_rx_power_state == DP_SET_POWER_D0) {
/*2. Check that Link Status changed, before re-training.*/
/*parse lane status*/ /*parse lane status*/
for (lane = 0; for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
lane < link->cur_link_settings.lane_count;
lane++) {
/* check status of lanes 0,1 /* check status of lanes 0,1
* changed DpcdAddress_Lane01Status (0x202)*/ * changed DpcdAddress_Lane01Status (0x202)
*/
lane_status.raw = get_nibble_at_index( lane_status.raw = get_nibble_at_index(
&hpd_irq_dpcd_data->bytes.lane01_status.raw, &hpd_irq_dpcd_data->bytes.lane01_status.raw,
lane); lane);
...@@ -1561,23 +1542,37 @@ static bool hpd_rx_irq_check_link_loss_status( ...@@ -1561,23 +1542,37 @@ static bool hpd_rx_irq_check_link_loss_status(
/* if one of the channel equalization, clock /* if one of the channel equalization, clock
* recovery or symbol lock is dropped * recovery or symbol lock is dropped
* consider it as (link has been * consider it as (link has been
* dropped) dp sink status has changed*/ * dropped) dp sink status has changed
*/
sink_status_changed = true; sink_status_changed = true;
break; break;
} }
} }
/* Check interlane align.*/ /* Check interlane align.*/
if (sink_status_changed || if (sink_status_changed ||
!hpd_irq_dpcd_data->bytes.lane_status_updated.bits. !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
INTERLANE_ALIGN_DONE) {
dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ, dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
"%s: Link Status changed.\n", "%s: Link Status changed.\n", __func__);
__func__);
return_code = true; return_code = true;
/*2. Check that we can handle interrupt: Not in FS DOS,
* Not in "Display Timeout" state, Link is trained.
*/
dpcd_result = core_link_read_dpcd(link,
DP_SET_POWER,
&irq_reg_rx_power_state,
sizeof(irq_reg_rx_power_state));
if (dpcd_result != DC_OK) {
dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
"%s: DPCD read failed to obtain power state.\n",
__func__);
} else {
if (irq_reg_rx_power_state != DP_SET_POWER_D0)
return_code = false;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment