bool vblank_enabled;
u32 display_number;
u32 display_type;
+
+ u32 cnt_vblanks;
};
static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc)
static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n",
crtc->base.id);
+
+ vc4_crtc->cnt_vblanks = 2;
+
if (crtc->state->active && old_state->active && crtc->state->event)
vc4_crtc_consume_event(crtc);
}
struct drm_device *dev = crtc->dev;
unsigned long flags;
+ /*
+ * WORKAROUND: A tearing problem occurs due to a firmware,
+ * so we wait for vblank twice and then run page_flip.
+ */
spin_lock_irqsave(&dev->event_lock, flags);
- if (vc4_crtc->event) {
+ if (vc4_crtc->cnt_vblanks)
+ vc4_crtc->cnt_vblanks--;
+ if (vc4_crtc->event && !vc4_crtc->cnt_vblanks) {
drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
vc4_crtc->event = NULL;
drm_crtc_vblank_put(crtc);