Commit c0057622 authored by Jaehyun Chung's avatar Jaehyun Chung Committed by Alex Deucher

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: default avatarJaehyun Chung <jaehyun.chung@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5e1613e2
...@@ -457,6 +457,19 @@ void dpp1_set_cursor_position( ...@@ -457,6 +457,19 @@ void dpp1_set_cursor_position(
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
uint32_t cur_en = pos->enable ? 1 : 0; 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) if (src_x_offset >= (int)param->viewport.width)
cur_en = 0; /* not visible beyond right edge*/ cur_en = 0; /* not visible beyond right edge*/
......
...@@ -2976,6 +2976,40 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) ...@@ -2976,6 +2976,40 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
pos_cpy.enable = false; 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); 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); dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
} }
......
...@@ -945,6 +945,8 @@ void hubp2_cursor_set_position( ...@@ -945,6 +945,8 @@ void hubp2_cursor_set_position(
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
int x_hotspot = pos->x_hotspot; int x_hotspot = pos->x_hotspot;
int y_hotspot = pos->y_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 dst_x_offset;
uint32_t cur_en = pos->enable ? 1 : 0; uint32_t cur_en = pos->enable ? 1 : 0;
...@@ -958,10 +960,16 @@ void hubp2_cursor_set_position( ...@@ -958,10 +960,16 @@ void hubp2_cursor_set_position(
if (hubp->curs_attr.address.quad_part == 0) if (hubp->curs_attr.address.quad_part == 0)
return; return;
// Rotated cursor width/height and hotspots tweaks for offset calculation
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
src_x_offset = pos->y - pos->y_hotspot - param->viewport.x; swap(cursor_height, cursor_width);
y_hotspot = pos->x_hotspot; if (param->rotation == ROTATION_ANGLE_90) {
x_hotspot = pos->y_hotspot; 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) { if (param->mirror) {
...@@ -983,13 +991,13 @@ void hubp2_cursor_set_position( ...@@ -983,13 +991,13 @@ void hubp2_cursor_set_position(
if (src_x_offset >= (int)param->viewport.width) if (src_x_offset >= (int)param->viewport.width)
cur_en = 0; /* not visible beyond right edge*/ 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*/ cur_en = 0; /* not visible beyond left edge*/
if (src_y_offset >= (int)param->viewport.height) if (src_y_offset >= (int)param->viewport.height)
cur_en = 0; /* not visible beyond bottom edge*/ 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*/ cur_en = 0; /* not visible beyond top edge*/
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment