ion_dev: add codec_mm heap for omx. [3/3]
authorjintao xu <jintao.xu@amlogic.com>
Thu, 19 Oct 2017 08:32:29 +0000 (16:32 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 23 Oct 2017 04:09:46 +0000 (21:09 -0700)
PD#152137: add codec_mm heap for omx
           codec_mm_cma 308M;
           ion_dev_dma 92M;

Change-Id: I804d16c19e6133ec41bd51a7b2c328339a8d0fd7
Signed-off-by: jintao xu <jintao.xu@amlogic.com>
14 files changed:
MAINTAINERS
arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts
arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts
arch/arm64/boot/dts/amlogic/gxl_skt.dts
arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts
arch/arm64/boot/dts/amlogic/gxm_skt.dts
drivers/amlogic/media/common/ion_dev/dev_ion.c
drivers/staging/android/ion/Makefile
drivers/staging/android/ion/ion_codec_mm_heap.c [new file with mode: 0644]
drivers/staging/android/ion/ion_heap.c
drivers/staging/android/ion/ion_priv.h

index 99caf2a..84c35ce 100644 (file)
@@ -14092,3 +14092,7 @@ F: scripts/amlogic/configs/meson64_audio_defconfig
 AMLOGIC gpio key wakeup function
 M: Hong Guo <hong.guo@amlogic.com>
 F: drivers/amlogic/input/keyboard/*
+
+AMLOGIC ION_DEV ADD CODEC_MM
+M: JinTao Xu <jintao.xu@amlogic.com>
+F: drivers/staging/android/ion/ion_codec_mm_heap.c
\ No newline at end of file
index 969fb74..1cee44d 100644 (file)
@@ -88,7 +88,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x8000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index d246013..02b0a61 100644 (file)
@@ -97,7 +97,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x8000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index ab38487..92b7a1a 100644 (file)
@@ -89,7 +89,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x8000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index 047e032..773718c 100644 (file)
@@ -89,7 +89,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x7000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index e8b4b75..5bf32dc 100644 (file)
@@ -89,7 +89,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x7000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index eeb57bb..518ec8d 100644 (file)
@@ -88,7 +88,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x7000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index acb2cdd..02ac8e2 100644 (file)
@@ -88,7 +88,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x7000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x11400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index c955ddb..e81b923 100644 (file)
@@ -88,7 +88,7 @@
                ion_reserved:linux,ion-dev {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x7000000>;
+                       size = <0x0 0x5C00000>;
                        alignment = <0x0 0x400000>;
                };
 
                codec_mm_cma:linux,codec_mm_cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0x10400000>;
+                       /* ion_codec_mm max can alloc size 80M*/
+                       size = <0x0 0x13400000>;
                        alignment = <0x0 0x400000>;
                        linux,contiguous-region;
                };
index 595dd54..8a5e706 100644 (file)
@@ -189,14 +189,14 @@ int dev_ion_probe(struct platform_device *pdev)
        my_ion_heap[num_heaps].name = "vmalloc_ion";
        num_heaps++;
 
-#ifdef CONFIG_AMLOGIC_ION_CODEC_MM
        my_ion_heap[num_heaps].type = ION_HEAP_TYPE_CUSTOM;
        my_ion_heap[num_heaps].id = ION_HEAP_TYPE_CUSTOM;
        my_ion_heap[num_heaps].name = "codec_mm_ion";
        my_ion_heap[num_heaps].base = (ion_phys_addr_t) NULL;
-       my_ion_heap[num_heaps].size = 32 * 1024 * 1024;
+       /* limit the maximum alloc total size 80M */
+       my_ion_heap[num_heaps].size = 80 * 1024 * 1024;
        num_heaps++;
-#endif
+
        /*add CMA ion heap*/
        my_ion_heap[num_heaps].type = ION_HEAP_TYPE_DMA;
        my_ion_heap[num_heaps].id = ION_HEAP_TYPE_DMA;
index 5d630a0..9fc3120 100644 (file)
@@ -1,6 +1,6 @@
 obj-$(CONFIG_ION) +=   ion.o ion-ioctl.o ion_heap.o \
                        ion_page_pool.o ion_system_heap.o \
-                       ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o
+                       ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o ion_codec_mm_heap.o
 obj-$(CONFIG_ION_TEST) += ion_test.o
 ifdef CONFIG_COMPAT
 obj-$(CONFIG_ION) += compat_ion.o
