diff options
author | Jimmy Kizito <Jimmy.Kizito@amd.com> | 2021-09-22 09:50:38 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-10-19 17:17:39 -0400 |
commit | d5ce4313cca480308ee0b41a1a0e223e4ba8a0ff (patch) | |
tree | bca55441e39f814747c71395208c447fc7cdf47c /drivers/gpu/drm | |
parent | 4a0dc87fca19c51421a8ef5ca086f57898447c70 (diff) | |
download | linux-d5ce4313cca480308ee0b41a1a0e223e4ba8a0ff.tar.bz2 |
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: Meenakshikumar Somasundaram <Meenakshikumar.Somasundaram@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Agustin Gutierrez Sanchez <agustin.gutierrez@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h | 2 |
3 files changed, 8 insertions, 5 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 54662d74c65a..8e0b40c7a1ee 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 @@ -2863,7 +2863,7 @@ bool dp_verify_link_cap( link->verified_link_cap = *known_limit_link_setting; return true; } 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; return true; } 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 1cab4bf06abe..72b0f8594b4a 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 @@ -488,16 +488,19 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( 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; 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++) { 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; break; } 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 83b2199b2c83..10dcf6a5e9b1 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 @@ -97,7 +97,7 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( const struct dc_stream_state *stream); /* 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. */ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state); |