From: hyesoo.yu Date: Fri, 31 Aug 2018 01:19:55 +0000 (+0900) Subject: [RAMEN9610-12270] videobuf2: sync the buffer with as much as payload X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=e7517593d560b9566020108d43f775c5bb3a8aec;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [RAMEN9610-12270] videobuf2: sync the buffer with as much as payload Change-Id: Ibda4b01e19a26e3ad771ee45bfa688ec394c55fe Signed-off-by: hyesoo.yu --- diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7f9797c4adae..a5e5f000e7bb 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -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; @@ -1796,7 +1801,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; } } @@ -1928,7 +1937,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) { diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index bc5caa58a307..ed5c5937308e 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -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); diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 4ad5406a1d64..1107ae9bf39d 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -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);