Skip to content

Commit

Permalink
drm/amd/display: Fix dynamic encoder reassignment
Browse files Browse the repository at this point in the history
BugLink: https://bugs.launchpad.net/bugs/1951868

[Why]
Incorrect encoder assignments were being used while applying a new state
to hardware.

(1) When committing a new state to hardware requires resetting the
back-end, the encoder assignments of the current or old state should be
used when disabling the back-end; and the encoder assignments for the
next or new state should be used when re-enabling the back-end.

(2) Link training on hot plug could take over an encoder already in use
by another stream without first disabling it.

[How]

(1) Introduce a resource context 'link_enc_cfg_context' which includes:
- a mode to indicate when transitioning from current to next state.
- transient encoder assignments to use during this state transition.

Update the encoder configuration interface to respond to queries about
encoder assignment based on the mode of operation.

(2) Check if an encoder is already in use before attempting to perform
link training on hot plug.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(backported from commit 0d4b425)
Signed-off-by: Timo Aaltonen <timo.aaltonen@canonical.com>
  • Loading branch information
Jimmy Kizito authored and Timo Aaltonen committed Dec 3, 2021
1 parent a09aa63 commit 2677b94
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 89 deletions.
16 changes: 6 additions & 10 deletions drivers/gpu/drm/amd/display/dc/core/dc_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -3331,11 +3331,8 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
link_enc = pipe_ctx->stream->link->link_enc;
config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
} else if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) {
/* Use link encoder assignment from current DC state - which may differ from the DC state to be
* committed - when updating PSP config.
*/
link_enc = link_enc_cfg_get_link_enc_used_by_stream(
pipe_ctx->stream->link->dc->current_state,
pipe_ctx->stream->ctx->dc,
pipe_ctx->stream);
config.phy_idx = 0; /* Clear phy_idx for non-physical display endpoints. */
}
Expand Down Expand Up @@ -3371,9 +3368,8 @@ void core_link_enable_stream(
dc_is_virtual_signal(pipe_ctx->stream->signal))
return;

if (dc->res_pool->funcs->link_encs_assign &&
stream->link->ep_type != DISPLAY_ENDPOINT_PHY)
link_enc = stream->link_enc;
if (dc->res_pool->funcs->link_encs_assign && stream->link->ep_type != DISPLAY_ENDPOINT_PHY)
link_enc = link_enc_cfg_get_link_enc_used_by_stream(dc, stream);
else
link_enc = stream->link->link_enc;
ASSERT(link_enc);
Expand Down Expand Up @@ -3903,14 +3899,14 @@ bool dc_link_is_fec_supported(const struct dc_link *link)
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
} else
link_enc = link->link_enc;
ASSERT(link_enc);

return (dc_is_dp_signal(link->connector_signal) &&
return (dc_is_dp_signal(link->connector_signal) && link_enc &&
link_enc->features.fec_supported &&
link->dpcd_caps.fec_cap.bits.FEC_CAPABLE &&
!IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment));
Expand Down
25 changes: 15 additions & 10 deletions drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc);
Expand Down Expand Up @@ -1781,7 +1781,7 @@ bool perform_link_training_with_retries(
* link.
*/
if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign)
link_enc = stream->link_enc;
link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
else
link_enc = link->link_enc;

Expand Down Expand Up @@ -2043,9 +2043,9 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
} else
link_enc = link->link_enc;
ASSERT(link_enc);
Expand All @@ -2071,9 +2071,9 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
} else
link_enc = link->link_enc;
ASSERT(link_enc);
Expand Down Expand Up @@ -2243,7 +2243,13 @@ bool dp_verify_link_cap(
enum link_training_result status;
union hpd_irq_data irq_data;

if (link->dc->debug.skip_detection_link_training) {
/* Accept reported capabilities if link supports flexible encoder mapping or encoder already in use. */
if (link->dc->debug.skip_detection_link_training ||
link->is_dig_mapping_flexible) {
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->verified_link_cap = *known_limit_link_setting;
return true;
}
Expand Down Expand Up @@ -4716,7 +4722,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready)
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc);
Expand Down Expand Up @@ -4763,8 +4769,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(
link->dc->current_state, link);
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc);
Expand Down
Loading

0 comments on commit 2677b94

Please sign in to comment.