aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1700-drm-amd-display-Prevent-cursor-hotspot-overflow-for-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1700-drm-amd-display-Prevent-cursor-hotspot-overflow-for-.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1700-drm-amd-display-Prevent-cursor-hotspot-overflow-for-.patch78
1 files changed, 78 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1700-drm-amd-display-Prevent-cursor-hotspot-overflow-for-.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1700-drm-amd-display-Prevent-cursor-hotspot-overflow-for-.patch
new file mode 100644
index 00000000..563f65f2
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1700-drm-amd-display-Prevent-cursor-hotspot-overflow-for-.patch
@@ -0,0 +1,78 @@
+From 01722258fac103b96bdd66f377fa7211f5586a05 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Mon, 11 Mar 2019 10:33:35 -0400
+Subject: [PATCH 1700/2940] drm/amd/display: Prevent cursor hotspot overflow
+ for RV overlay planes
+
+[Why]
+The actual position for the cursor on the screen is essentially:
+
+x_out = x - x_plane - x_hotspot
+y_out = y - y_plane - y_hotspot
+
+The register values for cursor position and cursor hotspot need to be
+greater than zero when programmed, but we also need to subtract off
+the plane position to display the cursor at the correct position.
+
+Since we don't want x or y to be less than zero, we add the plane
+position as a positive value to x_hotspot or y_hotspot. However, what
+this doesn't take into account is that the hotspot registers are limited
+by the maximum cursor size.
+
+On DCN10 the cursor hotspot regitsers are masked to 0xFF, so they have
+a maximum value of 0-255. Values greater this will wrap, causing the
+cursor to display in the wrong position.
+
+In practice this means that for sufficiently large plane positions, the
+cursor will be drawn twice on the screen, and can cause screen flashes
+or p-state WARNS depending on what the wrapped value is.
+
+So we need a way to remove the value from x_plane and y_plane without
+exceeding the maximum cursor size.
+
+[How]
+Subtract as much as x_plane/y_plane as possible from x and y and place
+the remainder in the cursor hotspot register.
+
+The value for x_hotspot and y_hotspot can still wrap around but it
+won't happen in a case where the cursor is actually enabled.
+
+The cursor plane needs to intersect at least one pixel of the plane's
+rectangle to be enabled, so the cursor position + hotspot provided by
+userspace must always be strictly less than the maximum cursor size for
+the cursor to actually be enabled.
+
+Change-Id: Ib1fe26aecaa10abad36547ab36a7d0246217c69b
+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>
+---
+ .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 2e5ff2c49aa2..439012f6ac35 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -2709,9 +2709,15 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
+ .rotation = pipe_ctx->plane_state->rotation,
+ .mirror = pipe_ctx->plane_state->horizontal_mirror
+ };
+-
+- pos_cpy.x_hotspot += pipe_ctx->plane_state->dst_rect.x;
+- pos_cpy.y_hotspot += pipe_ctx->plane_state->dst_rect.y;
++ uint32_t x_plane = pipe_ctx->plane_state->dst_rect.x;
++ uint32_t y_plane = pipe_ctx->plane_state->dst_rect.y;
++ uint32_t x_offset = min(x_plane, pos_cpy.x);
++ uint32_t y_offset = min(y_plane, pos_cpy.y);
++
++ pos_cpy.x -= x_offset;
++ pos_cpy.y -= y_offset;
++ pos_cpy.x_hotspot += (x_plane - x_offset);
++ pos_cpy.y_hotspot += (y_plane - y_offset);
+
+ if (pipe_ctx->plane_state->address.type
+ == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+--
+2.17.1
+