Commit 5ca3dc2b authored by Cruise Hung's avatar Cruise Hung Committed by Alex Deucher

drm/amd/display: Fix DPIA link encoder assignment issue

[Why]
The DPIA link encoder (DIG) was not released when a Display XDR 6K
monitor was disconnected. That's because the DPIA link encoder logic
checked the BW when it removed the link encoder for it. And the timing
BW was less than DP link BW.  So, it failed to release the link encoder.
And that caused the DIG was occupied and can't be used.  The reason it
checked the BW is it wants to identify whether this link was using DIG
or HPO. It skips if it's not DIG.

[How]
Not to check the BW when it removes the link encoder because it's
already in the assignment table, it must be the DIG.
Tested-by: default avatarDaniel Wheeler <Daniel.Wheeler@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarCruise Hung <Cruise.Hung@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 01506614
......@@ -305,15 +305,17 @@ void link_enc_cfg_link_encs_assign(
for (i = 0; i < stream_count; i++) {
struct dc_stream_state *stream = streams[i];
/* skip it if the link is mappable endpoint. */
if (stream->link->is_dig_mapping_flexible)
continue;
/* Skip stream if not supported by DIG link encoder. */
if (!is_dig_link_enc_stream(stream))
continue;
/* Physical endpoints have a fixed mapping to DIG link encoders. */
if (!stream->link->is_dig_mapping_flexible) {
eng_id = stream->link->eng_id;
add_link_enc_assignment(state, stream, eng_id);
}
eng_id = stream->link->eng_id;
add_link_enc_assignment(state, stream, eng_id);
}
/* (b) Retain previous assignments for mappable endpoints if encoders still available. */
......@@ -325,11 +327,12 @@ void link_enc_cfg_link_encs_assign(
for (i = 0; i < stream_count; i++) {
struct dc_stream_state *stream = state->streams[i];
/* Skip stream if not supported by DIG link encoder. */
if (!is_dig_link_enc_stream(stream))
/* Skip it if the link is NOT mappable endpoint. */
if (!stream->link->is_dig_mapping_flexible)
continue;
if (!stream->link->is_dig_mapping_flexible)
/* Skip stream if not supported by DIG link encoder. */
if (!is_dig_link_enc_stream(stream))
continue;
for (j = 0; j < prev_state->stream_count; j++) {
......@@ -338,6 +341,7 @@ void link_enc_cfg_link_encs_assign(
if (stream == prev_stream && stream->link == prev_stream->link &&
prev_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j].valid) {
eng_id = prev_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j].eng_id;
if (is_avail_link_enc(state, eng_id, stream))
add_link_enc_assignment(state, stream, eng_id);
}
......@@ -350,6 +354,15 @@ void link_enc_cfg_link_encs_assign(
for (i = 0; i < stream_count; i++) {
struct dc_stream_state *stream = streams[i];
struct link_encoder *link_enc = NULL;
/* Skip it if the link is NOT mappable endpoint. */
if (!stream->link->is_dig_mapping_flexible)
continue;
/* Skip if encoder assignment retained in step (b) above. */
if (stream->link_enc)
continue;
/* Skip stream if not supported by DIG link encoder. */
if (!is_dig_link_enc_stream(stream)) {
......@@ -358,24 +371,18 @@ void link_enc_cfg_link_encs_assign(
}
/* Mappable endpoints have a flexible mapping to DIG link encoders. */
if (stream->link->is_dig_mapping_flexible) {
struct link_encoder *link_enc = NULL;
/* Skip if encoder assignment retained in step (b) above. */
if (stream->link_enc)
continue;
/* For MST, multiple streams will share the same link / display
* endpoint. These streams should use the same link encoder
* assigned to that endpoint.
*/
link_enc = get_link_enc_used_by_link(state, stream->link);
if (link_enc == NULL)
eng_id = find_first_avail_link_enc(stream->ctx, state);
else
eng_id = link_enc->preferred_engine;
/* For MST, multiple streams will share the same link / display
* endpoint. These streams should use the same link encoder
* assigned to that endpoint.
*/
link_enc = get_link_enc_used_by_link(state, stream->link);
if (link_enc == NULL)
eng_id = find_first_avail_link_enc(stream->ctx, state);
else
eng_id = link_enc->preferred_engine;
add_link_enc_assignment(state, stream, eng_id);
}
add_link_enc_assignment(state, stream, eng_id);
}
link_enc_cfg_validate(dc, state);
......@@ -420,10 +427,6 @@ void link_enc_cfg_link_enc_unassign(
{
enum engine_id eng_id = ENGINE_ID_UNKNOWN;
/* Only DIG link encoders. */
if (!is_dig_link_enc_stream(stream))
return;
if (stream->link_enc)
eng_id = stream->link_enc->preferred_engine;
......
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