mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 22:23:27 +00:00
88 lines
3.3 KiB
Diff
88 lines
3.3 KiB
Diff
|
From e6f7f8f83e736bb94b146781b149810853b2bff3 Mon Sep 17 00:00:00 2001
|
||
|
From: Phil Elwell <8911409+pelwell@users.noreply.github.com>
|
||
|
Date: Wed, 24 Aug 2022 11:14:40 +0100
|
||
|
Subject: [PATCH] drm/vc4: Add async update support for cursor planes
|
||
|
|
||
|
Now that cursors are implemented as regular planes, all cursor
|
||
|
movements result in atomic updates. As the firmware-kms driver
|
||
|
doesn't support asynchronous updates, these are synchronous, which
|
||
|
limits the update rate to the screen refresh rate. Xorg seems unaware
|
||
|
of this (or at least of the effect of this), because if the mouse is
|
||
|
configured with a higher update rate than the screen then continuous
|
||
|
mouse movement results in an increasing backlog of mouse events -
|
||
|
cue extreme lag.
|
||
|
|
||
|
Add minimal support for asynchronous updates - limited to cursor
|
||
|
planes - to eliminate the lag.
|
||
|
|
||
|
See: https://github.com/raspberrypi/linux/pull/4971
|
||
|
https://github.com/raspberrypi/linux/issues/4988
|
||
|
|
||
|
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||
|
---
|
||
|
drivers/gpu/drm/vc4/vc4_firmware_kms.c | 46 ++++++++++++++++++++++++++
|
||
|
1 file changed, 46 insertions(+)
|
||
|
|
||
|
--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
|
||
|
+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
|
||
|
@@ -675,6 +675,50 @@ static int vc4_plane_atomic_check(struct
|
||
|
return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
|
||
|
}
|
||
|
|
||
|
+static void vc4_plane_atomic_async_update(struct drm_plane *plane,
|
||
|
+ struct drm_atomic_state *state)
|
||
|
+{
|
||
|
+ struct drm_plane_state *new_plane_state =
|
||
|
+ drm_atomic_get_new_plane_state(state, plane);
|
||
|
+
|
||
|
+ swap(plane->state->fb, new_plane_state->fb);
|
||
|
+ plane->state->crtc_x = new_plane_state->crtc_x;
|
||
|
+ plane->state->crtc_y = new_plane_state->crtc_y;
|
||
|
+ plane->state->crtc_w = new_plane_state->crtc_w;
|
||
|
+ plane->state->crtc_h = new_plane_state->crtc_h;
|
||
|
+ plane->state->src_x = new_plane_state->src_x;
|
||
|
+ plane->state->src_y = new_plane_state->src_y;
|
||
|
+ plane->state->src_w = new_plane_state->src_w;
|
||
|
+ plane->state->src_h = new_plane_state->src_h;
|
||
|
+ plane->state->alpha = new_plane_state->alpha;
|
||
|
+ plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode;
|
||
|
+ plane->state->rotation = new_plane_state->rotation;
|
||
|
+ plane->state->zpos = new_plane_state->zpos;
|
||
|
+ plane->state->normalized_zpos = new_plane_state->normalized_zpos;
|
||
|
+ plane->state->color_encoding = new_plane_state->color_encoding;
|
||
|
+ plane->state->color_range = new_plane_state->color_range;
|
||
|
+ plane->state->src = new_plane_state->src;
|
||
|
+ plane->state->dst = new_plane_state->dst;
|
||
|
+ plane->state->visible = new_plane_state->visible;
|
||
|
+
|
||
|
+ vc4_plane_set_blank(plane, false);
|
||
|
+}
|
||
|
+
|
||
|
+static int vc4_plane_atomic_async_check(struct drm_plane *plane,
|
||
|
+ struct drm_atomic_state *state)
|
||
|
+{
|
||
|
+ struct drm_plane_state *new_plane_state =
|
||
|
+ drm_atomic_get_new_plane_state(state, plane);
|
||
|
+ int ret = -EINVAL;
|
||
|
+
|
||
|
+ if (plane->type == 2 &&
|
||
|
+ plane->state->fb &&
|
||
|
+ new_plane_state->crtc->state->active)
|
||
|
+ ret = 0;
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
/* Called during init to allocate the plane's atomic state. */
|
||
|
static void vc4_plane_reset(struct drm_plane *plane)
|
||
|
{
|
||
|
@@ -769,6 +813,8 @@ static const struct drm_plane_helper_fun
|
||
|
.atomic_check = vc4_plane_atomic_check,
|
||
|
.atomic_update = vc4_plane_atomic_update,
|
||
|
.atomic_disable = vc4_plane_atomic_disable,
|
||
|
+ .atomic_async_check = vc4_plane_atomic_async_check,
|
||
|
+ .atomic_async_update = vc4_plane_atomic_async_update,
|
||
|
};
|
||
|
|
||
|
static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
|