* @fragments: list of extra display list bodies
  * @has_chain: if true, indicates that there's a partition chain
  * @chain: entry in the display list partition chain
+ * @internal: whether the display list is used for internal purpose
  */
 struct vsp1_dl_list {
        struct list_head list;
 
        bool has_chain;
        struct list_head chain;
+
+       bool internal;
 };
 
 enum vsp1_dl_mode {
         * case we can't replace the queued list by the new one, as we could
         * race with the hardware. We thus mark the update as pending, it will
         * be queued up to the hardware by the frame end interrupt handler.
+        *
+        * If a display list is already pending we simply drop it as the new
+        * display list is assumed to contain a more recent configuration. It is
+        * an error if the already pending list has the internal flag set, as
+        * there is then a process waiting for that list to complete. This
+        * shouldn't happen as the waiting process should perform proper
+        * locking, but warn just in case.
         */
        if (vsp1_dl_list_hw_update_pending(dlm)) {
+               WARN_ON(dlm->pending && dlm->pending->internal);
                __vsp1_dl_list_put(dlm->pending);
                dlm->pending = dl;
                return;
        dlm->active = dl;
 }
 
-void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
+void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
 {
        struct vsp1_dl_manager *dlm = dl->dlm;
        struct vsp1_dl_list *dl_child;
                }
        }
 
+       dl->internal = internal;
+
        spin_lock_irqsave(&dlm->lock, flags);
 
        if (dlm->singleshot)
  * raced with the frame end interrupt. The function always returns with the flag
  * set in header mode as display list processing is then not continuous and
  * races never occur.
+ *
+ * The VSP1_DL_FRAME_END_INTERNAL flag indicates that the previous display list
+ * has completed and had been queued with the internal notification flag.
+ * Internal notification is only supported for continuous mode.
  */
 unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 {
         * frame end interrupt. The display list thus becomes active.
         */
        if (dlm->queued) {
+               if (dlm->queued->internal)
+                       flags |= VSP1_DL_FRAME_END_INTERNAL;
+               dlm->queued->internal = false;
+
                __vsp1_dl_list_put(dlm->active);
                dlm->active = dlm->queued;
                dlm->queued = NULL;
 
 struct vsp1_dl_manager;
 
 #define VSP1_DL_FRAME_END_COMPLETED            BIT(0)
+#define VSP1_DL_FRAME_END_INTERNAL             BIT(1)
 
 void vsp1_dlm_setup(struct vsp1_device *vsp1);
 
 struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
 void vsp1_dl_list_put(struct vsp1_dl_list *dl);
 void vsp1_dl_list_write(struct vsp1_dl_list *dl, u32 reg, u32 data);
-void vsp1_dl_list_commit(struct vsp1_dl_list *dl);
+void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal);
 
 struct vsp1_dl_body *vsp1_dl_fragment_alloc(struct vsp1_device *vsp1,
                                            unsigned int num_entries);