aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Ripard2020-09-03 10:01:01 +0200
committerMaxime Ripard2020-09-07 18:04:08 +0200
commitb7cb67a6b4fbb99a297bb0a57d906f56d81b29c9 (patch)
tree4b86aaab59405deb1be000c5bf4a3621c2aeec85
parent792c3132bc1b0990db8e3dbef2e9a49bdf80cd62 (diff)
drm/vc4: crtc: Add a delay after disabling the PixelValve output
In order to avoid pixels getting stuck in the (unflushable) FIFO between the HVS and the PV, we need to add some delay after disabling the PV output and before disabling the HDMI controller. 20ms seems to be good enough so let's use that. Signed-off-by: Maxime Ripard <maxime@cerno.tech> Tested-by: Chanwoo Choi <cw00.choi@samsung.com> Tested-by: Hoegeun Kwon <hoegeun.kwon@samsung.com> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Link: https://patchwork.freedesktop.org/patch/msgid/15cf215bd2ceebd203c4010c09c21a4019c650ed.1599120059.git-series.maxime@cerno.tech
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index d0b326e1df0a..4c23cf8aefb9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -403,6 +403,24 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
+ /*
+ * This delay is needed to avoid to get a pixel stuck in an
+ * unflushable FIFO between the pixelvalve and the HDMI
+ * controllers on the BCM2711.
+ *
+ * Timing is fairly sensitive here, so mdelay is the safest
+ * approach.
+ *
+ * If it was to be reworked, the stuck pixel happens on a
+ * BCM2711 when changing mode with a good probability, so a
+ * script that changes mode on a regular basis should trigger
+ * the bug after less than 10 attempts. It manifests itself with
+ * every pixels being shifted by one to the right, and thus the
+ * last pixel of a line actually being displayed as the first
+ * pixel on the next line.
+ */
+ mdelay(20);
+
if (vc4_encoder->post_crtc_disable)
vc4_encoder->post_crtc_disable(encoder);