From: Samson Tam <samson....@amd.com>

[Why]
Cursor disappears for some SLS displays that are rotated 180
and 270 degrees.  This occurs when there is no pipe split being
done ( ex. 3 or more displays ).  The cursor calculations assume
pipe splitting is done so when it calculates the new cursor
position in hwss.set_cursor_position(), it is out-of-bounds so
it disables the cursor in hubp.set_cursor_position().

[How]
In non pipe split cases, calculate cursor using viewport size
( width or height ) instead of viewport size * 2 ( the two
because pipe splitting divides the rectangle into two ).

Signed-off-by: Samson Tam <samson....@amd.com>
Reviewed-by: Jun Lei <jun....@amd.com>
Acked-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 51 +++++++++++++------
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 9e53bbd5d2b5..9c55e4897fca 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -2916,6 +2916,8 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
                .rotation = pipe_ctx->plane_state->rotation,
                .mirror = pipe_ctx->plane_state->horizontal_mirror
        };
+       bool pipe_split_on = (pipe_ctx->top_pipe != NULL) ||
+               (pipe_ctx->bottom_pipe != NULL);
 
        int x_plane = pipe_ctx->plane_state->dst_rect.x;
        int y_plane = pipe_ctx->plane_state->dst_rect.y;
@@ -2948,6 +2950,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
        // Swap axis and mirror horizontally
        if (param.rotation == ROTATION_ANGLE_90) {
                uint32_t temp_x = pos_cpy.x;
+
                pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
                                (pos_cpy.y - 
pipe_ctx->plane_res.scl_data.viewport.x) + 
pipe_ctx->plane_res.scl_data.viewport.x;
                pos_cpy.y = temp_x;
@@ -2955,26 +2958,44 @@ void dcn10_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
        // Swap axis and mirror vertically
        else if (param.rotation == ROTATION_ANGLE_270) {
                uint32_t temp_y = pos_cpy.y;
-               if (pos_cpy.x >  pipe_ctx->plane_res.scl_data.viewport.height) {
-                       pos_cpy.x = pos_cpy.x - 
pipe_ctx->plane_res.scl_data.viewport.height;
-                       pos_cpy.y = 
pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.x;
-               } else {
-                       pos_cpy.y = 2 * 
pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.x;
-               }
+               int viewport_height =
+                       pipe_ctx->plane_res.scl_data.viewport.height;
+
+               if (pipe_split_on) {
+                       if (pos_cpy.x > viewport_height) {
+                               pos_cpy.x = pos_cpy.x - viewport_height;
+                               pos_cpy.y = viewport_height - pos_cpy.x;
+                       } else {
+                               pos_cpy.y = 2 * viewport_height - pos_cpy.x;
+                       }
+               } else
+                       pos_cpy.y = viewport_height - pos_cpy.x;
                pos_cpy.x = temp_y;
        }
        // Mirror horizontally and vertically
        else if (param.rotation == ROTATION_ANGLE_180) {
-               if (pos_cpy.x >= pipe_ctx->plane_res.scl_data.viewport.width + 
pipe_ctx->plane_res.scl_data.viewport.x) {
-                       pos_cpy.x = 2 * 
pipe_ctx->plane_res.scl_data.viewport.width
-                                       - pos_cpy.x + 2 * 
pipe_ctx->plane_res.scl_data.viewport.x;
-               } else {
-                       uint32_t temp_x = pos_cpy.x;
-                       pos_cpy.x = 2 * pipe_ctx->plane_res.scl_data.viewport.x 
- pos_cpy.x;
-                       if (temp_x >= pipe_ctx->plane_res.scl_data.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 + 
pipe_ctx->plane_res.scl_data.viewport.width;
+               int viewport_width =
+                       pipe_ctx->plane_res.scl_data.viewport.width;
+               int viewport_x =
+                       pipe_ctx->plane_res.scl_data.viewport.x;
+
+               if (pipe_split_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;
                }
                pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - 
pos_cpy.y;
        }
-- 
2.24.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to