drm/amd/display: Don't overwrite subvp pipe info in fast updates
authorAlvin Lee <Alvin.Lee2@amd.com>
Fri, 18 Nov 2022 18:49:11 +0000 (13:49 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 29 Nov 2022 16:03:38 +0000 (11:03 -0500)
[Description]
- This is a workaround to avoid concurrency issues -- a fast update
  creates a shallow copy of the dc current_state, and removes all
  subvp/phantom related flags.
- We want to prevent the fast update thread from removing those
  flags in case there's another thread running that requires
  the info for proper programming

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Jasdeep Dhillon <jdhillon@amd.com>
Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
drivers/gpu/drm/amd/display/dc/inc/core_types.h

index f9b8b6f6fd3118514e163345ebdb7d3e746ad39d..5e08922a8a66c7ca359867845c9833aa6ddd3ae7 100644 (file)
@@ -3061,7 +3061,7 @@ static bool update_planes_and_stream_state(struct dc *dc,
                 * Ensures that we have enough pipes for newly added MPO planes
                 */
                if (dc->res_pool->funcs->remove_phantom_pipes)
-                       dc->res_pool->funcs->remove_phantom_pipes(dc, context);
+                       dc->res_pool->funcs->remove_phantom_pipes(dc, context, false);
 
                /*remove old surfaces from context */
                if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
index 99ddd2232322cfb5c13b5d3f3b517e43b630b56b..67b43e7ee0efc7676552689866c7f944a5609e2c 100644 (file)
@@ -1743,7 +1743,7 @@ void dcn32_retain_phantom_pipes(struct dc *dc, struct dc_state *context)
 }
 
 // return true if removed piped from ctx, false otherwise
-bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
+bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context, bool fast_update)
 {
        int i;
        bool removed_pipe = false;
@@ -1770,14 +1770,23 @@ bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
                        removed_pipe = true;
                }
 
-               // Clear all phantom stream info
-               if (pipe->stream) {
-                       pipe->stream->mall_stream_config.type = SUBVP_NONE;
-                       pipe->stream->mall_stream_config.paired_stream = NULL;
-               }
+               /* For non-full updates, a shallow copy of the current state
+                * is created. In this case we don't want to erase the current
+                * state (there can be 2 HIRQL threads, one in flip, and one in
+                * checkMPO) that can cause a race condition.
+                *
+                * This is just a workaround, needs a proper fix.
+                */
+               if (!fast_update) {
+                       // Clear all phantom stream info
+                       if (pipe->stream) {
+                               pipe->stream->mall_stream_config.type = SUBVP_NONE;
+                               pipe->stream->mall_stream_config.paired_stream = NULL;
+                       }
 
-               if (pipe->plane_state) {
-                       pipe->plane_state->is_phantom = false;
+                       if (pipe->plane_state) {
+                               pipe->plane_state->is_phantom = false;
+                       }
                }
        }
        return removed_pipe;
@@ -1950,23 +1959,28 @@ int dcn32_populate_dml_pipes_from_context(
                pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
                pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19;
 
-               switch (pipe->stream->mall_stream_config.type) {
-               case SUBVP_MAIN:
-                       pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_sub_viewport;
-                       subvp_in_use = true;
-                       break;
-               case SUBVP_PHANTOM:
-                       pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_phantom_pipe;
-                       pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
-                       // Disallow unbounded req for SubVP according to DCHUB programming guide
-                       pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
-                       break;
-               case SUBVP_NONE:
-                       pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_disable;
-                       pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
-                       break;
-               default:
-                       break;
+               /* Only populate DML input with subvp info for full updates.
+                * This is just a workaround -- needs a proper fix.
+                */
+               if (!fast_validate) {
+                       switch (pipe->stream->mall_stream_config.type) {
+                       case SUBVP_MAIN:
+                               pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_sub_viewport;
+                               subvp_in_use = true;
+                               break;
+                       case SUBVP_PHANTOM:
+                               pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_phantom_pipe;
+                               pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
+                               // Disallow unbounded req for SubVP according to DCHUB programming guide
+                               pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
+                               break;
+                       case SUBVP_NONE:
+                               pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_disable;
+                               pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
+                               break;
+                       default:
+                               break;
+                       }
                }
 
                pipes[pipe_cnt].dout.dsc_input_bpc = 0;
index c50bb34b515ffe737c3494993a1970f0f9344a98..d4a37f3d79998c41af805312cdb3e611a17170b0 100644 (file)
@@ -81,7 +81,7 @@ bool dcn32_release_post_bldn_3dlut(
                struct dc_transfer_func **shaper);
 
 bool dcn32_remove_phantom_pipes(struct dc *dc,
-               struct dc_state *context);
+               struct dc_state *context, bool fast_update);
 
 void dcn32_retain_phantom_pipes(struct dc *dc,
                struct dc_state *context);
index ac324ce115973619f1b285305b22285001895d9a..f94abd124021ed33af67c9423a31684f9a17d087 100644 (file)
@@ -1203,7 +1203,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
                // If SubVP pipe config is unsupported (or cannot be used for UCLK switching)
                // remove phantom pipes and repopulate dml pipes
                if (!found_supported_config) {
-                       dc->res_pool->funcs->remove_phantom_pipes(dc, context);
+                       dc->res_pool->funcs->remove_phantom_pipes(dc, context, false);
                        vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] = dm_dram_clock_change_unsupported;
                        *pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, false);
 
@@ -1518,7 +1518,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
                return false;
 
        // For each full update, remove all existing phantom pipes first
-       dc->res_pool->funcs->remove_phantom_pipes(dc, context);
+       dc->res_pool->funcs->remove_phantom_pipes(dc, context, fast_validate);
 
        dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
 
index aac1b3989c95076fb720c4f38d97cc3ed157b64f..108bffb9a73ad3d6a8dd2e01c3a23233cfea5bca 100644 (file)
@@ -240,7 +240,7 @@ struct resource_funcs {
                        unsigned int pipe_cnt,
             unsigned int index);
 
-       bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context);
+       bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context, bool fast_update);
        void (*retain_phantom_pipes)(struct dc *dc, struct dc_state *context);
        void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
 };