diff options
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-.patch | 78 |
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 + |