diff mbox

drm/imx: move arming of the vblank event to atomic_flush

Message ID 20180315091159.5857-1-l.stach@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Stach March 15, 2018, 9:11 a.m. UTC
Right now the vblank event completion is racing with the atomic update,
which is especially bad when the PRE is in use, as one of the hardware
issue workaround might extend the atomic commit for quite some time.

If the vblank IRQ happens to trigger during that time, we will prematurely
signal the atomic commit completion to userspace, which causes tearing
when userspace re-uses a framebuffer we haven't managed to flip away from
yet.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/gpu/drm/imx/ipuv3-crtc.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Philipp Zabel March 16, 2018, 2:39 p.m. UTC | #1
On Thu, 2018-03-15 at 10:11 +0100, Lucas Stach wrote:
> Right now the vblank event completion is racing with the atomic update,
> which is especially bad when the PRE is in use, as one of the hardware
> issue workaround might extend the atomic commit for quite some time.
> 
> If the vblank IRQ happens to trigger during that time, we will prematurely
> signal the atomic commit completion to userspace, which causes tearing
> when userspace re-uses a framebuffer we haven't managed to flip away from
> yet.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>

This trades the tiny (on i.MX6Q) or not so tiny (on i.MX6QP) risk of
returning a vblank event completion too early for the tiny risk to miss
a vsync interrupt, and to return a vblank event completion a frame too
late. Applied to imx-drm/fixes.

regards
Philipp
diff mbox

Patch

diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 9a9961802f5c..e83af0f2be86 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -225,7 +225,11 @@  static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
 				  struct drm_crtc_state *old_crtc_state)
 {
 	drm_crtc_vblank_on(crtc);
+}
 
+static void ipu_crtc_atomic_flush(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
+{
 	spin_lock_irq(&crtc->dev->event_lock);
 	if (crtc->state->event) {
 		WARN_ON(drm_crtc_vblank_get(crtc));
@@ -293,6 +297,7 @@  static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
 	.mode_set_nofb = ipu_crtc_mode_set_nofb,
 	.atomic_check = ipu_crtc_atomic_check,
 	.atomic_begin = ipu_crtc_atomic_begin,
+	.atomic_flush = ipu_crtc_atomic_flush,
 	.atomic_disable = ipu_crtc_atomic_disable,
 	.atomic_enable = ipu_crtc_atomic_enable,
 };