As V4L2 specification states, frame_count must also
regard lost frames so that the user can handle that
case properly.

This patch adds a mechanism to increment the frame
counter even when a video buffer is not available
and a discard buffer is used.

Signed-off-by: Javier Martin <javier.mar...@vista-silicon.com>
---
 drivers/media/video/mx2_camera.c |   54 ++++++++++++++++++++++++--------------
 1 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index ca76dd2..b244714 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -256,6 +256,7 @@ struct mx2_camera_dev {
        size_t                  discard_size;
        struct mx2_fmt_cfg      *emma_prp;
        u32                     frame_count;
+       unsigned int            firstirq;
 };
 
 /* buffer for one video frame */
@@ -370,6 +371,7 @@ static int mx2_camera_add_device(struct soc_camera_device 
*icd)
 
        pcdev->icd = icd;
        pcdev->frame_count = 0;
+       pcdev->firstirq = 1;
 
        dev_info(icd->parent, "Camera driver attached to camera %d\n",
                 icd->devnum);
@@ -572,6 +574,7 @@ static void mx2_videobuf_queue(struct videobuf_queue *vq,
        struct soc_camera_host *ici =
                to_soc_camera_host(icd->parent);
        struct mx2_camera_dev *pcdev = ici->priv;
+       struct mx2_fmt_cfg *prp = pcdev->emma_prp;
        struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
        unsigned long flags;
 
@@ -584,6 +587,26 @@ static void mx2_videobuf_queue(struct videobuf_queue *vq,
        list_add_tail(&vb->queue, &pcdev->capture);
 
        if (mx27_camera_emma(pcdev)) {
+               if (prp->cfg.channel == 1) {
+                       writel(PRP_CNTL_CH1EN |
+                               PRP_CNTL_CSIEN |
+                               prp->cfg.in_fmt |
+                               prp->cfg.out_fmt |
+                               PRP_CNTL_CH1_LEN |
+                               PRP_CNTL_CH1BYP |
+                               PRP_CNTL_CH1_TSKIP(0) |
+                               PRP_CNTL_IN_TSKIP(0),
+                               pcdev->base_emma + PRP_CNTL);
+               } else {
+                       writel(PRP_CNTL_CH2EN |
+                               PRP_CNTL_CSIEN |
+                               prp->cfg.in_fmt |
+                               prp->cfg.out_fmt |
+                               PRP_CNTL_CH2_LEN |
+                               PRP_CNTL_CH2_TSKIP(0) |
+                               PRP_CNTL_IN_TSKIP(0),
+                               pcdev->base_emma + PRP_CNTL);
+               }
                goto out;
        } else { /* cpu_is_mx25() */
                u32 csicr3, dma_inten = 0;
@@ -747,16 +770,6 @@ static void mx27_camera_emma_buf_init(struct 
soc_camera_device *icd,
                writel(pcdev->discard_buffer_dma,
                                pcdev->base_emma + PRP_DEST_RGB2_PTR);
 
-               writel(PRP_CNTL_CH1EN |
-                               PRP_CNTL_CSIEN |
-                               prp->cfg.in_fmt |
-                               prp->cfg.out_fmt |
-                               PRP_CNTL_CH1_LEN |
-                               PRP_CNTL_CH1BYP |
-                               PRP_CNTL_CH1_TSKIP(0) |
-                               PRP_CNTL_IN_TSKIP(0),
-                               pcdev->base_emma + PRP_CNTL);
-
                writel((icd->user_width << 16) | icd->user_height,
                        pcdev->base_emma + PRP_SRC_FRAME_SIZE);
                writel((icd->user_width << 16) | icd->user_height,
@@ -784,15 +797,6 @@ static void mx27_camera_emma_buf_init(struct 
soc_camera_device *icd,
                                pcdev->base_emma + PRP_SOURCE_CR_PTR);
                }
 
-               writel(PRP_CNTL_CH2EN |
-                       PRP_CNTL_CSIEN |
-                       prp->cfg.in_fmt |
-                       prp->cfg.out_fmt |
-                       PRP_CNTL_CH2_LEN |
-                       PRP_CNTL_CH2_TSKIP(0) |
-                       PRP_CNTL_IN_TSKIP(0),
-                       pcdev->base_emma + PRP_CNTL);
-
                writel((icd->user_width << 16) | icd->user_height,
                        pcdev->base_emma + PRP_SRC_FRAME_SIZE);
 
@@ -1214,7 +1218,6 @@ static void mx27_camera_frame_done_emma(struct 
mx2_camera_dev *pcdev,
                vb->state = state;
                do_gettimeofday(&vb->ts);
                vb->field_count = pcdev->frame_count * 2;
-               pcdev->frame_count++;
 
                wake_up(&vb->done);
        }
@@ -1239,6 +1242,17 @@ static void mx27_camera_frame_done_emma(struct 
mx2_camera_dev *pcdev,
                return;
        }
 
+       /*
+        * According to V4L2 specification, first valid sequence number must
+        * be 0. However, by design the first received frame is written to the
+        * discard buffer even when a video buffer is available. For that reason
+        * we don't increment frame_count the first time.
+        */
+       if (pcdev->firstirq)
+               pcdev->firstirq = 0;
+       else
+               pcdev->frame_count++;
+
        buf = list_entry(pcdev->capture.next,
                        struct mx2_buffer, vb.queue);
 
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to