[RAMEN9610-12270] videobuf2: sync the buffer with as much as payload
authorhyesoo.yu <hyesoo.yu@samsung.com>
Fri, 31 Aug 2018 01:19:55 +0000 (10:19 +0900)
committerhskang <hs1218.kang@samsung.com>
Wed, 20 Feb 2019 01:00:33 +0000 (10:00 +0900)
Change-Id: Ibda4b01e19a26e3ad771ee45bfa688ec394c55fe
Signed-off-by: hyesoo.yu <hyesoo.yu@samsung.com>
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-dma-sg.c
include/media/videobuf2-core.h

index 9d3c358b63e261411b80abef48664849820e9d9f..13e276e69c505af0cd26543850ab1f32f0eefdb2 100644 (file)
@@ -270,7 +270,8 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p)
                return;
 
        if (p->dbuf_mapped)
-               call_void_memop(vb, unmap_dmabuf, p->mem_priv);
+               call_void_memop(vb, unmap_dmabuf,
+                               p->mem_priv, 0);
 
        call_void_memop(vb, detach_dmabuf, p->mem_priv);
        dma_buf_put(p->dbuf);
@@ -913,7 +914,8 @@ static void vb2_process_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state
            state != VB2_BUF_STATE_REQUEUEING) {
                /* sync buffers */
                for (plane = 0; plane < vb->num_planes; ++plane)
-                       call_void_memop(vb, finish, vb->planes[plane].mem_priv);
+                       call_void_memop(vb, finish, vb->planes[plane].mem_priv,
+                                       vb->planes[plane].bytesused);
        }
 
        spin_lock_irqsave(&q->done_lock, flags);
@@ -1202,7 +1204,9 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
         * userspace knows sooner rather than later if the dma-buf map fails.
         */
        for (plane = 0; plane < vb->num_planes; ++plane) {
-               ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
+               ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv,
+                                planes[plane].bytesused);
+
                if (ret) {
                        dprintk(1, "failed to map dmabuf for plane %d\n",
                                plane);
@@ -1308,7 +1312,8 @@ static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
 
        /* sync buffers */
        for (plane = 0; plane < vb->num_planes; ++plane)
-               call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
+               call_void_memop(vb, prepare, vb->planes[plane].mem_priv,
+                               vb->planes[plane].bytesused);
 
        vb->state = VB2_BUF_STATE_PREPARED;
 
@@ -1791,7 +1796,11 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
                for (i = 0; i < vb->num_planes; ++i) {
                        if (!vb->planes[i].dbuf_mapped)
                                continue;
-                       call_void_memop(vb, unmap_dmabuf, vb->planes[i].mem_priv);
+
+                       call_void_memop(vb, unmap_dmabuf,
+                                       vb->planes[i].mem_priv,
+                                       vb->planes[i].bytesused);
+
                        vb->planes[i].dbuf_mapped = 0;
                }
 }
@@ -1923,7 +1932,8 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
 
                        for (plane = 0; plane < vb->num_planes; ++plane)
                                call_void_memop(vb, finish,
-                                               vb->planes[plane].mem_priv);
+                                               vb->planes[plane].mem_priv,
+                                               0);
                }
 
                if (vb->state != VB2_BUF_STATE_DEQUEUED) {
index bc5caa58a307ac6b5275e28cfa91f72784ffdd03..ed5c5937308e3ee682d69755e3ea12e425cad1d9 100644 (file)
@@ -201,29 +201,58 @@ static void vb2_dma_sg_put(void *buf_priv)
        }
 }
 
-static void vb2_dma_sg_prepare(void *buf_priv)
+static void vb2_dma_sg_prepare(void *buf_priv, size_t size)
 {
        struct vb2_dma_sg_buf *buf = buf_priv;
        struct sg_table *sgt = buf->dma_sgt;
+       struct scatterlist *sg;
+       int i;
 
        /* DMABUF exporter will flush the cache for us */
        if (buf->db_attach)
                return;
 
-       dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
-                              buf->dma_dir);
+       if (size == 0)
+               size = buf->size;
+
+       for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+               size_t sg_len = min_t(size_t, size, sg->length);
+
+               dma_sync_single_for_device(buf->dev, sg->dma_address,
+                                          sg_len, buf->dma_dir);
+
+               size -= sg_len;
+
+               if (!size)
+                       break;
+       }
 }
 
