From: Peterson Guo <peterson....@amd.com>

[ Upstream commit 3c50bf2196aaddcaffe2c7a1a7080470380cbfdd ]

[WHY]
When checking if a pipe can disable cursor to prevent duplicate cursors,
having visual confirm on will prevent disabling cursors on planes which
cover the bottom of the screen.

[HOW]
When checking if a plane can disable visual confirm, the pipe first
reverses these calculations before doing the checks.

Reviewed-by: Alvin Lee <alvin.l...@amd.com>
Signed-off-by: Peterson Guo <peterson....@amd.com>
Signed-off-by: Wayne Lin <wayne....@amd.com>
Tested-by: Daniel Wheeler <daniel.whee...@amd.com>
Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 67 +++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 50 +-------------
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c   | 48 +------------
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 48 +------------
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  2 +
 5 files changed, 73 insertions(+), 142 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 3367030da3414..375b3b1d1d182 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -941,6 +941,17 @@ static void 
calculate_adjust_recout_for_visual_confirm(struct pipe_ctx *pipe_ctx
                *base_offset = VISUAL_CONFIRM_BASE_DEFAULT;
 }
 
+static void reverse_adjust_recout_for_visual_confirm(struct rect *recout,
+               struct pipe_ctx *pipe_ctx)
+{
+       int dpp_offset, base_offset;
+
+       calculate_adjust_recout_for_visual_confirm(pipe_ctx, &base_offset,
+               &dpp_offset);
+       recout->height += base_offset;
+       recout->height += dpp_offset;
+}
+
 static void adjust_recout_for_visual_confirm(struct rect *recout,
                struct pipe_ctx *pipe_ctx)
 {
@@ -1642,6 +1653,62 @@ bool resource_build_scaling_params(struct pipe_ctx 
*pipe_ctx)
        return res;
 }
 
+bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *test_pipe, *split_pipe;
+       struct rect r1 = pipe_ctx->plane_res.scl_data.recout;
+       int r1_right, r1_bottom;
+       int cur_layer = pipe_ctx->plane_state->layer_index;
+
+       reverse_adjust_recout_for_visual_confirm(&r1, pipe_ctx);
+       r1_right = r1.x + r1.width;
+       r1_bottom = r1.y + r1.height;
+
+       /**
+        * Disable the cursor if there's another pipe above this with a
+        * plane that contains this pipe's viewport to prevent double cursor
+        * and incorrect scaling artifacts.
+        */
+       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
+            test_pipe = test_pipe->top_pipe) {
+               struct rect r2;
+               int r2_right, r2_bottom;
+               // Skip invisible layer and pipe-split plane on same layer
+               if (!test_pipe->plane_state ||
+                   !test_pipe->plane_state->visible ||
+                   test_pipe->plane_state->layer_index == cur_layer)
+                       continue;
+
+               r2 = test_pipe->plane_res.scl_data.recout;
+               reverse_adjust_recout_for_visual_confirm(&r2, test_pipe);
+               r2_right = r2.x + r2.width;
+               r2_bottom = r2.y + r2.height;
+
+               /**
+                * There is another half plane on same layer because of
+                * pipe-split, merge together per same height.
+                */
+               for (split_pipe = pipe_ctx->top_pipe; split_pipe;
+                    split_pipe = split_pipe->top_pipe)
+                       if (split_pipe->plane_state->layer_index == 
test_pipe->plane_state->layer_index) {
+                               struct rect r2_half;
+
+                               r2_half = split_pipe->plane_res.scl_data.recout;
+                               
reverse_adjust_recout_for_visual_confirm(&r2_half, split_pipe);
+                               r2.x = min(r2_half.x, r2.x);
+                               r2.width = r2.width + r2_half.width;
+                               r2_right = r2.x + r2.width;
+                               r2_bottom = min(r2_bottom, r2_half.y + 
r2_half.height);
+                               break;
+                       }
+
+               if (r1.x >= r2.x && r1.y >= r2.y && r1_right <= r2_right && 
r1_bottom <= r2_bottom)
+                       return true;
+       }
+
+       return false;
+}
+
 
 enum dc_status resource_build_scaling_params_for_context(
        const struct dc  *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 44ff9abe2880f..87b4c2793df3c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -991,57 +991,11 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv 
*dc_dmub_srv)
        DC_LOG_DEBUG("    is_cw6_en          : %d", diag_data.is_cw6_enabled);
 }
 
-static bool dc_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *test_pipe, *split_pipe;
-       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
-       struct rect r1 = scl_data->recout, r2, r2_half;
-       int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
-       int cur_layer = pipe_ctx->plane_state->layer_index;
-
-       /**
-        * Disable the cursor if there's another pipe above this with a
-        * plane that contains this pipe's viewport to prevent double cursor
-        * and incorrect scaling artifacts.
-        */
-       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
-            test_pipe = test_pipe->top_pipe) {
-               // Skip invisible layer and pipe-split plane on same layer
-               if (!test_pipe->plane_state->visible || 
test_pipe->plane_state->layer_index == cur_layer)
-                       continue;
-
-               r2 = test_pipe->plane_res.scl_data.recout;
-               r2_r = r2.x + r2.width;
-               r2_b = r2.y + r2.height;
-
-               /**
-                * There is another half plane on same layer because of
-                * pipe-split, merge together per same height.
-                */
-               for (split_pipe = pipe_ctx->top_pipe; split_pipe;
-                    split_pipe = split_pipe->top_pipe)
-                       if (split_pipe->plane_state->layer_index == 
test_pipe->plane_state->layer_index) {
-                               r2_half = split_pipe->plane_res.scl_data.recout;
-                               r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
-                               r2.width = r2.width + r2_half.width;
-                               r2_r = r2.x + r2.width;
-                               break;
-                       }
-
-               if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= 
r2_b)
-                       return true;
-       }
-
-       return false;
-}
-
 static bool dc_dmub_should_update_cursor_data(struct pipe_ctx *pipe_ctx)
 {
        if (pipe_ctx->plane_state != NULL) {
-               if (pipe_ctx->plane_state->address.type == 
PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
-                       return false;
-
-               if (dc_can_pipe_disable_cursor(pipe_ctx))
+               if (pipe_ctx->plane_state->address.type == 
PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
+                       resource_can_pipe_disable_cursor(pipe_ctx))
                        return false;
        }
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index 4c89bf6725b3b..bbeaefe1ef0db 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -3424,52 +3424,6 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct 
dchub_init_data *dh_data)
        hubbub->funcs->update_dchub(hubbub, dh_data);
 }
 
