From: Ivan Lipski <ivan.lip...@amd.com>

[Why]
For the HW cursor, its current position in the pipe_ctx->stream struct is
not affected by the 180 rotation, i. e. the top left corner is still at
0,0. However, the DPP & HUBP set_cursor_position functions require rotated
position.

The current approach is hard-coded for ODM 2:1, thus it's failing for
ODM 4:1, resulting in a double cursor.

[How]
Instead of calculating the new cursor position relatively to the
viewports, we calculate it using a viewavable clip_rect of each plane.

The clip_rects are first offset and scaled to the same space as the
src_rect, i. e. Stream space -> Plane space.

In case of a pipe split, which divides the plane into 2 or more viewports,
the clip_rect is the union of all the viewports of the given plane.

With the assumption that the viewports in HUBP's set_cursor_position are
in the Plane space as well, it should produce a correct cursor position
for any number of pipe splits.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlaus...@amd.com>
Signed-off-by: Ivan Lipski <ivan.lip...@amd.com>
Signed-off-by: Leo Li <sunpeng...@amd.com>
Signed-off-by: Aurabindo Pillai <aurabindo.pil...@amd.com>
---
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c   | 73 +++++++------------
 1 file changed, 27 insertions(+), 46 deletions(-)

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 d633033c98f2..506c3bbbf221 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
@@ -3663,6 +3663,8 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
        int y_plane = pipe_ctx->plane_state->dst_rect.y;
        int x_pos = pos_cpy.x;
        int y_pos = pos_cpy.y;
+       int clip_x = pipe_ctx->plane_state->clip_rect.x;
+       int clip_width = pipe_ctx->plane_state->clip_rect.width;
 
        if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) {
                if ((pipe_ctx->plane_state->src_rect.width != 
pipe_ctx->plane_res.scl_data.viewport.width) ||
@@ -3681,7 +3683,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
         */
 
        /**
-        * Translate cursor from stream space to plane space.
+        * Translate cursor and clip offset from stream space to plane space.
         *
         * If the cursor is scaled then we need to scale the position
         * to be in the approximately correct place. We can't do anything
@@ -3698,6 +3700,10 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
                                pipe_ctx->plane_state->dst_rect.width;
                y_pos = (y_pos - y_plane) * 
pipe_ctx->plane_state->src_rect.height /
                                pipe_ctx->plane_state->dst_rect.height;
+               clip_x = (clip_x - x_plane) * 
pipe_ctx->plane_state->src_rect.width /
+                               pipe_ctx->plane_state->dst_rect.width;
+               clip_width = clip_width * pipe_ctx->plane_state->src_rect.width 
/
+                               pipe_ctx->plane_state->dst_rect.width;
        }
 
        /**
@@ -3744,30 +3750,18 @@ void dcn10_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
 
 
        if (param.rotation == ROTATION_ANGLE_0) {
-               int viewport_width =
-                       pipe_ctx->plane_res.scl_data.viewport.width;
-               int viewport_x =
-                       pipe_ctx->plane_res.scl_data.viewport.x;
 
                if (param.mirror) {
-                       if (pipe_split_on || odm_combine_on) {
-                               if (pos_cpy.x >= viewport_width + viewport_x) {
-                                       pos_cpy.x = 2 * viewport_width
-                                                       - pos_cpy.x + 2 * 
viewport_x;
-                               } else {
-                                       uint32_t temp_x = pos_cpy.x;
-
-                                       pos_cpy.x = 2 * viewport_x - pos_cpy.x;
-                                       if (temp_x >= viewport_x +
-                                               (int)hubp->curs_attr.width || 
pos_cpy.x
-                                               <= (int)hubp->curs_attr.width +
-                                               
pipe_ctx->plane_state->src_rect.x) {
-                                               pos_cpy.x = 2 * viewport_width 
- temp_x;
-                                       }
-                               }
-                       } else {
-                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * 
viewport_x;
-                       }
+                       /*
+                        * The plane is split into multiple viewports.
+                        * The combination of all viewports span the
+                        * entirety of the clip rect.
+                        *
+                        * For no pipe_split, viewport_width is represents
+                        * the full width of the clip_rect, so we can just
+                        * mirror it.
+                        */
+                       pos_cpy.x = clip_width - pos_cpy.x + 2 * clip_x;
                }
        }
        // Swap axis and mirror horizontally
@@ -3837,30 +3831,17 @@ void dcn10_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
        }
        // Mirror horizontally and vertically
        else if (param.rotation == ROTATION_ANGLE_180) {
-               int viewport_width =
-                       pipe_ctx->plane_res.scl_data.viewport.width;
-               int viewport_x =
-                       pipe_ctx->plane_res.scl_data.viewport.x;
-
                if (!param.mirror) {
-                       if (pipe_split_on || odm_combine_on) {
-                               if (pos_cpy.x >= viewport_width + viewport_x) {
-                                       pos_cpy.x = 2 * viewport_width
-                                                       - pos_cpy.x + 2 * 
viewport_x;
-                               } else {
-                                       uint32_t temp_x = pos_cpy.x;
-
-                                       pos_cpy.x = 2 * viewport_x - pos_cpy.x;
-                                       if (temp_x >= viewport_x +
-                                               (int)hubp->curs_attr.width || 
pos_cpy.x
-                                               <= (int)hubp->curs_attr.width +
-                                               
pipe_ctx->plane_state->src_rect.x) {
-                                               pos_cpy.x = temp_x + 
viewport_width;
-                                       }
-                               }
-                       } else {
-                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * 
viewport_x;
-                       }
+                       /*
+                        * The plane is split into multiple viewports.
+                        * The combination of all viewports span the
+                        * entirety of the clip rect.
+                        *
+                        * For no pipe_split, viewport_width is represents
+                        * the full width of the clip_rect, so we can just
+                        * mirror it.
+                        */
+                       pos_cpy.x = clip_width - pos_cpy.x + 2 * clip_x;
                }
 
                /**
-- 
2.50.1

Reply via email to