diff --git a/drivers/staging/android/ion/ion_codec_mm_heap.c b/drivers/staging/android/ion/ion_codec_mm_heap.c
new file mode 100644 (file)
index 0000000..074992f
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * drivers/staging/android/ion/ion_codec_mm_heap.c
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include "ion.h"
+#include "ion_priv.h"
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+
+struct ion_codec_mm_heap {
+       struct ion_heap heap;
+       int max_can_alloc_size;
+       int alloced_size;
+};
+
+#define CODEC_MM_ION "ION"
+
+ion_phys_addr_t ion_codec_mm_allocate(struct ion_heap *heap,
+                                     unsigned long size,
+                                     unsigned long align)
+{
+       struct ion_codec_mm_heap *codec_heap =
+               container_of(heap, struct ion_codec_mm_heap, heap);
+       unsigned long offset;
+
+       if (codec_heap->alloced_size + size > codec_heap->max_can_alloc_size) {
+               pr_err(
+                       "ion_codec_mm_allocate failed out size %ld,alloced %d\n",
+                       size,
+                       codec_heap->alloced_size);
+               return ION_CODEC_MM_ALLOCATE_FAIL;
+       }
+
+       offset = codec_mm_alloc_for_dma(
+               CODEC_MM_ION,
+               size / PAGE_SIZE,
+               0,
+               CODEC_MM_FLAGS_DMA_CPU);
+
+       if (!offset) {
+               pr_err("ion_codec_mm_allocate failed out size %d\n", (int)size);
+               return ION_CODEC_MM_ALLOCATE_FAIL;
+       }
+       codec_heap->alloced_size += size;
+       return offset;
+}
+
+void ion_codec_mm_free(struct ion_heap *heap, ion_phys_addr_t addr,
+                      unsigned long size)
+{
+       struct ion_codec_mm_heap *codec_heap =
+               container_of(heap, struct ion_codec_mm_heap, heap);
+
+       if (addr == ION_CODEC_MM_ALLOCATE_FAIL)
+               return;
+       codec_mm_free_for_dma(CODEC_MM_ION, addr);
+       codec_heap->alloced_size -= size;
+}
+
+static int ion_codec_mm_heap_allocate(struct ion_heap *heap,
+                                     struct ion_buffer *buffer,
+                                     unsigned long size, unsigned long align,
+                                     unsigned long flags)
+{
+       struct sg_table *table;
+       ion_phys_addr_t paddr;
+       int ret;
+
+       if (align > PAGE_SIZE)
+               return -EINVAL;
+
+       table = kzalloc(sizeof(*table), GFP_KERNEL);
+       if (!table)
+               return -ENOMEM;
+       ret = sg_alloc_table(table, 1, GFP_KERNEL);
+       if (ret)
+               goto err_free;
+
+       paddr = ion_codec_mm_allocate(heap, size, align);
+       if (paddr == ION_CODEC_MM_ALLOCATE_FAIL) {
+               ret = -ENOMEM;
+               goto err_free_table;
+       }
+
+       sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), size, 0);
+       buffer->priv_virt = table;
+       buffer->sg_table = table;
+
+       return 0;
+
+err_free_table:
+       sg_free_table(table);
+err_free:
+       kfree(table);
+       return ret;
+}
+
+static void ion_codec_mm_heap_free(struct ion_buffer *buffer)
+{
+       struct ion_heap *heap = buffer->heap;
+       struct sg_table *table = buffer->priv_virt;
+       struct page *page = sg_page(table->sgl);
+       ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
+
+       ion_heap_buffer_zero(buffer);
+
+       if (ion_buffer_cached(buffer))
+               dma_sync_sg_for_device(
+                       NULL,
+                       table->sgl,
+                       table->nents,
+                       DMA_BIDIRECTIONAL);
+
+       ion_codec_mm_free(heap, paddr, buffer->size);
+       sg_free_table(table);
+       kfree(table);
+}
+
+static struct ion_heap_ops codec_mm_heap_ops = {
+       .allocate = ion_codec_mm_heap_allocate,
+       .free = ion_codec_mm_heap_free,
+       .map_user = ion_heap_map_user,
+       .map_kernel = ion_heap_map_kernel,
+       .unmap_kernel = ion_heap_unmap_kernel,
+};
+
+struct ion_heap *ion_codec_mm_heap_create(struct ion_platform_heap *heap_data)
+{
+       struct ion_codec_mm_heap *codec_heap;
+       /* int ret; */
+       codec_heap = kzalloc(sizeof(*codec_heap), GFP_KERNEL);
+       if (!codec_heap)
+               return ERR_PTR(-ENOMEM);
+
+       codec_heap->max_can_alloc_size = heap_data->size;
+       codec_heap->alloced_size = 0;
+       codec_heap->heap.ops = &codec_mm_heap_ops;
+       codec_heap->heap.type = ION_HEAP_TYPE_CUSTOM;
+       codec_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
+       return &codec_heap->heap;
+}
+
+void ion_codec_mm_heap_destroy(struct ion_heap *heap)
+{
+       struct ion_codec_mm_heap *codec_heap =
+            container_of(heap, struct  ion_codec_mm_heap, heap);
+
+       kfree(codec_heap);
+       codec_heap = NULL;
+}
index 4e5c0f1..908b2f1 100644 (file)
@@ -335,6 +335,9 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
        case ION_HEAP_TYPE_DMA:
                heap = ion_cma_heap_create(heap_data);
                break;
+       case ION_HEAP_TYPE_CUSTOM:
+               heap = ion_codec_mm_heap_create(heap_data);
+               break;
        default:
                pr_err("%s: Invalid heap type %d\n", __func__,
                       heap_data->type);
@@ -375,6 +378,9 @@ void ion_heap_destroy(struct ion_heap *heap)
        case ION_HEAP_TYPE_DMA:
                ion_cma_heap_destroy(heap);
                break;
+       case ION_HEAP_TYPE_CUSTOM:
+               ion_codec_mm_heap_destroy(heap);
+               break;
        default:
                pr_err("%s: Invalid heap type %d\n", __func__,
                       heap->type);
index 3c3b324..0dd8781 100644 (file)
@@ -388,6 +388,19 @@ struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
 void ion_cma_heap_destroy(struct ion_heap *);
 
 /**
+ * The codec_mm heap returns physical addresses, since 0 may be a valid
+ * physical address, this is used to indicate allocation failed
+ */
+#define ION_CODEC_MM_ALLOCATE_FAIL -1
+
+/*
+ * Amlogic:
+ * Alloc from codec_mm support
+ */
+struct ion_heap *ion_codec_mm_heap_create(struct ion_platform_heap *heap_data);
+void ion_codec_mm_heap_destroy(struct ion_heap *heap);
+
+/**
  * functions for creating and destroying a heap pool -- allows you
  * to keep a pool of pre allocated memory to use from your heap.  Keeping
  * a pool of memory that is ready for dma, ie any cached mapping have been