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

[ Upstream commit 4a4077b4b63a8404efd6d37fc2926f03fb25bace ]

[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: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Zhikai Zhai <zhikai.zhai@amd.com>
Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Zhikai Zhai
2025-01-09 16:11:48 +08:00
committed by Greg Kroah-Hartman
parent f5b168c309
commit 2528ccb0f2
2 changed files with 10 additions and 14 deletions

View File

@@ -1930,20 +1930,11 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
dc->hwss.get_position(&pipe_ctx, 1, &position); dc->hwss.get_position(&pipe_ctx, 1, &position);
vpos = position.vertical_count; 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) { if (vpos <= vupdate_start) {
/* VPOS is in VACTIVE or back porch. */ /* VPOS is in VACTIVE or back porch. */
lines_to_vupdate = vupdate_start - vpos; lines_to_vupdate = vupdate_start - vpos;
} else if (vpos > vupdate_end) {
/* VPOS is in the front porch. */
return;
} else { } else {
/* VPOS is in VUPDATE. */ lines_to_vupdate = stream->timing.v_total - vpos + vupdate_start;
lines_to_vupdate = 0;
} }
/* Calculate time until VUPDATE in microseconds. */ /* Calculate time until VUPDATE in microseconds. */
@@ -1951,13 +1942,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; stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
us_to_vupdate = lines_to_vupdate * us_per_line; 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*/ /* 70 us is a conservative estimate of cursor update time*/
if (us_to_vupdate > 70) if (us_to_vupdate > 70)
return; 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; us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
udelay(us_to_vupdate + us_vupdate); udelay(us_to_vupdate + us_vupdate);
} }

View File

@@ -44,7 +44,7 @@ void hubp31_set_unbounded_requesting(struct hubp *hubp, bool enable)
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
REG_UPDATE(DCHUBP_CNTL, HUBP_UNBOUNDED_REQ_MODE, enable); 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) void hubp31_soft_reset(struct hubp *hubp, bool reset)