From: Martin Tsai <martin.t...@amd.com>

[Why]
Incorrect cursor position will induce system hang on pipe split.

[How]
1.Handle horizontal mirror on rotation,
2.Correct cursor set on piep split.

Reviewed-by: Ariel Bernstein <eric.bernst...@amd.com>
Acked-by: Brian Chang <brian.ch...@amd.com>
Signed-off-by: Martin Tsai <martin.t...@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c  |  5 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c |  9 +--
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 72 ++++++++++++++-----
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c |  9 +--
 4 files changed, 63 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index db7ca4b0cdb9..897f412f539e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -448,11 +448,12 @@ void dpp1_set_cursor_position(
                        src_y_offset = pos->y - pos->x_hotspot - 
param->viewport.y;
                }
        } else if (param->rotation == ROTATION_ANGLE_180) {
-               src_x_offset = pos->x - param->viewport.x;
+               if (!param->mirror)
+                       src_x_offset = pos->x - param->viewport.x;
+
                src_y_offset = pos->y - param->viewport.y;
        }
 
-
        if (src_x_offset >= (int)param->viewport.width)
                cur_en = 0;  /* not visible beyond right edge*/
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 564e061ccb58..52e201e9b091 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -1208,13 +1208,10 @@ void hubp1_cursor_set_position(
                        src_y_offset = pos->y - pos->x_hotspot - 
param->viewport.y;
                }
        } else if (param->rotation == ROTATION_ANGLE_180) {
-               src_x_offset = pos->x - param->viewport.x;
-               src_y_offset = pos->y - param->viewport.y;
-       }
+               if (!param->mirror)
+                       src_x_offset = pos->x - param->viewport.x;
 
-       if (param->mirror) {
-               x_hotspot = param->viewport.width - x_hotspot;
-               src_x_offset = param->viewport.x + param->viewport.width - 
src_x_offset;
+               src_y_offset = pos->y - param->viewport.y;
        }
 
        dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
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 d3f6a2609c8c..b92c14b9043f 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
@@ -3470,8 +3470,7 @@ 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);
+       bool pipe_split_on = false;
        bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
                (pipe_ctx->prev_odm_pipe != NULL);
 
@@ -3480,6 +3479,13 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
        int x_pos = pos_cpy.x;
        int y_pos = pos_cpy.y;
 
+       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) ||
+                       (pipe_ctx->plane_state->src_rect.height != 
pipe_ctx->plane_res.scl_data.viewport.height)) {
+                       pipe_split_on = true;
+               }
+       }
+
        /**
         * DC cursor is stream space, HW cursor is plane space and drawn
         * as part of the framebuffer.
@@ -3551,8 +3557,36 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
        if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
                pos_cpy.enable = false;
 
+
+       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 = temp_x + 
viewport_width;
+                                       }
+                               }
+                       } else {
+                               pos_cpy.x = viewport_width - pos_cpy.x + 2 * 
viewport_x;
+                       }
+               }
+       }
        // Swap axis and mirror horizontally
-       if (param.rotation == ROTATION_ANGLE_90) {
+       else if (param.rotation == ROTATION_ANGLE_90) {
                uint32_t temp_x = pos_cpy.x;
 
                pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
@@ -3623,23 +3657,25 @@ void dcn10_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
                int viewport_x =
                        pipe_ctx->plane_res.scl_data.viewport.x;
 
-               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;
+               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;
                        }
-               } else {
-                       pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
                }
 
                /**
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index 9570c2118ccc..b1ec0e6f7f58 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -987,13 +987,10 @@ void hubp2_cursor_set_position(
                        src_y_offset = pos->y - pos->x_hotspot - 
param->viewport.y;
                }
        } else if (param->rotation == ROTATION_ANGLE_180) {
-               src_x_offset = pos->x - param->viewport.x;
-               src_y_offset = pos->y - param->viewport.y;
-       }
+               if (!param->mirror)
+                       src_x_offset = pos->x - param->viewport.x;
 
-       if (param->mirror) {
-               x_hotspot = param->viewport.width - x_hotspot;
-               src_x_offset = param->viewport.x + param->viewport.width - 
src_x_offset;
+               src_y_offset = pos->y - param->viewport.y;
        }
 
        dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
-- 
2.25.1

Reply via email to