1 From 57b528e557890f25e010b6bc7356b5a716c79db2 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Tue, 12 Nov 2024 17:58:52 +0000
4 Subject: [PATCH] drm/vc4: hvs: Defer updating the enable_bg_fill until vblank
6 The register to enable/disable background fill was being set
7 from atomic flush, however that will be applied immediately and
8 can be a while before the vblank. If it was required for the
9 current frame but not for the next one, that can result in
10 corruption for part of the current frame.
12 Store the state in vc4_hvs, and update it on vblank.
14 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
16 drivers/gpu/drm/vc4/vc4_drv.h | 2 ++
17 drivers/gpu/drm/vc4/vc4_hvs.c | 18 ++++++++++--------
18 2 files changed, 12 insertions(+), 8 deletions(-)
20 --- a/drivers/gpu/drm/vc4/vc4_drv.h
21 +++ b/drivers/gpu/drm/vc4/vc4_drv.h
22 @@ -339,6 +339,8 @@ struct vc4_hvs {
23 unsigned int enabled: 1;
24 } eof_irq[HVS_NUM_CHANNELS];
26 + bool bg_fill[HVS_NUM_CHANNELS];
28 unsigned long max_core_rate;
30 /* Memory manager for CRTCs to allocate space in the display
31 --- a/drivers/gpu/drm/vc4/vc4_hvs.c
32 +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
33 @@ -1470,14 +1470,7 @@ void vc4_hvs_atomic_flush(struct drm_crt
34 /* This sets a black background color fill, as is the case
35 * with other DRM drivers.
38 - HVS_WRITE(SCALER6_DISPX_CTRL1(channel),
39 - HVS_READ(SCALER6_DISPX_CTRL1(channel)) |
40 - SCALER6(DISPX_CTRL1_BGENB));
42 - HVS_WRITE(SCALER6_DISPX_CTRL1(channel),
43 - HVS_READ(SCALER6_DISPX_CTRL1(channel)) &
44 - ~SCALER6(DISPX_CTRL1_BGENB));
45 + hvs->bg_fill[channel] = enable_bg_fill;
47 /* we can actually run with a lower core clock when background
48 * fill is enabled on VC4_GEN_5 so leave it enabled always.
49 @@ -1662,6 +1655,15 @@ static irqreturn_t vc6_hvs_eof_irq_handl
50 if (hvs->eof_irq[i].desc != irq)
53 + if (hvs->bg_fill[i])
54 + HVS_WRITE(SCALER6_DISPX_CTRL1(i),
55 + HVS_READ(SCALER6_DISPX_CTRL1(i)) |
56 + SCALER6(DISPX_CTRL1_BGENB));
58 + HVS_WRITE(SCALER6_DISPX_CTRL1(i),
59 + HVS_READ(SCALER6_DISPX_CTRL1(i)) &
60 + ~SCALER6(DISPX_CTRL1_BGENB));
62 vc4_hvs_schedule_dlist_sweep(hvs, i);