aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0732-drm-amd-display-Clean-up-cursor-code.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0732-drm-amd-display-Clean-up-cursor-code.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/0732-drm-amd-display-Clean-up-cursor-code.patch353
1 files changed, 353 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0732-drm-amd-display-Clean-up-cursor-code.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0732-drm-amd-display-Clean-up-cursor-code.patch
new file mode 100644
index 00000000..bd038211
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0732-drm-amd-display-Clean-up-cursor-code.patch
@@ -0,0 +1,353 @@
+From 4f58082aaa5f35ce2d7150443b6f82743afbab8e Mon Sep 17 00:00:00 2001
+From: Harry Wentland <harry.wentland@amd.com>
+Date: Mon, 31 Jul 2017 16:32:18 -0400
+Subject: [PATCH 0732/4131] drm/amd/display: Clean up cursor code
+
+This will also fix disappearing cursor after resume.
+
+With this change we'll set cursor attributes, as well as
+cursor position on every update. The impact is minor.
+
+These are sample logs that show timestamps at beginning
+and end of atomic_check, commit_tail, handle_cursor_update,
+and before and after cursor_attribute and cursor_position
+calls:
+
+[ 66.800353] hwhw: begin of check
+[ 66.800377] hwhw: end of check
+[ 66.800428] hwhw: begin of commit_tail
+[ 66.800441] hwhw: begin of cursor
+[ 66.800449] hwhw: begin of cursor_attr
+[ 66.800468] hwhw: end of cursor_attr
+[ 66.800484] hwhw: end of cursor_positionr
+[ 66.800501] hwhw: end of commit_tail
+[ 66.807139] hwhw: begin of check
+[ 66.807160] hwhw: end of check
+[ 66.807206] hwhw: begin of commit_tail
+[ 66.807217] hwhw: begin of cursor
+[ 66.807225] hwhw: begin of cursor_attr
+[ 66.807357] hwhw: end of cursor_attr
+[ 66.807374] hwhw: end of cursor_positionr
+[ 66.807392] hwhw: end of commit_tail
+
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Reviewed-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
+Acked-by: Harry Wentland <Harry.Wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 283 +++++++---------------
+ 1 file changed, 92 insertions(+), 191 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 d81c0a0..031f31c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1652,178 +1652,6 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
+ .destroy = amdgpu_dm_encoder_destroy,
+ };
+
+-static void dm_set_cursor(
+- struct amdgpu_crtc *amdgpu_crtc,
+- uint64_t gpu_addr,
+- uint32_t width,
+- uint32_t height)
+-{
+- struct dc_cursor_attributes attributes;
+- struct dc_cursor_position position;
+- struct drm_crtc *crtc = &amdgpu_crtc->base;
+- int x, y;
+- int xorigin = 0, yorigin = 0;
+- struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
+-
+- amdgpu_crtc->cursor_width = width;
+- amdgpu_crtc->cursor_height = height;
+-
+- attributes.address.high_part = upper_32_bits(gpu_addr);
+- attributes.address.low_part = lower_32_bits(gpu_addr);
+- attributes.width = width;
+- attributes.height = height;
+- attributes.color_format = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA;
+- attributes.rotation_angle = 0;
+- attributes.attribute_flags.value = 0;
+-
+- attributes.pitch = attributes.width;
+-
+- x = amdgpu_crtc->cursor_x;
+- y = amdgpu_crtc->cursor_y;
+-
+- /* avivo cursor are offset into the total surface */
+- x += crtc->primary->state->src_x >> 16;
+- y += crtc->primary->state->src_y >> 16;
+-
+- 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;
+- }
+-
+- position.enable = true;
+- position.x = x;
+- position.y = y;
+-
+- position.x_hotspot = xorigin;
+- position.y_hotspot = yorigin;
+-
+- if (!dc_stream_set_cursor_attributes(
+- acrtc_state->stream,
+- &attributes)) {
+- DRM_ERROR("DC failed to set cursor attributes\n");
+- }
+-
+- if (!dc_stream_set_cursor_position(
+- acrtc_state->stream,
+- &position)) {
+- DRM_ERROR("DC failed to set cursor position\n");
+- }
+-}
+-
+-static int dm_crtc_cursor_set(
+- struct drm_crtc *crtc,
+- uint64_t address,
+- uint32_t width,
+- uint32_t height)
+-{
+- struct dc_cursor_position position;
+- struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
+-
+- int ret;
+-
+- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+- ret = EINVAL;
+-
+- DRM_DEBUG_KMS("%s: crtc_id=%d with size %d to %d \n",
+- __func__,
+- amdgpu_crtc->crtc_id,
+- width,
+- height);
+-
+- if (!address) {
+- /* turn off cursor */
+- position.enable = false;
+- position.x = 0;
+- position.y = 0;
+-
+- if (acrtc_state->stream) {
+- /*set cursor visible false*/
+- dc_stream_set_cursor_position(
+- acrtc_state->stream,
+- &position);
+- }
+- goto release;
+-
+- }
+-
+- if ((width > amdgpu_crtc->max_cursor_width) ||
+- (height > amdgpu_crtc->max_cursor_height)) {
+- DRM_ERROR(
+- "%s: bad cursor width or height %d x %d\n",
+- __func__,
+- width,
+- height);
+- goto release;
+- }
+-
+- /*program new cursor bo to hardware*/
+- dm_set_cursor(amdgpu_crtc, address, width, height);
+-
+-release:
+- return ret;
+-
+-}
+-
+-static int dm_crtc_cursor_move(struct drm_crtc *crtc,
+- int x, int y)
+-{
+- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+- int xorigin = 0, yorigin = 0;
+- struct dc_cursor_position position;
+- struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
+-
+- amdgpu_crtc->cursor_x = x;
+- amdgpu_crtc->cursor_y = y;
+-
+- /* avivo cursor are offset into the total surface */
+- x += crtc->primary->state->src_x >> 16;
+- y += crtc->primary->state->src_y >> 16;
+-
+- /*
+- * TODO: for cursor debugging unguard the following
+- */
+-#if 0
+- DRM_DEBUG_KMS(
+- "%s: x %d y %d c->x %d c->y %d\n",
+- __func__,
+- x,
+- y,
+- crtc->x,
+- crtc->y);
+-#endif
+-
+- 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;
+- }
+-
+- position.enable = true;
+- position.x = x;
+- position.y = y;
+-
+- position.x_hotspot = xorigin;
+- position.y_hotspot = yorigin;
+-
+- if (acrtc_state->stream) {
+- if (!dc_stream_set_cursor_position(
+- acrtc_state->stream,
+- &position)) {
+- DRM_ERROR("DC failed to set cursor position\n");
+- return -EINVAL;
+- }
+- }
+-
+- return 0;
+-}
+-
+ static bool fill_rects_from_plane_state(
+ const struct drm_plane_state *state,
+ struct dc_plane_state *plane_state)
+@@ -3940,34 +3768,107 @@ static void remove_stream(
+ acrtc->enabled = false;
+ }
+
++int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
++ struct dc_cursor_position *position)
++{
++ struct amdgpu_crtc *amdgpu_crtc = amdgpu_crtc = to_amdgpu_crtc(crtc);
++ int x, y;
++ int xorigin = 0, yorigin = 0;
++
++ if (!crtc || !plane->state->fb) {
++ position->enable = false;
++ position->x = 0;
++ position->y = 0;
++ return 0;
++ }
++
++ if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) ||
++ (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) {
++ DRM_ERROR("%s: bad cursor width or height %d x %d\n",
++ __func__,
++ plane->state->crtc_w,
++ plane->state->crtc_h);
++ return -EINVAL;
++ }
++
++ x = plane->state->crtc_x;
++ y = plane->state->crtc_y;
++ /* avivo cursor are offset into the total surface */
++ x += crtc->primary->state->src_x >> 16;
++ y += crtc->primary->state->src_y >> 16;
++ 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;
++ }
++ position->enable = true;
++ position->x = x;
++ position->y = y;
++ position->x_hotspot = xorigin;
++ position->y_hotspot = yorigin;
++
++ return 0;
++}
++
+ static void handle_cursor_update(
+ struct drm_plane *plane,
+ struct drm_plane_state *old_plane_state)
+ {
++ struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb);
++ struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc;
++ struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
++ struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
++ uint64_t address = afb ? afb->address : 0;
++ struct dc_cursor_position position;
++ struct dc_cursor_attributes attributes;
++ int ret;
++
+ if (!plane->state->fb && !old_plane_state->fb)
+ return;
+
+- /* Check if it's a cursor on/off update or just cursor move*/
+- if (plane->state->fb == old_plane_state->fb)
+- dm_crtc_cursor_move(
+- plane->state->crtc,
+- plane->state->crtc_x,
+- plane->state->crtc_y);
+- else {
+- struct amdgpu_framebuffer *afb =
+- to_amdgpu_framebuffer(plane->state->fb);
+- dm_crtc_cursor_set(
+- (!!plane->state->fb) ?
+- plane->state->crtc :
+- old_plane_state->crtc,
+- (!!plane->state->fb) ?
+- afb->address :
+- 0,
+- plane->state->crtc_w,
+- plane->state->crtc_h);
++ DRM_DEBUG_KMS("%s: crtc_id=%d with size %d to %d\n",
++ __func__,
++ amdgpu_crtc->crtc_id,
++ plane->state->crtc_w,
++ plane->state->crtc_h);
++
++ ret = get_cursor_position(plane, crtc, &position);
++ if (ret)
++ return;
++
++ if (!position.enable) {
++ /* turn off cursor */
++ if (crtc_state && crtc_state->stream)
++ dc_stream_set_cursor_position(crtc_state->stream,
++ &position);
++ return;
+ }
+-}
+
++ amdgpu_crtc->cursor_width = plane->state->crtc_w;
++ amdgpu_crtc->cursor_height = plane->state->crtc_h;
++
++ attributes.address.high_part = upper_32_bits(address);
++ attributes.address.low_part = lower_32_bits(address);
++ attributes.width = plane->state->crtc_w;
++ attributes.height = plane->state->crtc_h;
++ attributes.color_format = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA;
++ attributes.rotation_angle = 0;
++ attributes.attribute_flags.value = 0;
++
++ attributes.pitch = attributes.width;
++
++ if (!dc_stream_set_cursor_attributes(crtc_state->stream,
++ &attributes))
++ DRM_ERROR("DC failed to set cursor attributes\n");
++
++ if (crtc_state->stream)
++ if (!dc_stream_set_cursor_position(crtc_state->stream,
++ &position))
++ DRM_ERROR("DC failed to set cursor position\n");
++}
+
+ static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
+ {
+--
+2.7.4
+