From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit e371e19c10a264bd72c2ff1d21e2167b994710d1 ]
[Why] When x or y is negative we set the x and y values to 0 and compensate with a positive cursor hotspot in DM since DC expects positive cursor values.
When x or y is less than or equal to the maximum cursor width or height the cursor hotspot is clamped so the hotspot doesn't exceed the cursor size:
if (x < 0) { xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1); x = 0; }
if (y < 0) { yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1); y = 0; }
This incorrectly forces the cursor to be at least 1 pixel on the screen in either direction when x or y is sufficiently negative.
[How] Just disable the cursor when it goes far enough off the screen in one of these directions.
This fixes kms_cursor_crc@cursor-256x256-offscreen.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Sun peng Li Sunpeng.Li@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ab7c5c3004ee..fa268dd736f4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4952,12 +4952,12 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, int x, y; int xorigin = 0, yorigin = 0;
- if (!crtc || !plane->state->fb) { - position->enable = false; - position->x = 0; - position->y = 0; + position->enable = false; + position->x = 0; + position->y = 0; + + if (!crtc || !plane->state->fb) return 0; - }
if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) || (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) { @@ -4971,6 +4971,10 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, x = plane->state->crtc_x; y = plane->state->crtc_y;
+ if (x <= -amdgpu_crtc->max_cursor_width || + y <= -amdgpu_crtc->max_cursor_height) + return 0; + if (crtc->primary->state) { /* avivo cursor are offset into the total surface */ x += crtc->primary->state->src_x >> 16;