]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Fix wrong x_pos and y_pos for cursor offload
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Wed, 12 Nov 2025 15:58:19 +0000 (10:58 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Dec 2025 18:56:40 +0000 (13:56 -0500)
[Why]
The hubp401_cursor_set_position function programs a different value
than it stores for use with cursor offload.

This can cause a desync when switching between cursor programming paths.

[How]
We do the translation to destination space currently twice: once in the
HWSS layer, and then again in the HUBP layer since we never store the
translated result.

HUBP expects to program the pos->x and pos->y directly for other ASIC,
so follow that pattern here as well.

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c

index f01eae50d02f78d15ef2165b2968ff82cc23622c..c205500290ecd7d3af50affafd92b39af589709f 100644 (file)
@@ -733,10 +733,8 @@ void hubp401_cursor_set_position(
        const struct dc_cursor_mi_param *param)
 {
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
-       int x_pos = pos->x - param->recout.x;
-       int y_pos = pos->y - param->recout.y;
-       int rec_x_offset = x_pos - pos->x_hotspot;
-       int rec_y_offset = y_pos - pos->y_hotspot;
+       int rec_x_offset = pos->x - pos->x_hotspot;
+       int rec_y_offset = pos->y - pos->y_hotspot;
        int dst_x_offset;
        int x_pos_viewport = 0;
        int x_hot_viewport = 0;
@@ -748,10 +746,10 @@ void hubp401_cursor_set_position(
         * within preceeding ODM slices.
         */
        if (param->recout.width) {
-               x_pos_viewport = x_pos * param->viewport.width / param->recout.width;
+               x_pos_viewport = pos->x * param->viewport.width / param->recout.width;
                x_hot_viewport = pos->x_hotspot * param->viewport.width / param->recout.width;
        } else {
-               ASSERT(!cur_en || x_pos == 0);
+               ASSERT(!cur_en || pos->x == 0);
                ASSERT(!cur_en || pos->x_hotspot == 0);
        }
 
@@ -790,8 +788,8 @@ void hubp401_cursor_set_position(
 
        if (!hubp->cursor_offload) {
                REG_SET_2(CURSOR_POSITION, 0,
-                       CURSOR_X_POSITION, x_pos,
-                       CURSOR_Y_POSITION, y_pos);
+                       CURSOR_X_POSITION, pos->x,
+                       CURSOR_Y_POSITION, pos->y);
 
                REG_SET_2(CURSOR_HOT_SPOT, 0,
                        CURSOR_HOT_SPOT_X, pos->x_hotspot,
index 2fbc22afb89c5a76094117ec2d9c49b4b95276ad..163b5869d7f78c0f4b3726d2116cd61845b4831c 100644 (file)
@@ -1213,6 +1213,9 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
        if (recout_y_pos + (int)hubp->curs_attr.height <= 0)
                pos_cpy.enable = false;  /* not visible beyond top edge*/
 
+       pos_cpy.x = x_pos;
+       pos_cpy.y = y_pos;
+
        hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
        dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
 }