From: Jimmy Kizito <Jimmy.Kizito@xxxxxxx> [Why] Some display endpoints may be dynamically mapped to the link encoders which drive them. [How] Update the code paths for display enabling/disabling to accommodate the dynamic association between links and link encoders. Signed-off-by: Jimmy Kizito <Jimmy.Kizito@xxxxxxx> Reviewed-by: Jun Lei <Jun.Lei@xxxxxxx> Acked-by: Anson Jacob <Anson.Jacob@xxxxxxx> --- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 15 ++- .../drm/amd/display/dc/core/dc_link_enc_cfg.c | 99 +++++++++++++++++++ .../drm/amd/display/dc/core/dc_link_hwss.c | 22 ++++- .../gpu/drm/amd/display/dc/inc/link_enc_cfg.h | 18 ++++ 4 files changed, 146 insertions(+), 8 deletions(-) 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 cebf68200f43..0b8082a15e24 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 @@ -1728,11 +1728,16 @@ bool perform_link_training_with_retries( if (link->aux_access_disabled) { dc_link_dp_perform_link_training_skip_aux(link, link_setting); return true; - } else if (dc_link_dp_perform_link_training( - link, - link_setting, - skip_video_pattern) == LINK_TRAINING_SUCCESS) - return true; + } else { + enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0; + + status = dc_link_dp_perform_link_training( + link, + link_setting, + skip_video_pattern); + if (status == LINK_TRAINING_SUCCESS) + return true; + } /* latest link training still fail, skip delay and keep PHY on */ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index c2bf9e5d9675..1361b87d86d7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -127,6 +127,32 @@ static enum engine_id find_first_avail_link_enc( return eng_id; } +/* Return stream using DIG link encoder resource. NULL if unused. */ +static struct dc_stream_state *get_stream_using_link_enc( + struct dc_state *state, + enum engine_id eng_id) +{ + struct dc_stream_state *stream = NULL; + int stream_idx = -1; + int i; + + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; + + if (assignment.valid && (assignment.eng_id == eng_id)) { + stream_idx = i; + break; + } + } + + if (stream_idx != -1) + stream = state->streams[stream_idx]; + else + dm_output_to_console("%s: No stream using DIG(%d).\n", __func__, eng_id); + + return stream; +} + void link_enc_cfg_init( struct dc *dc, struct dc_state *state) @@ -202,3 +228,76 @@ void link_enc_cfg_link_enc_unassign( update_link_enc_assignment(state, stream, eng_id, false); } + +bool link_enc_cfg_is_transmitter_mappable( + struct dc_state *state, + struct link_encoder *link_enc) +{ + bool is_mappable = false; + enum engine_id eng_id = link_enc->preferred_engine; + struct dc_stream_state *stream = get_stream_using_link_enc(state, eng_id); + + if (stream) + is_mappable = stream->link->is_dig_mapping_flexible; + + return is_mappable; +} + +struct dc_link *link_enc_cfg_get_link_using_link_enc( + struct dc_state *state, + enum engine_id eng_id) +{ + struct dc_link *link = NULL; + int stream_idx = -1; + int i; + + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; + + if (assignment.valid && (assignment.eng_id == eng_id)) { + stream_idx = i; + break; + } + } + + if (stream_idx != -1) + link = state->streams[stream_idx]->link; + else + dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id); + + return link; +} + +struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( + struct dc_state *state, + struct dc_link *link) +{ + struct link_encoder *link_enc = NULL; + struct display_endpoint_id ep_id; + int stream_idx = -1; + int i; + + ep_id = (struct display_endpoint_id) { + .link_id = link->link_id, + .ep_type = link->ep_type}; + + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; + + if (assignment.valid && + assignment.ep_id.link_id.id == ep_id.link_id.id && + assignment.ep_id.link_id.enum_id == ep_id.link_id.enum_id && + assignment.ep_id.link_id.type == ep_id.link_id.type && + assignment.ep_id.ep_type == ep_id.ep_type) { + stream_idx = i; + break; + } + } + + if (stream_idx != -1) + link_enc = state->streams[stream_idx]->link_enc; + else + dm_output_to_console("%s: No link encoder used by link(%d).\n", __func__, link->link_index); + + return link_enc; +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 22fe19ee842d..48ad1a8d4a74 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -14,6 +14,7 @@ #include "dpcd_defs.h" #include "dsc.h" #include "resource.h" +#include "link_enc_cfg.h" #include "clk_mgr.h" static uint8_t convert_to_count(uint8_t lttpr_repeater_count) @@ -95,7 +96,7 @@ void dp_enable_link_phy( enum clock_source_id clock_source, const struct dc_link_settings *link_settings) { - struct link_encoder *link_enc = link->link_enc; + struct link_encoder *link_enc; struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; @@ -105,6 +106,13 @@ void dp_enable_link_phy( link->dc->res_pool->dp_clock_source; unsigned int i; + /* Link should always be assigned encoder when en-/disabling. */ + if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign) + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); + else + link_enc = link->link_enc; + ASSERT(link_enc); + if (link->connector_signal == SIGNAL_TYPE_EDP) { link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); @@ -227,6 +235,14 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; + struct link_encoder *link_enc; + + /* Link should always be assigned encoder when en-/disabling. */ + if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign) + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); + else + link_enc = link->link_enc; + ASSERT(link_enc); if (!link->wa_flags.dp_keep_receiver_powered) dp_receiver_power_ctrl(link, false); @@ -234,13 +250,13 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) if (signal == SIGNAL_TYPE_EDP) { if (link->dc->hwss.edp_backlight_control) link->dc->hwss.edp_backlight_control(link, false); - link->link_enc->funcs->disable_output(link->link_enc, signal); + link_enc->funcs->disable_output(link_enc, signal); link->dc->hwss.edp_power_control(link, false); } else { if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); - link->link_enc->funcs->disable_output(link->link_enc, signal); + link_enc->funcs->disable_output(link_enc, signal); if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h index ad641632eadd..7d36e55f3097 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h @@ -65,4 +65,22 @@ void link_enc_cfg_link_enc_unassign( struct dc_state *state, struct dc_stream_state *stream); +/* + * Check whether the transmitter driven by a link encoder is a mappable + * endpoint. + */ +bool link_enc_cfg_is_transmitter_mappable( + struct dc_state *state, + struct link_encoder *link_enc); + +/* Return link using DIG link encoder resource. NULL if unused. */ +struct dc_link *link_enc_cfg_get_link_using_link_enc( + struct dc_state *state, + enum engine_id eng_id); + +/* Return DIG link encoder used by link. NULL if unused. */ +struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( + struct dc_state *state, + struct dc_link *link); + #endif /* DC_INC_LINK_ENC_CFG_H_ */ -- 2.25.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx