From: Max Tseng <max.ts...@amd.com>

[Why]
PSR-SU requires extra conditions while cursor update.

Reviewed-by: Robin Chen <robin.c...@amd.com>
Acked-by: Alan Liu <haoping....@amd.com>
Signed-off-by: Max Tseng <max.ts...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 48 ++++++++++++++++++++
 1 file changed, 48 insertions(+)

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 67eef5beab95..4cb912bf400b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -859,11 +859,59 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv 
*dc_dmub_srv)
                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;
+               split_pipe = test_pipe;
+
+               /**
+                * 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))
+                       return false;
        }
 
        if ((pipe_ctx->stream->link->psr_settings.psr_version == 
DC_PSR_VERSION_SU_1 ||
-- 
2.25.1

Reply via email to