From: Piotr Maziarz <[email protected]>

[Why]
dcn401_build_cursor_position() clamped x_hotspot to 0xFF before
publishing *pos_out, but that field is also stored into hubp->curs_pos
and forwarded to dpp1_set_cursor_position(), which derives
src_x_offset from it. The ODM/MPC slice adjustments earlier in the same
function deliberately grow x_hotspot past 255 to keep the cursor
visible across a slice boundary, so the clamp corrupted DPP source
addressing in exactly the case it was meant to handle.

[How]
Clamp in hubp401_cursor_set_position() instead, where the 8-bit
CURSOR_HOT_SPOT_X field lives. A local is used for the register write
only; pos->x_hotspot passes through unmodified.

Reviewed-by: Alvin Lee <[email protected]>
Signed-off-by: Piotr Maziarz <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c  | 4 +++-
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 4 ----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index a985c3e00dca..91e87fb51fe4 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -818,6 +818,8 @@ void hubp401_cursor_set_position(
        struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
        int dst_x_offset = param->dst_x_offset;
        uint32_t cur_en = pos->enable ? 1 : 0;
+       /* CURSOR_HOT_SPOT_X is 8 bits wide; clamp only the register write */
+       uint32_t x_hotspot_clamped = pos->x_hotspot > 0xFF ? 0xFF : 
pos->x_hotspot;
        hubp->curs_pos = *pos;
 
        /*
@@ -842,7 +844,7 @@ void hubp401_cursor_set_position(
                        CURSOR_Y_POSITION, pos->y);
 
                REG_SET_2(CURSOR_HOT_SPOT, 0,
-                       CURSOR_HOT_SPOT_X, pos->x_hotspot,
+                       CURSOR_HOT_SPOT_X, x_hotspot_clamped,
                        CURSOR_HOT_SPOT_Y, pos->y_hotspot);
 
                REG_SET(CURSOR_DST_OFFSET, 0,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 37b699c69144..98398dac9861 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1264,10 +1264,6 @@ void dcn401_build_cursor_position(struct pipe_ctx 
*pipe_ctx,
        param.cur_rect_x = rec_x_offset + param.recout.x;
        param.cur_rect_y = rec_y_offset + param.recout.y;
 
-       /* Clamp hotspot to the CURSOR_HOT_SPOT_X register field width */
-       if (pos_cpy.x_hotspot > 0xFF)
-               pos_cpy.x_hotspot = 0xFF;
-
        *pos_out = pos_cpy;
        *param_out = param;
 }
-- 
2.55.0

Reply via email to