From: Alvin Lee <alvin.l...@amd.com>

[Description]
- For SubVP transitioning into MPO, we want to
  use a minimal transition to prevent transient
  underflow
- Transitioning a phantom pipe directly into a
  "real" pipe can result in underflow due to the
  HUBP still having it's "phantom" programming
  when HUBP is unblanked (have to wait for next
  VUPDATE of the new OTG)
- Also ensure subvp pipe lock is acquired early
  enough for programming in dc_commit_state_no_check
- When disabling phantom planes, enable phantom OTG
  first so the disable gets the double buffer update

Reviewed-by: Aric Cyr <aric....@amd.com>
Acked-by: Alex Hung <alex.h...@amd.com>
Signed-off-by: Alvin Lee <alvin.l...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 43 +++++++++++-------------
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index d446e6098948..da808996e21d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1054,6 +1054,7 @@ static void disable_dangling_plane(struct dc *dc, struct 
dc_state *context)
        int i, j;
        struct dc_state *dangling_context = dc_create_state(dc);
        struct dc_state *current_ctx;
+       struct pipe_ctx *pipe;
 
        if (dangling_context == NULL)
                return;
@@ -1096,6 +1097,16 @@ static void disable_dangling_plane(struct dc *dc, struct 
dc_state *context)
                }
 
                if (should_disable && old_stream) {
+                       pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+                       /* When disabling plane for a phantom pipe, we must 
turn on the
+                        * phantom OTG so the disable programming gets the 
double buffer
+                        * update. Otherwise the pipe will be left in a 
partially disabled
+                        * state that can result in underflow or hang when 
enabling it
+                        * again for different use.
+                        */
+                       if (old_stream->mall_stream_config.type == 
SUBVP_PHANTOM) {
+                               
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+                       }
                        dc_rem_all_planes_for_stream(dc, old_stream, 
dangling_context);
                        disable_all_writeback_pipes_for_stream(dc, old_stream, 
dangling_context);
 
@@ -1749,6 +1760,12 @@ static enum dc_status dc_commit_state_no_check(struct dc 
*dc, struct dc_state *c
                context->stream_count == 0)
                dc->hwss.prepare_bandwidth(dc, context);
 
+       /* When SubVP is active, all HW programming must be done while
+        * SubVP lock is acquired
+        */
+       if (dc->hwss.subvp_pipe_control_lock)
+               dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, 
subvp_prev_use);
+
        if (dc->debug.enable_double_buffered_dsc_pg_support)
                dc->hwss.update_dsc_pg(dc, context, false);
 
@@ -1776,9 +1793,6 @@ static enum dc_status dc_commit_state_no_check(struct dc 
*dc, struct dc_state *c
                dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
        }
 
-       if (dc->hwss.subvp_pipe_control_lock)
-               dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, 
subvp_prev_use);
-
        result = dc->hwss.apply_ctx_to_hw(dc, context);
 
        if (result != DC_OK) {
@@ -3675,7 +3689,6 @@ static bool 
could_mpcc_tree_change_for_active_pipes(struct dc *dc,
 
        struct dc_stream_status *cur_stream_status = 
stream_get_status(dc->current_state, stream);
        bool force_minimal_pipe_splitting = false;
-       uint32_t i;
 
        *is_plane_addition = false;
 
@@ -3707,27 +3720,11 @@ static bool 
could_mpcc_tree_change_for_active_pipes(struct dc *dc,
                }
        }
 
-       /* For SubVP pipe split case when adding MPO video
-        * we need to add a minimal transition. In this case
-        * there will be 2 streams (1 main stream, 1 phantom
-        * stream).
+       /* For SubVP when adding MPO video we need to add a minimal transition.
         */
-       if (cur_stream_status &&
-                       dc->current_state->stream_count == 2 &&
-                       stream->mall_stream_config.type == SUBVP_MAIN) {
-               bool is_pipe_split = false;
-
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       if (dc->current_state->res_ctx.pipe_ctx[i].stream == 
stream &&
-                                       
(dc->current_state->res_ctx.pipe_ctx[i].bottom_pipe ||
-                                       
dc->current_state->res_ctx.pipe_ctx[i].next_odm_pipe)) {
-                               is_pipe_split = true;
-                               break;
-                       }
-               }
-
+       if (cur_stream_status && stream->mall_stream_config.type == SUBVP_MAIN) 
{
                /* determine if minimal transition is required due to SubVP*/
-               if (surface_count > 0 && is_pipe_split) {
+               if (surface_count > 0) {
                        if (cur_stream_status->plane_count > surface_count) {
                                force_minimal_pipe_splitting = true;
                        } else if (cur_stream_status->plane_count < 
surface_count) {
-- 
2.38.1

Reply via email to