Commit d5ce4313 authored by Jimmy Kizito's avatar Jimmy Kizito Committed by Alex Deucher

drm/amd/display: Do not skip link training on DP quick hot plug

[Why]
When rapidly plugging and unplugging a DP sink, detection link
training can be mistakenly skipped.

This is due to the hotplug processing occurring before the
encoder assignment logic has had a chance to process the removal
of a stream. The encoder that would be used for detection link
training is then erroneously reported as already in use and
detection link training is skipped.

[How]
During hot plug processing, only determine a link encoder to be
unavailable for a particular link if it has been assigned to a
different link.
Reviewed-by: default avatarMeenakshikumar Somasundaram <Meenakshikumar.Somasundaram@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarAgustin Gutierrez Sanchez <agustin.gutierrez@amd.com>
Signed-off-by: default avatarJimmy Kizito <Jimmy.Kizito@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4a0dc87f
...@@ -2863,7 +2863,7 @@ bool dp_verify_link_cap( ...@@ -2863,7 +2863,7 @@ bool dp_verify_link_cap(
link->verified_link_cap = *known_limit_link_setting; link->verified_link_cap = *known_limit_link_setting;
return true; return true;
} else if (link->link_enc && link->dc->res_pool->funcs->link_encs_assign && } else if (link->link_enc && link->dc->res_pool->funcs->link_encs_assign &&
!link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine)) { !link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine, link)) {
link->verified_link_cap = initial_link_settings; link->verified_link_cap = initial_link_settings;
return true; return true;
} }
......
...@@ -488,16 +488,19 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( ...@@ -488,16 +488,19 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
return link_enc; return link_enc;
} }
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id) bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link)
{ {
bool is_avail = true; bool is_avail = true;
int i; int i;
/* Add assigned encoders to list. */ /* An encoder is not available if it has already been assigned to a different endpoint. */
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
struct link_enc_assignment assignment = get_assignment(dc, i); struct link_enc_assignment assignment = get_assignment(dc, i);
struct display_endpoint_id ep_id = (struct display_endpoint_id) {
.link_id = link->link_id,
.ep_type = link->ep_type};
if (assignment.valid && assignment.eng_id == eng_id) { if (assignment.valid && assignment.eng_id == eng_id && !are_ep_ids_equal(&ep_id, &assignment.ep_id)) {
is_avail = false; is_avail = false;
break; break;
} }
......
...@@ -97,7 +97,7 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( ...@@ -97,7 +97,7 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
const struct dc_stream_state *stream); const struct dc_stream_state *stream);
/* Return true if encoder available to use. */ /* Return true if encoder available to use. */
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id); bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link);
/* Returns true if encoder assignments in supplied state pass validity checks. */ /* Returns true if encoder assignments in supplied state pass validity checks. */
bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state); bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment