diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3588-drm-amd-display-Enable-HW-rotation.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3588-drm-amd-display-Enable-HW-rotation.patch | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3588-drm-amd-display-Enable-HW-rotation.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3588-drm-amd-display-Enable-HW-rotation.patch new file mode 100644 index 00000000..7f800032 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3588-drm-amd-display-Enable-HW-rotation.patch @@ -0,0 +1,143 @@ +From 252680ecb1b81f5eb52878e54a0fbe0545520127 Mon Sep 17 00:00:00 2001 +From: Jaehyun Chung <jaehyun.chung@amd.com> +Date: Wed, 7 Aug 2019 11:20:16 -0400 +Subject: [PATCH 3588/4256] drm/amd/display: Enable HW rotation + +[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.chung@amd.com> +Reviewed-by: Jun Lei <Jun.Lei@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@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 808a31c197d2..24a5d79887c1 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 +@@ -2974,6 +2974,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, ¶m); + dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, 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 + |