]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
media: rcar-vin: allocate a scratch buffer at stream start
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Wed, 14 Mar 2018 02:49:09 +0000 (22:49 -0400)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Thu, 22 Mar 2018 10:22:39 +0000 (06:22 -0400)
Before starting a capture, allocate a scratch buffer which can be used
by the driver to give to the hardware if no buffers are available from
userspace. The buffer is not used in this patch but prepares for future
refactoring where the scratch buffer can be used to avoid the need to
fallback on single capture mode if userspace can't queue buffers as fast
as the VIN driver consumes them.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/rcar-vin/rcar-dma.c
drivers/media/platform/rcar-vin/rcar-vin.h

index 23fdff7a7370842e56716d9ef72717007c07e695..1f91b056188ebdb36935660b9192ae3d1393fe42 100644 (file)
@@ -1076,6 +1076,17 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
        unsigned long flags;
        int ret;
 
+       /* Allocate scratch buffer. */
+       vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
+                                         &vin->scratch_phys, GFP_KERNEL);
+       if (!vin->scratch) {
+               spin_lock_irqsave(&vin->qlock, flags);
+               return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
+               spin_unlock_irqrestore(&vin->qlock, flags);
+               vin_err(vin, "Failed to allocate scratch buffer\n");
+               return -ENOMEM;
+       }
+
        sd = vin_to_source(vin);
        v4l2_subdev_call(sd, video, s_stream, 1);
 
@@ -1091,6 +1102,10 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 
        spin_unlock_irqrestore(&vin->qlock, flags);
 
+       if (ret)
+               dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+                                 vin->scratch_phys);
+
        return ret;
 }
 
@@ -1141,6 +1156,10 @@ static void rvin_stop_streaming(struct vb2_queue *vq)
 
        /* disable interrupts */
        rvin_disable_interrupts(vin);
+
+       /* Free scratch buffer. */
+       dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+                         vin->scratch_phys);
 }
 
 static const struct vb2_ops rvin_qops = {
index 5382078143fb3869a0b0b742225f4f71d58f268e..00b405f78d0912c992aa9d342d162ab5e8d1e97c 100644 (file)
@@ -102,6 +102,8 @@ struct rvin_graph_entity {
  *
  * @lock:              protects @queue
  * @queue:             vb2 buffers queue
+ * @scratch:           cpu address for scratch buffer
+ * @scratch_phys:      physical address of the scratch buffer
  *
  * @qlock:             protects @queue_buf, @buf_list, @continuous, @sequence
  *                     @state
@@ -130,6 +132,8 @@ struct rvin_dev {
 
        struct mutex lock;
        struct vb2_queue queue;
+       void *scratch;
+       dma_addr_t scratch_phys;
 
        spinlock_t qlock;
        struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];