| From d1b20925085186a43f4c3d9fca757441889cfe57 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 26 May 2020 13:56:53 -0400 |
| Subject: drm/amd/display: Improve DisplayPort monitor interop |
| |
| From: Aric Cyr <aric.cyr@amd.com> |
| |
| [ Upstream commit eec3303de3378cdfaa0bb86f43546dbbd88f94e2 ] |
| |
| [Why] |
| DC is very fast at link training and stream enablement |
| which causes issues such as blackscreens for non-compliant |
| monitors. |
| |
| [How] |
| After debugging with scaler vendors we implement the |
| minimum delays at the necessary locations to ensure |
| the monitor does not hang. Delays are generic due to |
| lack of IEEE OUI information on the failing displays. |
| |
| Signed-off-by: Aric Cyr <aric.cyr@amd.com> |
| Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com> |
| Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com> |
| Acked-by: Tony Cheng <Tony.Cheng@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 +++- |
| drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 16 ++++++++++------ |
| .../amd/display/dc/dce110/dce110_hw_sequencer.c | 11 ++++++++++- |
| 3 files changed, 23 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
| index 67cfff1586e9f..3f157bcc174b9 100644 |
| --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
| +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
| @@ -3146,9 +3146,11 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) |
| write_i2c_redriver_setting(pipe_ctx, false); |
| } |
| } |
| - dc->hwss.disable_stream(pipe_ctx); |
| |
| disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); |
| + |
| + dc->hwss.disable_stream(pipe_ctx); |
| + |
| if (pipe_ctx->stream->timing.flags.DSC) { |
| if (dc_is_dp_signal(pipe_ctx->stream->signal)) |
| dp_set_dsc_enable(pipe_ctx, false); |
| diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c |
| index caa090d0b6acc..1ada01322cd2c 100644 |
| --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c |
| +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c |
| @@ -1103,6 +1103,10 @@ static inline enum link_training_result perform_link_training_int( |
| dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE; |
| dpcd_set_training_pattern(link, dpcd_pattern); |
| |
| + /* delay 5ms after notifying sink of idle pattern before switching output */ |
| + if (link->connector_signal != SIGNAL_TYPE_EDP) |
| + msleep(5); |
| + |
| /* 4. mainlink output idle pattern*/ |
| dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); |
| |
| @@ -1552,6 +1556,12 @@ bool perform_link_training_with_retries( |
| struct dc_link *link = stream->link; |
| enum dp_panel_mode panel_mode = dp_get_panel_mode(link); |
| |
| + /* We need to do this before the link training to ensure the idle pattern in SST |
| + * mode will be sent right after the link training |
| + */ |
| + link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, |
| + pipe_ctx->stream_res.stream_enc->id, true); |
| + |
| for (j = 0; j < attempts; ++j) { |
| |
| dp_enable_link_phy( |
| @@ -1568,12 +1578,6 @@ bool perform_link_training_with_retries( |
| |
| dp_set_panel_mode(link, panel_mode); |
| |
| - /* We need to do this before the link training to ensure the idle pattern in SST |
| - * mode will be sent right after the link training |
| - */ |
| - link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, |
| - pipe_ctx->stream_res.stream_enc->id, true); |
| - |
| if (link->aux_access_disabled) { |
| dc_link_dp_perform_link_training_skip_aux(link, link_setting); |
| return true; |
| diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c |
| index 10527593868cc..24ca592c90df5 100644 |
| --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c |
| +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c |
| @@ -1090,8 +1090,17 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) |
| dc_link_set_abm_disable(link); |
| } |
| |
| - if (dc_is_dp_signal(pipe_ctx->stream->signal)) |
| + if (dc_is_dp_signal(pipe_ctx->stream->signal)) { |
| pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); |
| + |
| + /* |
| + * After output is idle pattern some sinks need time to recognize the stream |
| + * has changed or they enter protection state and hang. |
| + */ |
| + if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) |
| + msleep(60); |
| + } |
| + |
| } |
| |
| |
| -- |
| 2.25.1 |
| |