Commit 4a4077b4 authored by Zhikai Zhai's avatar Zhikai Zhai Committed by Alex Deucher
Browse files

drm/amd/display: Update Cursor request mode to the beginning prefetch always



[Why]
The double buffer cursor registers is updated by the cursor
vupdate event. There is a gap between vupdate and cursor data
fetch if cursor fetch data reletive to cursor position.
Cursor corruption will happen if we update the cursor surface
in this gap.

[How]
Modify the cursor request mode to the beginning prefetch always
and avoid wraparound calculation issues.

Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarZhikai Zhai <zhikai.zhai@amd.com>
Signed-off-by: default avatarZaeem Mohamed <zaeem.mohamed@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6a7fde43
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ void hubp31_set_unbounded_requesting(struct hubp *hubp, bool enable)
	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);

	REG_UPDATE(DCHUBP_CNTL, HUBP_UNBOUNDED_REQ_MODE, enable);
	REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, enable);
	REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, 1);
}

void hubp31_soft_reset(struct hubp *hubp, bool reset)
+9 −13
Original line number Diff line number Diff line
@@ -1993,20 +1993,11 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
	dc->hwss.get_position(&pipe_ctx, 1, &position);
	vpos = position.vertical_count;

	/* Avoid wraparound calculation issues */
	vupdate_start += stream->timing.v_total;
	vupdate_end += stream->timing.v_total;
	vpos += stream->timing.v_total;

	if (vpos <= vupdate_start) {
		/* VPOS is in VACTIVE or back porch. */
		lines_to_vupdate = vupdate_start - vpos;
	} else if (vpos > vupdate_end) {
		/* VPOS is in the front porch. */
		return;
	} else {
		/* VPOS is in VUPDATE. */
		lines_to_vupdate = 0;
		lines_to_vupdate = stream->timing.v_total - vpos + vupdate_start;
	}

	/* Calculate time until VUPDATE in microseconds. */
@@ -2014,13 +2005,18 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
		stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
	us_to_vupdate = lines_to_vupdate * us_per_line;

	/* Stall out until the cursor update completes. */
	if (vupdate_end < vupdate_start)
		vupdate_end += stream->timing.v_total;

	/* Position is in the range of vupdate start and end*/
	if (lines_to_vupdate > stream->timing.v_total - vupdate_end + vupdate_start)
		us_to_vupdate = 0;

	/* 70 us is a conservative estimate of cursor update time*/
	if (us_to_vupdate > 70)
		return;

	/* Stall out until the cursor update completes. */
	if (vupdate_end < vupdate_start)
		vupdate_end += stream->timing.v_total;
	us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
	udelay(us_to_vupdate + us_vupdate);
}