]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
drm/amd/display: fix stale info in link encoder assignment
authorRoy Chan <roy.chan@amd.com>
Tue, 17 May 2022 08:28:00 +0000 (10:28 +0200)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Tue, 31 May 2022 16:30:51 +0000 (18:30 +0200)
BugLink: https://bugs.launchpad.net/bugs/1971417
[Why]
The link encoder assignment leaves the old stream data when it was
unassigned. When the clear encoder assignment is called, it based on the
old stale data to access the de-allocated stream.

[How]
There should be no need to explicitly clean up the link encoder
assignment if the unassign loop does the work properly, the loop should
base on the current state to clean up the assignment.

Also, the unassignment should better clean up the values in the
assignement slots as well.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Anson Jacob <Anson.Jacob@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Roy Chan <roy.chan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit e43098f6abb033142810e695c1b3d9cf61e19849)
Signed-off-by: Koba Ko <koba.ko@canonical.com>
Acked-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c

index 95c60c8a038ff5d2db044ac42258365ad3aa8adf..c6ff6c797d11db61c428189cec9880c851e391ee 100644 (file)
@@ -119,7 +119,10 @@ static void remove_link_enc_assignment(
                                 */
                                if (get_stream_using_link_enc(state, eng_id) == NULL)
                                        state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = eng_id;
+
                                stream->link_enc = NULL;
+                               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN;
+                               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL;
                                break;
                        }
                }
@@ -224,28 +227,15 @@ static struct link_encoder *get_link_enc_used_by_link(
        return link_enc;
 }
 /* Clear all link encoder assignments. */
-static void clear_enc_assignments(struct dc_state *state)
+static void clear_enc_assignments(struct dc *dc, struct dc_state *state)
 {
        int i;
-       enum engine_id eng_id;
-       struct dc_stream_state *stream;
 
        for (i = 0; i < MAX_PIPES; i++) {
                state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false;
-               eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id;
-               stream = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream;
-               if (eng_id != ENGINE_ID_UNKNOWN)
-                       state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_id - ENGINE_ID_DIGA] = eng_id;
-               if (stream)
-                       stream->link_enc = NULL;
+               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN;
+               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL;
        }
-}
-
-void link_enc_cfg_init(
-               struct dc *dc,
-               struct dc_state *state)
-{
-       int i;
 
        for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) {
                if (dc->res_pool->link_encoders[i])
@@ -253,8 +243,13 @@ void link_enc_cfg_init(
                else
                        state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN;
        }
+}
 
-       clear_enc_assignments(state);
+void link_enc_cfg_init(
+               struct dc *dc,
+               struct dc_state *state)
+{
+       clear_enc_assignments(dc, state);
 
        state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
 }
@@ -271,12 +266,9 @@ void link_enc_cfg_link_encs_assign(
 
        ASSERT(state->stream_count == stream_count);
 
-       if (stream_count == 0)
-               clear_enc_assignments(state);
-
        /* Release DIG link encoder resources before running assignment algorithm. */
-       for (i = 0; i < stream_count; i++)
-               dc->res_pool->funcs->link_enc_unassign(state, streams[i]);
+       for (i = 0; i < dc->current_state->stream_count; i++)
+               dc->res_pool->funcs->link_enc_unassign(state, dc->current_state->streams[i]);
 
        for (i = 0; i < MAX_PIPES; i++)
                ASSERT(state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid == false);