summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorIvan Lipski <ivan.lipski@amd.com>2026-02-02 15:57:19 -0500
committerAlex Deucher <alexander.deucher@amd.com>2026-02-23 14:39:31 -0500
commitd8f6c978fd3d12ae129879dd1c514cec2e8cf2f8 (patch)
treebe275f6b6df01cde4f7b25a7ecb1fbf7d9573f19 /drivers
parentf44c094449669c7d9ac403cc73ce23e255f0828b (diff)
drm/amd/display: Fix cursor pos at overlay plane edges on DCN4
[Why&How] On DCN4, when cursor straddles the left/top edge of an overlay plane, the recout-relative position becomes negative. These negative values wrap to large positive numbers when cast to uint32_t, causing the cursor on the the overlay plane to disappear. Fix by adding hotspot adjustment and position clamping after the recout-relative calculation, matching the existing ODM/MPC slice boundary handling. Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Ivan Lipski <ivan.lipski@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c19
1 files changed, 19 insertions, 0 deletions
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 b91517b9fedc..f604c30e8493 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
@@ -1202,6 +1202,25 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
x_pos = pos_cpy.x - param.recout.x;
y_pos = pos_cpy.y - param.recout.y;
+ /**
+ * If the cursor position is negative after recout adjustment, we need
+ * to shift the hotspot to compensate and clamp position to 0. This
+ * handles the case where cursor straddles the left/top edge of an
+ * overlay plane - the cursor is partially visible and needs correct
+ * hotspot adjustment to render the visible portion.
+ */
+ if (x_pos < 0) {
+ pos_cpy.x_hotspot -= x_pos;
+ if (hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION)
+ adjust_hotspot_between_slices_for_2x_magnify(hubp->curs_attr.width, &pos_cpy);
+ x_pos = 0;
+ }
+
+ if (y_pos < 0) {
+ pos_cpy.y_hotspot -= y_pos;
+ y_pos = 0;
+ }
+
recout_x_pos = x_pos - pos_cpy.x_hotspot;
recout_y_pos = y_pos - pos_cpy.y_hotspot;