uvm: copy the vframe to dma_buf one time [1/1]
authorAo Xu <ao.xu@amlogic.com>
Wed, 25 Dec 2019 04:13:24 +0000 (12:13 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 30 Dec 2019 07:57:22 +0000 (00:57 -0700)
PD#SWPL-19184

Problem:
1. When playing 4K video and pressing the power button,
it will stuck for more than 2s.
2. For some memory pressue condition, ion_alloc will
alloc fail for CMA memory.

Solution:
1. only do the data copy from vframe once.
2. change heap type to system heap for afbc video case.

Verify:
u212

Change-Id: I778541577004fa77e0917ca612a48745d92f2fb7
Signed-off-by: Ao Xu <ao.xu@amlogic.com>
drivers/amlogic/uvm/meson_uvm.c
drivers/amlogic/uvm/meson_uvm.h

index 3e5fe04259146d1cf9dd016e31cbf7e127ae13a2..d998882be4ec99bbd13674e1a582c416d4aac168 100644 (file)
@@ -48,15 +48,23 @@ static int meson_uvm_alloc_buffer(struct dma_buf *dmabuf)
        struct ion_handle *handle;
        phys_addr_t pat;
        size_t len;
+       struct vframe_s *vf;
+       enum ion_heap_type heap_type;
 
        struct uvm_buffer *buffer = dmabuf->priv;
 
        /* use ion_alloc to alloc the buffer */
        num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
+       vf = buffer->vf;
+
+       if ((vf->type & VIDTYPE_COMPRESS))
+               heap_type = ION_HEAP_TYPE_SYSTEM;
+       else
+               heap_type = ION_HEAP_TYPE_DMA;
 
        pr_debug("num_pages: %d.\n", num_pages);
        handle = ion_alloc(uvm_dev->uvm_client, buffer->size, 0,
-                                               (1 << ION_HEAP_TYPE_DMA), 0);
+                                               (1 << heap_type), 0);
        if (IS_ERR(handle)) {
                pr_err("%s: ion_alloc fail.\n", __func__);
                return -1;
@@ -163,7 +171,10 @@ static int meson_uvm_fill_pattern(struct dma_buf *dmabuf)
 
        pr_debug("the phy addr is %pa.\n", &val_data.phy_addr[0]);
 
-       v4lvideo_data_copy(&val_data);
+       if (!buffer->index || buffer->index != buffer->vf->omx_index) {
+               v4lvideo_data_copy(&val_data);
+               buffer->index = buffer->vf->omx_index;
+       }
 
        vunmap(buffer->vaddr);
        return 0;
@@ -200,8 +211,10 @@ static struct sg_table *meson_uvm_map_dma_buf(
 
        pr_debug("meson_uvm_map_dma_buf called, %s.\n", current->comm);
 
-       if (!buffer->handle)
-               meson_uvm_alloc_buffer(dmabuf);
+       if (!buffer->handle && meson_uvm_alloc_buffer(dmabuf)) {
+               pr_err("uvm_map_dma_buf fail.\n");
+               return ERR_PTR(-ENOMEM);
+       }
 
        meson_uvm_map_buffer(dmabuf);
        meson_uvm_fill_pattern(dmabuf);
index c65fc1b33e45996985e48263350858962684d941..7d191da6e7f5772c8fec88e1c826b25291b11b34 100644 (file)
@@ -54,6 +54,7 @@ struct uvm_buffer {
        struct dma_buf *dmabuf;
 
        struct vframe_s *vf;
+       u32 index;
 };
 
 struct uvm_device {