-static void vb2_dma_sg_finish(void *buf_priv)
+static void vb2_dma_sg_finish(void *buf_priv, size_t size)
 {
        struct vb2_dma_sg_buf *buf = buf_priv;
        struct sg_table *sgt = buf->dma_sgt;
+       struct scatterlist *sg;
+       int i;
 
        /* DMABUF exporter will flush the cache for us */
        if (buf->db_attach)
                return;
 
-       dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+       if (size == 0)
+               size = buf->size;
+
+       for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+               size_t sg_len = min_t(size_t, size, sg->length);
+
+               dma_sync_single_for_cpu(buf->dev, sg->dma_address,
+                                       sg_len, buf->dma_dir);
+
+               size -= sg_len;
+
+               if (!size)
+                       break;
+       }
 }
 
 static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
@@ -556,7 +585,7 @@ static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags
 /*       callbacks for DMABUF buffers        */
 /*********************************************/
 
-static int vb2_dma_sg_map_dmabuf(void *mem_priv)
+static int vb2_dma_sg_map_dmabuf(void *mem_priv, size_t size)
 {
        struct vb2_dma_sg_buf *buf = mem_priv;
        struct sg_table *sgt;
@@ -573,7 +602,11 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv)
        }
 
        /* get the associated scatterlist for this buffer */
-       sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+       sgt = (size == 0) ?
+               dma_buf_map_attachment(buf->db_attach, buf->dma_dir) :
+               dma_buf_map_attachment_area(buf->db_attach,
+                                           buf->dma_dir, size);
+
        if (IS_ERR(sgt)) {
                pr_err("Error getting dmabuf scatterlist\n");
                return -EINVAL;
@@ -599,7 +632,7 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv)
        return 0;
 }
 
-static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
+static void vb2_dma_sg_unmap_dmabuf(void *mem_priv, size_t size)
 {
        struct vb2_dma_sg_buf *buf = mem_priv;
        struct sg_table *sgt = buf->dma_sgt;
@@ -618,7 +651,12 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
                dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
                buf->vaddr = NULL;
        }
-       dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+       if (size == 0)
+               dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+       else
+               dma_buf_unmap_attachment_area(buf->db_attach, sgt,
+                                             buf->dma_dir, size);
 
        buf->dma_sgt = NULL;
 }
@@ -629,7 +667,7 @@ static void vb2_dma_sg_detach_dmabuf(void *mem_priv)
 
        /* if vb2 works correctly you should never detach mapped buffer */
        if (WARN_ON(buf->dma_sgt))
-               vb2_dma_sg_unmap_dmabuf(buf);
+               vb2_dma_sg_unmap_dmabuf(buf, 0);
 
        ion_iovmm_unmap(buf->db_attach, buf->iova);
 
index 4ad5406a1d649de2474714142a3359aaf8e4b878..1107ae9bf39d57780e71c1a3c3308b2b3909c2ae 100644 (file)
@@ -126,16 +126,16 @@ struct vb2_mem_ops {
                                        enum dma_data_direction dma_dir);
        void            (*put_userptr)(void *buf_priv);
 
-       void            (*prepare)(void *buf_priv);
-       void            (*finish)(void *buf_priv);
+       void            (*prepare)(void *buf_priv, size_t size);
+       void            (*finish)(void *buf_priv, size_t size);
 
        void            *(*attach_dmabuf)(struct device *dev,
                                          struct dma_buf *dbuf,
                                          unsigned long size,
                                          enum dma_data_direction dma_dir);
        void            (*detach_dmabuf)(void *buf_priv);
-       int             (*map_dmabuf)(void *buf_priv);
-       void            (*unmap_dmabuf)(void *buf_priv);
+       int             (*map_dmabuf)(void *buf_priv, size_t size);
+       void            (*unmap_dmabuf)(void *buf_priv, size_t size);
 
        void            *(*vaddr)(void *buf_priv);
        void            *(*cookie)(void *buf_priv);