Commit 577d3983 authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

drm: omapdrm: Prevent processing the same event multiple times



The vblank interrupt is disabled after one occurrence, preventing the
atomic update event from being processed twice. However, this also
prevents the software frame counter from being updated correctly that
would require vblank interrupts to be kept enabled while the CRTC is
active.

In preparation for vblank interrupt fixes, make sure that the atomic
update event will be processed once only when the vblank interrupt will
be kept enabled.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 03af8157
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ struct omap_crtc {
	bool enabled;
	bool pending;
	wait_queue_head_t pending_wait;
	struct drm_pending_vblank_event *event;
};

/* -----------------------------------------------------------------------------
@@ -263,16 +264,16 @@ static const struct dss_mgr_ops mgr_ops = {

static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_pending_vblank_event *event;
	struct drm_device *dev = crtc->dev;
	unsigned long flags;

	event = crtc->state->event;

	if (!event)
		return;

	spin_lock_irqsave(&dev->event_lock, flags);
	event = omap_crtc->event;
	omap_crtc->event = NULL;

	if (event)
		drm_crtc_send_vblank_event(crtc, event);
	spin_unlock_irqrestore(&dev->event_lock, flags);
}
@@ -431,6 +432,12 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
	omap_crtc->pending = true;
	wmb();

	if (crtc->state->event) {
		spin_lock_irq(&crtc->dev->event_lock);
		omap_crtc->event = crtc->state->event;
		spin_unlock_irq(&crtc->dev->event_lock);
	}

	dispc_mgr_go(omap_crtc->channel);
	omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
}