mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
a34255b795
Removed upstreamed: bcm27xx/patches-5.15/950-0446-drm-vc4-Fix-timings-for-VEC-modes.patch[1] Manually rebased: patches-5.15/950-0600-xhci-quirks-add-link-TRB-quirk-for-VL805.patch bcm27xx/patches-5.15/950-0606-usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch bcm27xx/patches-5.15/950-0717-usb-xhci-add-a-quirk-for-Superspeed-bulk-OUT-transfe.patch bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch All other patches automatically rebased 1. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.15.75&id=2810061452f9b748b096ad023d318690ca519aa3 Build system: x86_64 Build-tested: bcm2711/RPi4B, mt7622/RT3200 Run-tested: bcm2711/RPi4B, mt7622/RT3200 Signed-off-by: John Audia <therealgraysky@proton.me>
98 lines
3.4 KiB
Diff
98 lines
3.4 KiB
Diff
From a0bc59127231cbea506651c362d4836a0ff5591f Mon Sep 17 00:00:00 2001
|
|
From: Maxime Ripard <maxime@cerno.tech>
|
|
Date: Wed, 8 Sep 2021 21:12:26 +0200
|
|
Subject: [PATCH] drm/vc4: Fix out of order frames during asynchronous
|
|
page flips
|
|
|
|
When doing an asynchronous page flip (PAGE_FLIP ioctl with the
|
|
DRM_MODE_PAGE_FLIP_ASYNC flag set), the current code waits for the
|
|
possible GPU buffer being rendered through a call to
|
|
vc4_queue_seqno_cb().
|
|
|
|
On the BCM2835-37, the GPU driver is part of the vc4 driver and that
|
|
function is defined in vc4_gem.c to wait for the buffer to be rendered,
|
|
and once it's done, call a callback.
|
|
|
|
However, on the BCM2711 used on the RaspberryPi4, the GPU driver is
|
|
separate (v3d) and that function won't do anything. This was working
|
|
because we were going into a path, due to uninitialized variables, that
|
|
was always scheduling the callback.
|
|
|
|
However, we were never actually waiting for the buffer to be rendered
|
|
which was resulting in frames being displayed out of order.
|
|
|
|
The generic API to signal those kind of completion in the kernel are the
|
|
DMA fences, and fortunately the v3d drivers supports them and signal
|
|
when its job is done. That API also provides an equivalent function that
|
|
allows to have a callback being executed when the fence is signalled as
|
|
done.
|
|
|
|
Let's change our driver a bit to rely on the previous function for the
|
|
older SoCs, and on DMA fences for the BCM2711.
|
|
|
|
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
|
---
|
|
drivers/gpu/drm/vc4/vc4_crtc.c | 37 ++++++++++++++++++++++++++++++++--
|
|
1 file changed, 35 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
|
|
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
|
|
@@ -797,6 +797,7 @@ struct vc4_async_flip_state {
|
|
struct drm_pending_vblank_event *event;
|
|
|
|
struct vc4_seqno_cb cb;
|
|
+ struct dma_fence_cb fence_cb;
|
|
};
|
|
|
|
/* Called when the V3D execution for the BO being flipped to is done, so that
|
|
@@ -842,6 +843,39 @@ vc4_async_page_flip_complete(struct vc4_
|
|
kfree(flip_state);
|
|
}
|
|
|
|
+static void vc4_async_page_flip_fence_complete(struct dma_fence *fence,
|
|
+ struct dma_fence_cb *cb)
|
|
+{
|
|
+ struct vc4_async_flip_state *flip_state =
|
|
+ container_of(cb, struct vc4_async_flip_state, fence_cb);
|
|
+
|
|
+ vc4_async_page_flip_complete(&flip_state->cb);
|
|
+ dma_fence_put(fence);
|
|
+}
|
|
+
|
|
+static int vc4_async_set_fence_cb(struct drm_device *dev,
|
|
+ struct vc4_async_flip_state *flip_state)
|
|
+{
|
|
+ struct drm_framebuffer *fb = flip_state->fb;
|
|
+ struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
|
|
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
|
|
+ struct dma_fence *fence;
|
|
+
|
|
+ if (!vc4->hvs->hvs5) {
|
|
+ struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
|
|
+
|
|
+ return vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno,
|
|
+ vc4_async_page_flip_complete);
|
|
+ }
|
|
+
|
|
+ fence = dma_fence_get(dma_resv_excl_fence(cma_bo->base.resv));
|
|
+ if (dma_fence_add_callback(fence, &flip_state->fence_cb,
|
|
+ vc4_async_page_flip_fence_complete))
|
|
+ vc4_async_page_flip_fence_complete(fence, &flip_state->fence_cb);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Implements async (non-vblank-synced) page flips.
|
|
*
|
|
* The page flip ioctl needs to return immediately, so we grab the
|
|
@@ -902,8 +936,7 @@ static int vc4_async_page_flip(struct dr
|
|
*/
|
|
drm_atomic_set_fb_for_plane(plane->state, fb);
|
|
|
|
- vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno,
|
|
- vc4_async_page_flip_complete);
|
|
+ vc4_async_set_fence_cb(dev, flip_state);
|
|
|
|
/* Driver takes ownership of state on successful async commit. */
|
|
return 0;
|