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

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
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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*/

+34 −0
Original line number Diff line number Diff line
@@ -2976,6 +2976,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);
}
+13 −5
Original line number Diff line number Diff line
@@ -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)