From: Jaehyun Chung <jaehyun.ch...@amd.com>

[Why] HW rotation is not enabled. Calculations for cursor rotation
are wrong for the values passed to set_cursor_position.

[How] Swap Src rect and height and vertically mirror surface for
the correct surface rotation direction. Cursor position is rotated
according to angle. Offset calculations are tweaked for non-rotated
cursor hotspot and width/height.

Signed-off-by: Jaehyun Chung <jaehyun.ch...@amd.com>
Reviewed-by: Jun Lei <jun....@amd.com>
Acked-by: Bhawanpreet Lakha <bhawanpreet.la...@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c  | 13 +++++++
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 34 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 18 +++++++---
 3 files changed, 60 insertions(+), 5 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 23b2361cec62..d8b2da18db39 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -457,6 +457,19 @@ void dpp1_set_cursor_position(
        int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
        uint32_t cur_en = pos->enable ? 1 : 0;
 
+       // Cursor width/height and hotspots need to be rotated for offset 
calculation
+       if (param->rotation == ROTATION_ANGLE_90 || param->rotation == 
ROTATION_ANGLE_270) {
+               swap(width, height);
+               if (param->rotation == ROTATION_ANGLE_90) {
+                       src_x_offset = pos->x - pos->y_hotspot - 
param->viewport.x;
+                       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 (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_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index bfd402bede94..004675db686d 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
@@ -2975,6 +2975,40 @@ static void dcn10_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
                        == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
                pos_cpy.enable = false;
 
+       // 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;
+       }
+       // 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;
+               }
+               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;
+                       }
+               }
+               pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - 
pos_cpy.y;
+       }
+
        hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
        dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 
hubp->curs_attr.width, hubp->curs_attr.height);
 }
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 b4b384c7fa9b..69e2aae42394 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -945,6 +945,8 @@ void hubp2_cursor_set_position(
        int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
        int x_hotspot = pos->x_hotspot;
        int y_hotspot = pos->y_hotspot;
+       int cursor_height = (int)hubp->curs_attr.height;
+       int cursor_width = (int)hubp->curs_attr.width;
        uint32_t dst_x_offset;
        uint32_t cur_en = pos->enable ? 1 : 0;
 
@@ -958,10 +960,16 @@ void hubp2_cursor_set_position(
        if (hubp->curs_attr.address.quad_part == 0)
                return;
 
+       // Rotated cursor width/height and hotspots tweaks for offset 
calculation
        if (param->rotation == ROTATION_ANGLE_90 || param->rotation == 
ROTATION_ANGLE_270) {
-               src_x_offset = pos->y - pos->y_hotspot - param->viewport.x;
-               y_hotspot = pos->x_hotspot;
-               x_hotspot = pos->y_hotspot;
+               swap(cursor_height, cursor_width);
+               if (param->rotation == ROTATION_ANGLE_90) {
+                       src_x_offset = pos->x - pos->y_hotspot - 
param->viewport.x;
+                       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) {
@@ -983,13 +991,13 @@ void hubp2_cursor_set_position(
        if (src_x_offset >= (int)param->viewport.width)
                cur_en = 0;  /* not visible beyond right edge*/
 
-       if (src_x_offset + (int)hubp->curs_attr.width <= 0)
+       if (src_x_offset + cursor_width <= 0)
                cur_en = 0;  /* not visible beyond left edge*/
 
        if (src_y_offset >= (int)param->viewport.height)
                cur_en = 0;  /* not visible beyond bottom edge*/
 
-       if (src_y_offset + (int)hubp->curs_attr.height <= 0)
+       if (src_y_offset + cursor_height <= 0)
                cur_en = 0;  /* not visible beyond top edge*/
 
        if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
-- 
2.17.1

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

Reply via email to