-static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *test_pipe, *split_pipe;
-       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
-       struct rect r1 = scl_data->recout, r2, r2_half;
-       int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
-       int cur_layer = pipe_ctx->plane_state->layer_index;
-
-       /**
-        * Disable the cursor if there's another pipe above this with a
-        * plane that contains this pipe's viewport to prevent double cursor
-        * and incorrect scaling artifacts.
-        */
-       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
-            test_pipe = test_pipe->top_pipe) {
-               // Skip invisible layer and pipe-split plane on same layer
-               if (!test_pipe->plane_state ||
-                   !test_pipe->plane_state->visible ||
-                   test_pipe->plane_state->layer_index == cur_layer)
-                       continue;
-
-               r2 = test_pipe->plane_res.scl_data.recout;
-               r2_r = r2.x + r2.width;
-               r2_b = r2.y + r2.height;
-
-               /**
-                * There is another half plane on same layer because of
-                * pipe-split, merge together per same height.
-                */
-               for (split_pipe = pipe_ctx->top_pipe; split_pipe;
-                    split_pipe = split_pipe->top_pipe)
-                       if (split_pipe->plane_state->layer_index == 
test_pipe->plane_state->layer_index) {
-                               r2_half = split_pipe->plane_res.scl_data.recout;
-                               r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
-                               r2.width = r2.width + r2_half.width;
-                               r2_r = r2.x + r2.width;
-                               break;
-                       }
-
-               if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= 
r2_b)
-                       return true;
-       }
-
-       return false;
-}
-
 void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
 {
        struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
@@ -3569,7 +3523,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
                        == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
                pos_cpy.enable = false;
 
-       if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
+       if (pos_cpy.enable && resource_can_pipe_disable_cursor(pipe_ctx))
                pos_cpy.enable = false;
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 50e710b4ce651..47132e40aa2d2 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -972,52 +972,6 @@ void dcn401_setup_hpo_hw_control(const struct dce_hwseq 
*hws, bool enable)
        REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, enable);
 }
 
-static bool dcn401_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
-{
-       struct pipe_ctx *test_pipe, *split_pipe;
-       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
-       struct rect r1 = scl_data->recout, r2, r2_half;
-       int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
-       int cur_layer = pipe_ctx->plane_state->layer_index;
-
-       /**
-        * Disable the cursor if there's another pipe above this with a
-        * plane that contains this pipe's viewport to prevent double cursor
-        * and incorrect scaling artifacts.
-        */
-       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
-               test_pipe = test_pipe->top_pipe) {
-               // Skip invisible layer and pipe-split plane on same layer
-               if (!test_pipe->plane_state ||
-                       !test_pipe->plane_state->visible ||
-                       test_pipe->plane_state->layer_index == cur_layer)
-                       continue;
-
-               r2 = test_pipe->plane_res.scl_data.recout;
-               r2_r = r2.x + r2.width;
-               r2_b = r2.y + r2.height;
-
-               /**
-                * There is another half plane on same layer because of
-                * pipe-split, merge together per same height.
-                */
-               for (split_pipe = pipe_ctx->top_pipe; split_pipe;
-                       split_pipe = split_pipe->top_pipe)
-                       if (split_pipe->plane_state->layer_index == 
test_pipe->plane_state->layer_index) {
-                               r2_half = split_pipe->plane_res.scl_data.recout;
-                               r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
-                               r2.width = r2.width + r2_half.width;
-                               r2_r = r2.x + r2.width;
-                               break;
-                       }
-
-               if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= 
r2_b)
-                       return true;
-       }
-
-       return false;
-}
-
 void adjust_hotspot_between_slices_for_2x_magnify(uint32_t cursor_width, 
struct dc_cursor_position *pos_cpy)
 {
        if (cursor_width <= 128) {
@@ -1208,7 +1162,7 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
        pos_cpy.x = (uint32_t)x_pos;
        pos_cpy.y = (uint32_t)y_pos;
 
-       if (pos_cpy.enable && dcn401_can_pipe_disable_cursor(pipe_ctx))
+       if (pos_cpy.enable && resource_can_pipe_disable_cursor(pipe_ctx))
                pos_cpy.enable = false;
 
        x_pos = pos_cpy.x - param.recout.x;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h 
b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index cd1157d225abe..b32d07ce0f087 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -152,6 +152,8 @@ bool resource_attach_surfaces_to_context(
                struct dc_state *context,
                const struct resource_pool *pool);
 
+bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx);
+
 #define FREE_PIPE_INDEX_NOT_FOUND -1
 
 /*
-- 
2.39.5

Reply via email to