drm/amd/display: Improve DisplayPort monitor interop
[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>
This commit is contained in:
parent
a96562b018
commit
eec3303de3
|
@ -3309,9 +3309,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);
|
||||
|
|
|
@ -1102,6 +1102,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);
|
||||
|
||||
|
@ -1551,6 +1555,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(
|
||||
|
@ -1559,21 +1569,14 @@ bool perform_link_training_with_retries(
|
|||
pipe_ctx->clock_source->id,
|
||||
link_setting);
|
||||
|
||||
if ((link && link->dc->debug.dppowerup_delay > 0) || stream->sink_patches.dppowerup_delay > 0) {
|
||||
int delay_dp_power_up_in_ms =
|
||||
(link->dc->debug.dppowerup_delay >= stream->sink_patches.dppowerup_delay) ?
|
||||
link->dc->debug.dppowerup_delay : stream->sink_patches.dppowerup_delay;
|
||||
if (stream->sink_patches.dppowerup_delay > 0) {
|
||||
int delay_dp_power_up_in_ms = stream->sink_patches.dppowerup_delay;
|
||||
|
||||
msleep(delay_dp_power_up_in_ms);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -498,7 +498,6 @@ struct dc_debug_options {
|
|||
bool usbc_combo_phy_reset_wa;
|
||||
bool disable_dsc;
|
||||
bool enable_dram_clock_change_one_display_vactive;
|
||||
unsigned int dppowerup_delay;
|
||||
};
|
||||
|
||||
struct dc_debug_data {
|
||||
|
|
|
@ -1069,8 +1069,17 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
|
|||
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue