bcm27xx: 6.1: add kernel patches
[openwrt/staging/nbd.git] / target / linux / bcm27xx / patches-6.1 / 950-0053-drm-vc4-Add-async-update-support-for-cursor-planes.patch
1 From e6f7f8f83e736bb94b146781b149810853b2bff3 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <8911409+pelwell@users.noreply.github.com>
3 Date: Wed, 24 Aug 2022 11:14:40 +0100
4 Subject: [PATCH] drm/vc4: Add async update support for cursor planes
5
6 Now that cursors are implemented as regular planes, all cursor
7 movements result in atomic updates. As the firmware-kms driver
8 doesn't support asynchronous updates, these are synchronous, which
9 limits the update rate to the screen refresh rate. Xorg seems unaware
10 of this (or at least of the effect of this), because if the mouse is
11 configured with a higher update rate than the screen then continuous
12 mouse movement results in an increasing backlog of mouse events -
13 cue extreme lag.
14
15 Add minimal support for asynchronous updates - limited to cursor
16 planes - to eliminate the lag.
17
18 See: https://github.com/raspberrypi/linux/pull/4971
19 https://github.com/raspberrypi/linux/issues/4988
20
21 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
22 ---
23 drivers/gpu/drm/vc4/vc4_firmware_kms.c | 46 ++++++++++++++++++++++++++
24 1 file changed, 46 insertions(+)
25
26 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
27 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
28 @@ -675,6 +675,50 @@ static int vc4_plane_atomic_check(struct
29 return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
30 }
31
32 +static void vc4_plane_atomic_async_update(struct drm_plane *plane,
33 + struct drm_atomic_state *state)
34 +{
35 + struct drm_plane_state *new_plane_state =
36 + drm_atomic_get_new_plane_state(state, plane);
37 +
38 + swap(plane->state->fb, new_plane_state->fb);
39 + plane->state->crtc_x = new_plane_state->crtc_x;
40 + plane->state->crtc_y = new_plane_state->crtc_y;
41 + plane->state->crtc_w = new_plane_state->crtc_w;
42 + plane->state->crtc_h = new_plane_state->crtc_h;
43 + plane->state->src_x = new_plane_state->src_x;
44 + plane->state->src_y = new_plane_state->src_y;
45 + plane->state->src_w = new_plane_state->src_w;
46 + plane->state->src_h = new_plane_state->src_h;
47 + plane->state->alpha = new_plane_state->alpha;
48 + plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode;
49 + plane->state->rotation = new_plane_state->rotation;
50 + plane->state->zpos = new_plane_state->zpos;
51 + plane->state->normalized_zpos = new_plane_state->normalized_zpos;
52 + plane->state->color_encoding = new_plane_state->color_encoding;
53 + plane->state->color_range = new_plane_state->color_range;
54 + plane->state->src = new_plane_state->src;
55 + plane->state->dst = new_plane_state->dst;
56 + plane->state->visible = new_plane_state->visible;
57 +
58 + vc4_plane_set_blank(plane, false);
59 +}
60 +
61 +static int vc4_plane_atomic_async_check(struct drm_plane *plane,
62 + struct drm_atomic_state *state)
63 +{
64 + struct drm_plane_state *new_plane_state =
65 + drm_atomic_get_new_plane_state(state, plane);
66 + int ret = -EINVAL;
67 +
68 + if (plane->type == 2 &&
69 + plane->state->fb &&
70 + new_plane_state->crtc->state->active)
71 + ret = 0;
72 +
73 + return ret;
74 +}
75 +
76 /* Called during init to allocate the plane's atomic state. */
77 static void vc4_plane_reset(struct drm_plane *plane)
78 {
79 @@ -769,6 +813,8 @@ static const struct drm_plane_helper_fun
80 .atomic_check = vc4_plane_atomic_check,
81 .atomic_update = vc4_plane_atomic_update,
82 .atomic_disable = vc4_plane_atomic_disable,
83 + .atomic_async_check = vc4_plane_atomic_async_check,
84 + .atomic_async_update = vc4_plane_atomic_async_update,
85 };
86
87 static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,