mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
drm/amd/display: Work around bad DPCD state on link loss
[Why] This display doesn't properly indicate link loss through DPCD bits such as CR_DONE / CHANNEL_EQ_DONE / SYMBOL_LOCKED / INTERLANE_ALIGN_DONE, which all remain set. In addition, DPCD200Eh doesn't match the value of DPCD204h in all cases. For these reasons, we can miss re-training the link, since we don't properly detect link loss with this display. [Why] Add display-specific workaround to read DPCD204h, so that we can detect link loss based on 128b132b-specific status bits in this register. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Reviewed-by: Wenjing Liu <wenjing.liu@amd.com> Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com> Signed-off-by: Ilya Bakoulin <ilya.bakoulin@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
2036b34d4a
commit
2faa3653d6
@ -1525,6 +1525,7 @@ struct dc_link {
|
||||
bool dpia_forced_tbt3_mode;
|
||||
bool dongle_mode_timing_override;
|
||||
bool blank_stream_on_ocs_change;
|
||||
bool read_dpcd204h_on_irq_hpd;
|
||||
} wa_flags;
|
||||
struct link_mst_stream_allocation_table mst_stream_alloc_table;
|
||||
|
||||
|
@ -208,6 +208,25 @@ void dp_handle_link_loss(struct dc_link *link)
|
||||
}
|
||||
}
|
||||
|
||||
static void read_dpcd204h_on_irq_hpd(struct dc_link *link, union hpd_irq_data *irq_data)
|
||||
{
|
||||
enum dc_status retval;
|
||||
union lane_align_status_updated dpcd_lane_status_updated;
|
||||
|
||||
retval = core_link_read_dpcd(
|
||||
link,
|
||||
DP_LANE_ALIGN_STATUS_UPDATED,
|
||||
&dpcd_lane_status_updated.raw,
|
||||
sizeof(union lane_align_status_updated));
|
||||
|
||||
if (retval == DC_OK) {
|
||||
irq_data->bytes.lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b =
|
||||
dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b;
|
||||
irq_data->bytes.lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b =
|
||||
dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b;
|
||||
}
|
||||
}
|
||||
|
||||
enum dc_status dp_read_hpd_rx_irq_data(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *irq_data)
|
||||
@ -249,6 +268,13 @@ enum dc_status dp_read_hpd_rx_irq_data(
|
||||
irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
|
||||
irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
|
||||
irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
|
||||
|
||||
/*
|
||||
* This display doesn't have correct values in DPCD200Eh.
|
||||
* Read and check DPCD204h instead.
|
||||
*/
|
||||
if (link->wa_flags.read_dpcd204h_on_irq_hpd)
|
||||
read_dpcd204h_on_irq_hpd(link, irq_data);
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
Loading…
Reference in New Issue
Block a user