From dcbfe3bd8c9f09bd58a248ff2e60941937caa7f9 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Thu, 12 May 2022 15:02:17 +0800 Subject: [PATCH] dma-buf: cma_heap: support dmabuf partial sync Add partital sync support for begain/end of cpu access. Signed-off-by: Jianqun Xu Change-Id: I36cc7d2fffd1e22d796d429c76a990542acb8dd2 --- drivers/dma-buf/heaps/cma_heap.c | 46 +++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 90602a77086b..2c0ba561957c 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -132,8 +132,11 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, dma_unmap_sgtable(attachment->dev, table, direction, attrs); } -static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) +static int +cma_heap_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, + enum dma_data_direction direction, + unsigned int offset, + unsigned int len) { struct cma_heap_buffer *buffer = dmabuf->priv; struct dma_heap_attachment *a; @@ -150,13 +153,24 @@ static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, continue; dma_sync_sgtable_for_cpu(a->dev, &a->table, direction); } + if (list_empty(&buffer->attachments)) { + phys_addr_t phys = page_to_phys(buffer->cma_pages); + + dma_sync_single_for_cpu(dma_heap_get_dev(buffer->heap->heap), + phys + offset, + len, + direction); + } mutex_unlock(&buffer->lock); return 0; } -static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) +static int +cma_heap_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, + enum dma_data_direction direction, + unsigned int offset, + unsigned int len) { struct cma_heap_buffer *buffer = dmabuf->priv; struct dma_heap_attachment *a; @@ -173,11 +187,33 @@ static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, continue; dma_sync_sgtable_for_device(a->dev, &a->table, direction); } + if (list_empty(&buffer->attachments)) { + phys_addr_t phys = page_to_phys(buffer->cma_pages); + + dma_sync_single_for_device(dma_heap_get_dev(buffer->heap->heap), + phys + offset, + len, + direction); + } mutex_unlock(&buffer->lock); return 0; } +static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction dir) +{ + return cma_heap_dma_buf_begin_cpu_access_partial(dmabuf, dir, 0, + dmabuf->size); +} + +static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction dir) +{ + return cma_heap_dma_buf_end_cpu_access_partial(dmabuf, dir, 0, + dmabuf->size); +} + static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; @@ -287,6 +323,8 @@ static const struct dma_buf_ops cma_heap_buf_ops = { .unmap_dma_buf = cma_heap_unmap_dma_buf, .begin_cpu_access = cma_heap_dma_buf_begin_cpu_access, .end_cpu_access = cma_heap_dma_buf_end_cpu_access, + .begin_cpu_access_partial = cma_heap_dma_buf_begin_cpu_access_partial, + .end_cpu_access_partial = cma_heap_dma_buf_end_cpu_access_partial, .mmap = cma_heap_mmap, .vmap = cma_heap_vmap, .vunmap = cma_heap_vunmap,