]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: Update Cursor request mode to the beginning prefetch always
authorZhikai Zhai <zhikai.zhai@amd.com>
Thu, 9 Jan 2025 08:11:48 +0000 (16:11 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Apr 2025 08:45:17 +0000 (10:45 +0200)
[ 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>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c

index ff38a85c4fa22d5979442b0b6b7fb4c31bc8b196..e71b79f5a66cda6a83a652d8db7e4006bdacebc8 100644 (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);
        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. */
@@ -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;
        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);
 }
index 39a57bcd78667a9abd2d5b98f6eadbed53e5a2d8..576acf2ce10dd5ef0c2e0b5984a54cc7a40b5caa 100644 (file)
@@ -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)