From 970cdba09cfb837d01232020b6e8381a6fe301c1 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 11 Jan 2016 11:45:11 -0500 Subject: [PATCH 0684/1110] drm/amd/dal: Don't handle DP short pulse until necessary We shouldn't handle DP short pulse interrupts until one of the following is met 1) The link is established (cur_link_settings != unknown) 2) We kicked off MST detection 3) We know we're dealing with an active dongle This works around an issue where the short pulse handler is trying to acquire the AUX line while EDID read is still happening. We still don't protect the AUX line properly in this case. Signed-off-by: Harry Wentland Acked-by: Jordan Lazare --- drivers/gpu/drm/amd/dal/dc/core/dc_link.c | 13 +++------- drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c | 36 ++++++++++++++++++++++++++++ drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h | 7 +++++- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c index c5ff145..e9e36c8 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c @@ -420,13 +420,6 @@ static enum signal_type dp_passive_dongle_detection( audio_support); } -static bool is_dp_active_dongle(enum display_dongle_type dongle_type) -{ - return (dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER || - dongle_type == DISPLAY_DONGLE_DP_DVI_CONVERTER || - dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER); -} - static void link_disconnect_sink(struct core_link *link) { if (link->public.local_sink) { @@ -472,7 +465,7 @@ static enum dc_edid_status read_edid( return edid_status; } -static void dc_link_detect_dp( +static void detect_dp( struct core_link *link, struct display_sink_capability *sink_caps, bool *converter_disable_audio, @@ -487,7 +480,7 @@ static void dc_link_detect_dp( detect_dp_sink_caps(link); /* DP active dongles */ - if (is_dp_active_dongle(link->dpcd_caps.dongle_type)) { + if (is_dp_active_dongle(link)) { if (!link->dpcd_caps.sink_count.bits.SINK_COUNT) { link->public.type = dc_connection_none; /* @@ -608,7 +601,7 @@ void dc_link_detect(const struct dc_link *dc_link) } case SIGNAL_TYPE_DISPLAY_PORT: { - dc_link_detect_dp( + detect_dp( link, &sink_caps, &converter_disable_audio, diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c index 4c17ff1..eaea78e 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c @@ -1,6 +1,7 @@ /* Copyright 2015 Advanced Micro Devices, Inc. */ #include "dc_services.h" #include "dc.h" +#include "dc_link_dp.h" #include "dc_helpers.h" #include "inc/core_types.h" #include "link_hwss.h" @@ -1391,6 +1392,23 @@ static enum dc_status read_hpd_rx_irq_data( sizeof(union hpd_irq_data)); } +static bool allow_hpd_rx_irq(const struct core_link *link) +{ + /* + * Don't handle RX IRQ unless one of following is met: + * 1) The link is established (cur_link_settings != unknown) + * 2) We kicked off MST detection + * 3) We know we're dealing with an active dongle + */ + + if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) || + (link->public.type == dc_connection_mst_branch) || + is_dp_active_dongle(link)) + return true; + + return false; +} + bool dc_link_handle_hpd_rx_irq(const struct dc_link *dc_link) { struct core_link *link = DC_LINK_TO_LINK(dc_link); @@ -1407,6 +1425,15 @@ bool dc_link_handle_hpd_rx_irq(const struct dc_link *dc_link) "%s: Got short pulse HPD on link %d\n", __func__, link->public.link_index); + if (!allow_hpd_rx_irq(link)) { + dal_logger_write(link->ctx->logger, + LOG_MAJOR_HW_TRACE, + LOG_MINOR_HW_TRACE_HPD_IRQ, + "%s: skipping HPD handling on %d\n", + __func__, link->public.link_index); + return false; + } + /* All the "handle_hpd_irq_xxx()" methods * should be called only after * dal_dpsst_ls_read_hpd_irq_data @@ -1480,6 +1507,15 @@ bool is_mst_supported(struct core_link *link) } +bool is_dp_active_dongle(const struct core_link *link) +{ + enum display_dongle_type dongle_type = link->dpcd_caps.dongle_type; + + return (dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) || + (dongle_type == DISPLAY_DONGLE_DP_DVI_CONVERTER) || + (dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER); +} + static void get_active_converter_info( uint8_t data, struct core_link *link) { diff --git a/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h index e3e4778..682c0b4 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h @@ -26,6 +26,10 @@ #ifndef __DC_LINK_DP_H__ #define __DC_LINK_DP_H__ +struct core_link; +struct core_stream; +struct link_settings; + bool dp_hbr_verify_link_cap( struct core_link *link, struct link_settings *known_limit_link_setting); @@ -43,9 +47,10 @@ bool perform_link_training( const struct link_settings *link_setting, bool skip_video_pattern); -/*dp mst functions*/ bool is_mst_supported(struct core_link *link); void detect_dp_sink_caps(struct core_link *link); +bool is_dp_active_dongle(const struct core_link *link); + #endif /* __DC_LINK_DP_H__ */ -- 2.7.4