v4l: vsp1: Don't recycle active list at display start
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 21 Jun 2017 11:32:45 +0000 (14:32 +0300)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Sat, 29 Jul 2017 20:46:56 +0000 (23:46 +0300)
When the display start interrupt occurs, we know that the hardware has
finished loading the active display list. The driver then proceeds to
recycle the list, assuming it won't be needed anymore.

This assumption holds true for headerless display lists, as the VSP
doesn't reload the list for the next frame if it hasn't changed.
However, this isn't true anymore for header display lists, as they are
loaded at every frame start regardless of whether they have been
updated.

To prepare for header display lists usage in display pipelines, we need
to postpone recycling the list until it gets replaced by a new one
through a page flip. The driver already does so in the frame end
interrupt handler, so all we need is to skip list recycling in the
display start interrupt handler.

While the active list can be recycled at display start for headerless
display lists, there's no real harm in postponing that to the frame end
interrupt handler in all cases. This simplifies interrupt handling as we
don't need to process the display start interrupt anymore.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Acked-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/vsp1/vsp1_dl.c
drivers/media/platform/vsp1/vsp1_dl.h
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/platform/vsp1/vsp1_drm.h
drivers/media/platform/vsp1/vsp1_drv.c

index dc47e236c780da70011ee2749f5c352f77105349..bb92be4fe0f022cc64b580212420a5e35683e404 100644 (file)
@@ -547,22 +547,6 @@ done:
  * Display List Manager
  */
 
-/* Interrupt Handling */
-void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm)
-{
-       spin_lock(&dlm->lock);
-
-       /*
-        * The display start interrupt signals the end of the display list
-        * processing by the device. The active display list, if any, won't be
-        * accessed anymore and can be reused.
-        */
-       __vsp1_dl_list_put(dlm->active);
-       dlm->active = NULL;
-
-       spin_unlock(&dlm->lock);
-}
-
 /**
  * vsp1_dlm_irq_frame_end - Display list handler for the frame end interrupt
  * @dlm: the display list manager
index 6ec1380a10afbf6e2cdbd037a589d284a036fbd4..ee3508172f0a7fd4b4fb17082c48caebb64aaa6b 100644 (file)
@@ -27,7 +27,6 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
                                        unsigned int prealloc);
 void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm);
 void vsp1_dlm_reset(struct vsp1_dl_manager *dlm);
-void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm);
 bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm);
 
 struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
index 9377aafa8996a8d839db535c455e5e619e2d79ab..bc3fd9bc7126c61348e152fb2a1905c00db112cc 100644 (file)
  * Interrupt Handling
  */
 
-void vsp1_drm_display_start(struct vsp1_device *vsp1)
-{
-       vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm);
-}
-
 static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe)
 {
        struct vsp1_drm *drm = to_vsp1_drm(pipe);
@@ -224,6 +219,10 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
                return ret;
        }
 
+       /* Disable the display interrupts. */
+       vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
+       vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
+
        dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
 
        return 0;
@@ -529,13 +528,10 @@ void vsp1_du_atomic_flush(struct device *dev)
 
        /* Start or stop the pipeline if needed. */
        if (!vsp1->drm->num_inputs && pipe->num_inputs) {
-               vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
-               vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
                spin_lock_irqsave(&pipe->irqlock, flags);
                vsp1_pipeline_run(pipe);
                spin_unlock_irqrestore(&pipe->irqlock, flags);
        } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
-               vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
                vsp1_pipeline_stop(pipe);
        }
 }
index e9f80727ff92140a41d08b83dfd0a33c12dcc54e..cbdbb8a39883838a110fabcc0fc8c01d55c3cbe6 100644 (file)
@@ -50,6 +50,4 @@ int vsp1_drm_init(struct vsp1_device *vsp1);
 void vsp1_drm_cleanup(struct vsp1_device *vsp1);
 int vsp1_drm_create_links(struct vsp1_device *vsp1);
 
-void vsp1_drm_display_start(struct vsp1_device *vsp1);
-
 #endif /* __VSP1_DRM_H__ */
index 95c26edead85291f097a4850a08c95e5490ce50d..6b35e043b554378505ef0159435375a8fa6435c7 100644 (file)
@@ -68,14 +68,6 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
                }
        }
 
-       status = vsp1_read(vsp1, VI6_DISP_IRQ_STA);
-       vsp1_write(vsp1, VI6_DISP_IRQ_STA, ~status & VI6_DISP_IRQ_STA_DST);
-
-       if (status & VI6_DISP_IRQ_STA_DST) {
-               vsp1_drm_display_start(vsp1);
-               ret = IRQ_HANDLED;
-       }
-
        return ret;
 }