1 From 7bbbfef1c98e832cbd55e66ac2d7f13ec0a2b11e Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Fri, 21 Feb 2020 14:34:31 +0100
4 Subject: [PATCH] drm/vc4: crtc: Enable and disable the PV in
5 atomic_enable / disable
7 The VIDEN bit in the pixelvalve currently being used to enable or disable
8 the pixelvalve seems to not be enough in some situations, which whill end
9 up with the pixelvalve stalling.
11 In such a case, even re-enabling VIDEN doesn't bring it back and we need to
12 clear the FIFO. This can only be done if the pixelvalve is disabled though.
14 In order to overcome this, we can configure the pixelvalve during
15 mode_set_no_fb, but only enable it in atomic_enable and flush the FIFO
16 there, and in atomic_disable disable the pixelvalve again.
18 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
20 drivers/gpu/drm/vc4/vc4_crtc.c | 10 +++++++---
21 1 file changed, 7 insertions(+), 3 deletions(-)
23 --- a/drivers/gpu/drm/vc4/vc4_crtc.c
24 +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
25 @@ -374,9 +374,7 @@ static void vc4_crtc_config_pv(struct dr
26 PV_CONTROL_TRIGGER_UNDERFLOW |
27 PV_CONTROL_WAIT_HSTART |
28 VC4_SET_FIELD(vc4_encoder->clock_select,
29 - PV_CONTROL_CLK_SELECT) |
30 - PV_CONTROL_FIFO_CLR |
32 + PV_CONTROL_CLK_SELECT));
35 static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
36 @@ -467,6 +465,8 @@ static void vc4_crtc_atomic_disable(stru
37 ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
38 WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
40 + CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
42 if (HVS_READ(SCALER_DISPCTRLX(chan)) &
43 SCALER_DISPCTRLX_ENABLE) {
44 HVS_WRITE(SCALER_DISPCTRLX(chan),
45 @@ -554,6 +554,10 @@ static void vc4_crtc_atomic_enable(struc
47 require_hvs_enabled(dev);
49 + /* Reset the PV fifo. */
50 + CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) |
51 + PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
53 /* Enable vblank irq handling before crtc is started otherwise
54 * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().