}
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
 
+/**
+ * drm_atomic_helper_fake_vblank - fake VBLANK events if needed
+ * @old_state: atomic state object with old state structures
+ *
+ * This function walks all CRTCs and fake VBLANK events on those with
+ * &drm_crtc_state.no_vblank set to true and &drm_crtc_state.event != NULL.
+ * The primary use of this function is writeback connectors working in oneshot
+ * mode and faking VBLANK events. In this case they only fake the VBLANK event
+ * when a job is queued, and any change to the pipeline that does not touch the
+ * connector is leading to timeouts when calling
+ * drm_atomic_helper_wait_for_vblanks() or
+ * drm_atomic_helper_wait_for_flip_done().
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
+ */
+void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)
+{
+       struct drm_crtc_state *new_crtc_state;
+       struct drm_crtc *crtc;
+       int i;
+
+       for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+               unsigned long flags;
+
+               if (!new_crtc_state->no_vblank)
+                       continue;
+
+               spin_lock_irqsave(&old_state->dev->event_lock, flags);
+               if (new_crtc_state->event) {
+                       drm_crtc_send_vblank_event(crtc,
+                                                  new_crtc_state->event);
+                       new_crtc_state->event = NULL;
+               }
+               spin_unlock_irqrestore(&old_state->dev->event_lock, flags);
+       }
+}
+EXPORT_SYMBOL(drm_atomic_helper_fake_vblank);
+
 /**
  * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit
  * @old_state: atomic state object with old state structures
 
 int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
                                   bool nonblock);
 void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_fake_vblank(struct drm_atomic_state *state);
 void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
 void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
 
 
        bool zpos_changed : 1;
        bool color_mgmt_changed : 1;
 
+       /**
+        * @no_vblank:
+        *
+        * Reflects the ability of a CRTC to send VBLANK events. This state
+        * usually depends on the pipeline configuration, and the main usuage
+        * is CRTCs feeding a writeback connector operating in oneshot mode.
+        * In this case the VBLANK event is only generated when a job is queued
+        * to the writeback connector, and we want the core to fake VBLANK
+        * events when this part of the pipeline hasn't changed but others had
+        * or when the CRTC and connectors are being disabled.
+        *
+        * __drm_atomic_helper_crtc_duplicate_state() will not reset the value
+        * from the current state, the CRTC driver is then responsible for
+        * updating this field when needed.
+        *
+        * Note that the combination of &drm_crtc_state.event == NULL and
+        * &drm_crtc_state.no_blank == true is valid and usually used when the
+        * writeback connector attached to the CRTC has a new job queued. In
+        * this case the driver will send the VBLANK event on its own when the
+        * writeback job is complete.
+        */
+       bool no_vblank : 1;
+
        /* attached planes bitmask:
         * WARNING: transitional helpers do not maintain plane_mask so
         * drivers not converted over to atomic helpers should not rely