Commit 9d84c7ef authored by Martin Tsai's avatar Martin Tsai Committed by Alex Deucher
Browse files

drm/amd/display: Correct cursor position on horizontal mirror



[Why]
Incorrect cursor position will induce system hang on pipe split.

[How]
1.Handle horizontal mirror on rotation,
2.Correct cursor set on piep split.

Reviewed-by: default avatarAriel Bernstein <Eric.Bernstein@amd.com>
Acked-by: default avatarBrian Chang <Brian.Chang@amd.com>
Signed-off-by: default avatarMartin Tsai <martin.tsai@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 67ec7195
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -448,11 +448,12 @@ void dpp1_set_cursor_position(
			src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
		}
	} else if (param->rotation == ROTATION_ANGLE_180) {
		if (!param->mirror)
			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*/

+3 −6
Original line number Diff line number Diff line
@@ -1208,13 +1208,10 @@ void hubp1_cursor_set_position(
			src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
		}
	} else if (param->rotation == ROTATION_ANGLE_180) {
		if (!param->mirror)
			src_x_offset = pos->x - param->viewport.x;
		src_y_offset = pos->y - param->viewport.y;
	}

	if (param->mirror) {
		x_hotspot = param->viewport.width - x_hotspot;
		src_x_offset = param->viewport.x + param->viewport.width - src_x_offset;
		src_y_offset = pos->y - param->viewport.y;
	}

	dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
+54 −18
Original line number Diff line number Diff line
@@ -3470,8 +3470,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
		.rotation = pipe_ctx->plane_state->rotation,
		.mirror = pipe_ctx->plane_state->horizontal_mirror
	};
	bool pipe_split_on = (pipe_ctx->top_pipe != NULL) ||
		(pipe_ctx->bottom_pipe != NULL);
	bool pipe_split_on = false;
	bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
		(pipe_ctx->prev_odm_pipe != NULL);

@@ -3480,6 +3479,13 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
	int x_pos = pos_cpy.x;
	int y_pos = pos_cpy.y;

	if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) {
		if ((pipe_ctx->plane_state->src_rect.width != pipe_ctx->plane_res.scl_data.viewport.width) ||
			(pipe_ctx->plane_state->src_rect.height != pipe_ctx->plane_res.scl_data.viewport.height)) {
			pipe_split_on = true;
		}
	}

	/**
	 * DC cursor is stream space, HW cursor is plane space and drawn
	 * as part of the framebuffer.
@@ -3551,8 +3557,36 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
	if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
		pos_cpy.enable = false;


	if (param.rotation == ROTATION_ANGLE_0) {
		int viewport_width =
			pipe_ctx->plane_res.scl_data.viewport.width;
		int viewport_x =
			pipe_ctx->plane_res.scl_data.viewport.x;

		if (param.mirror) {
			if (pipe_split_on || odm_combine_on) {
				if (pos_cpy.x >= viewport_width + viewport_x) {
					pos_cpy.x = 2 * viewport_width
							- pos_cpy.x + 2 * viewport_x;
				} else {
					uint32_t temp_x = pos_cpy.x;

					pos_cpy.x = 2 * viewport_x - pos_cpy.x;
					if (temp_x >= 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 + viewport_width;
					}
				}
			} else {
				pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
			}
		}
	}
	// Swap axis and mirror horizontally
	if (param.rotation == ROTATION_ANGLE_90) {
	else if (param.rotation == ROTATION_ANGLE_90) {
		uint32_t temp_x = pos_cpy.x;

		pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
@@ -3623,6 +3657,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
		int viewport_x =
			pipe_ctx->plane_res.scl_data.viewport.x;

		if (!param.mirror) {
			if (pipe_split_on || odm_combine_on) {
				if (pos_cpy.x >= viewport_width + viewport_x) {
					pos_cpy.x = 2 * viewport_width
@@ -3641,6 +3676,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
			} else {
				pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
			}
		}

		/**
		 * Display groups that are 1xnY, have pos_cpy.y > viewport.height
+3 −6
Original line number Diff line number Diff line
@@ -987,13 +987,10 @@ void hubp2_cursor_set_position(
			src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
		}
	} else if (param->rotation == ROTATION_ANGLE_180) {
		if (!param->mirror)
			src_x_offset = pos->x - param->viewport.x;
		src_y_offset = pos->y - param->viewport.y;
	}

	if (param->mirror) {
		x_hotspot = param->viewport.width - x_hotspot;
		src_x_offset = param->viewport.x + param->viewport.width - src_x_offset;
		src_y_offset = pos->y - param->viewport.y;
	}

	dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;