Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c31a821 authored by Yongqiang Sun's avatar Yongqiang Sun Committed by Alex Deucher
Browse files

drm/amd/display: fix recout_skip calculation when rotating 180 or 270



Fixed fliped landscape and fliped portrait hard hang.

Signed-off-by: default avatarYongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ee016c4b
Loading
Loading
Loading
Loading
+60 −34
Original line number Original line Diff line number Diff line
@@ -498,27 +498,16 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
	data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
	data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;


	/* Handle hsplit */
	/* Handle hsplit */
	if (pri_split || sec_split) {
	if (sec_split) {
		/* HMirror XOR Secondary_pipe XOR Rotation_180 */
		bool right_view = (sec_split != plane_state->horizontal_mirror) !=
					(plane_state->rotation == ROTATION_ANGLE_180);

		if (plane_state->rotation == ROTATION_ANGLE_90
				|| plane_state->rotation == ROTATION_ANGLE_270)
			/* Secondary_pipe XOR Rotation_270 */
			right_view = (plane_state->rotation == ROTATION_ANGLE_270) != sec_split;

		if (right_view) {
		data->viewport.x +=  data->viewport.width / 2;
		data->viewport.x +=  data->viewport.width / 2;
		data->viewport_c.x +=  data->viewport_c.width / 2;
		data->viewport_c.x +=  data->viewport_c.width / 2;
		/* Ceil offset pipe */
		/* Ceil offset pipe */
		data->viewport.width = (data->viewport.width + 1) / 2;
		data->viewport.width = (data->viewport.width + 1) / 2;
		data->viewport_c.width = (data->viewport_c.width + 1) / 2;
		data->viewport_c.width = (data->viewport_c.width + 1) / 2;
		} else {
	} else if (pri_split) {
		data->viewport.width /= 2;
		data->viewport.width /= 2;
		data->viewport_c.width /= 2;
		data->viewport_c.width /= 2;
	}
	}
	}


	if (plane_state->rotation == ROTATION_ANGLE_90 ||
	if (plane_state->rotation == ROTATION_ANGLE_90 ||
			plane_state->rotation == ROTATION_ANGLE_270) {
			plane_state->rotation == ROTATION_ANGLE_270) {
@@ -534,6 +523,16 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip
	struct rect surf_src = plane_state->src_rect;
	struct rect surf_src = plane_state->src_rect;
	struct rect surf_clip = plane_state->clip_rect;
	struct rect surf_clip = plane_state->clip_rect;
	int recout_full_x, recout_full_y;
	int recout_full_x, recout_full_y;
	bool pri_split = pipe_ctx->bottom_pipe &&
			pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state;
	bool sec_split = pipe_ctx->top_pipe &&
			pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;

	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
		stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
		pri_split = false;
		sec_split = false;
	}


	if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
	if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
			pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
			pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270)
@@ -569,23 +568,35 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip


	/* Handle h & vsplit */
	/* Handle h & vsplit */
	if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state ==
	if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state ==
		pipe_ctx->plane_state) {
			pipe_ctx->plane_state && stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
		if (stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
		pipe_ctx->plane_res.scl_data.recout.y += pipe_ctx->plane_res.scl_data.recout.height / 2;
		pipe_ctx->plane_res.scl_data.recout.y += pipe_ctx->plane_res.scl_data.recout.height / 2;
		/* Floor primary pipe, ceil 2ndary pipe */
		/* Floor primary pipe, ceil 2ndary pipe */
		pipe_ctx->plane_res.scl_data.recout.height = (pipe_ctx->plane_res.scl_data.recout.height + 1) / 2;
		pipe_ctx->plane_res.scl_data.recout.height = (pipe_ctx->plane_res.scl_data.recout.height + 1) / 2;
		} else {
			pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width / 2;
			pipe_ctx->plane_res.scl_data.recout.width = (pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
		}
	} else if (pipe_ctx->bottom_pipe &&
	} else if (pipe_ctx->bottom_pipe &&
			pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state) {
			pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state
		if (stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
			&& stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
		pipe_ctx->plane_res.scl_data.recout.height /= 2;
		pipe_ctx->plane_res.scl_data.recout.height /= 2;
		else

	if (pri_split || sec_split) {
		/* HMirror XOR Secondary_pipe XOR Rotation_180 */
		bool right_view = (sec_split != plane_state->horizontal_mirror) !=
					(plane_state->rotation == ROTATION_ANGLE_180);

		if (plane_state->rotation == ROTATION_ANGLE_90
				|| plane_state->rotation == ROTATION_ANGLE_270)
			/* Secondary_pipe XOR Rotation_270 */
			right_view = (plane_state->rotation == ROTATION_ANGLE_270) != sec_split;

		if (right_view) {
			pipe_ctx->plane_res.scl_data.recout.x +=
					pipe_ctx->plane_res.scl_data.recout.width / 2;
			/* Ceil offset pipe */
			pipe_ctx->plane_res.scl_data.recout.width =
					(pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
		} else {
			pipe_ctx->plane_res.scl_data.recout.width /= 2;
			pipe_ctx->plane_res.scl_data.recout.width /= 2;
		}
		}

	}
	/* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset)
	/* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset)
	 * 				* 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl
	 * 				* 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl
	 * 				ratio)
	 * 				ratio)
@@ -601,6 +612,21 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip


	recout_skip->width = pipe_ctx->plane_res.scl_data.recout.x - recout_full_x;
	recout_skip->width = pipe_ctx->plane_res.scl_data.recout.x - recout_full_x;
	recout_skip->height = pipe_ctx->plane_res.scl_data.recout.y - recout_full_y;
	recout_skip->height = pipe_ctx->plane_res.scl_data.recout.y - recout_full_y;

	/*Adjust recout_skip for rotation */
	if ((pri_split || sec_split) && (plane_state->rotation == ROTATION_ANGLE_270 || plane_state->rotation == ROTATION_ANGLE_180)) {
		bool right_view = (sec_split != plane_state->horizontal_mirror) !=
					(plane_state->rotation == ROTATION_ANGLE_180);

		if (plane_state->rotation == ROTATION_ANGLE_90
				|| plane_state->rotation == ROTATION_ANGLE_270)
			/* Secondary_pipe XOR Rotation_270 */
			right_view = (plane_state->rotation == ROTATION_ANGLE_270) != sec_split;
		if (!right_view)
			recout_skip->width = pipe_ctx->plane_res.scl_data.recout.x + pipe_ctx->plane_res.scl_data.recout.width / 2 - recout_full_x;
		else
			recout_skip->width = pipe_ctx->plane_res.scl_data.recout.x - pipe_ctx->plane_res.scl_data.recout.width / 2 - recout_full_x;
	}
}
}


static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)