android: ion: add fdt handling for carveout_heap
authorCho KyongHo <pullip.cho@samsung.com>
Wed, 7 Feb 2018 11:36:08 +0000 (20:36 +0900)
committerSangwook Ju <sw.ju@samsung.com>
Mon, 14 May 2018 10:45:23 +0000 (19:45 +0900)
Carveout heap provides buffer management for a reserved pool of
physical memory which is carved out by an early allocator like
memblock. Current ION is lack of how to initialize carveout heap.
We have decided to define the reserved memory pool in
"reserved-memory" device tree node with "exynos9820-ion" compatible
string.
The node may have the following properties in addition to the properties
of the child nodes of "reserved-memory" node:
- ion,untouchable: the buffer from the heap should not creates a
              mapping in the kernel and userland.
- ion,heapname: The name of the heap.
- ion,alignment: The alignment of buffers from the heap.

Change-Id: I41cdc72078a88795c8d6aca6af2c40e910330894
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/staging/android/ion/Kconfig
drivers/staging/android/ion/Makefile
drivers/staging/android/ion/ion_exynos.h [new file with mode: 0644]
drivers/staging/android/ion/ion_fdt_exynos.c [new file with mode: 0644]

index c7957dce7f64128c94bdd6aff2e3841f5f71ba47..4aed58a9a7dec66f2abcac4a6df4729a40634f1a 100644 (file)
@@ -10,6 +10,13 @@ menuconfig ION
          If you're not using Android its probably safe to
          say N here.
 
+config ION_EXYNOS
+       bool "Exynos Extension to ION"
+       depends on ION
+       help
+         Choose this option for Exynos SoCs. Initialization of cma heap is
+         changed.
+
 config ION_TEST
        tristate "Ion Test Device"
        depends on ION
index 1a12b514ef1db42f3c3f805d4a55b859c4f059c6..7b46caaab30bd00aaa9df4b2ba4d30c73f4175f2 100644 (file)
@@ -5,3 +5,4 @@ obj-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o
 obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o
 obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o
 obj-$(CONFIG_ION_TEST) += ion_test.o
+obj-$(CONFIG_ION_EXYNOS) += ion_fdt_exynos.o
diff --git a/drivers/staging/android/ion/ion_exynos.h b/drivers/staging/android/ion/ion_exynos.h
new file mode 100644 (file)
index 0000000..d0c8571
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * drivers/staging/android/ion/ion_exynos.h
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ION_EXYNOS_H_
+#define _ION_EXYNOS_H_
+
+struct ion_heap;
+struct ion_platform_heap;
+
+#ifdef CONFIG_ION_CARVEOUT_HEAP
+extern struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *);
+#else
+#define ion_carveout_heap_create(p) ERR_PTR(-ENODEV)
+#endif
+
+#endif /* _ION_EXYNOS_H_ */
diff --git a/drivers/staging/android/ion/ion_fdt_exynos.c b/drivers/staging/android/ion/ion_fdt_exynos.c
new file mode 100644 (file)
index 0000000..65c25b3
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * drivers/staging/android/ion/ion_fdt_exynos.c
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ *
+ * 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/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+#include "ion.h"
+#include "ion_exynos.h"
+
+unsigned int reserved_mem_count __initdata;
+struct ion_reserved_mem_struct {
+       char            *heapname;
+       phys_addr_t     base;
+       phys_addr_t     size;
+       unsigned int    alloc_align;
+       bool            untouchable;
+} ion_reserved_mem[ION_NUM_HEAP_IDS - 1] __initdata;
+
+static int __init exynos_ion_reserved_mem_setup(struct reserved_mem *rmem)
+{
+       bool untch;
+       size_t alloc_align = PAGE_SIZE;
+       char *heapname;
+       const __be32 *prop;
+       int len;
+
+       untch = !!of_get_flat_dt_prop(rmem->fdt_node, "ion,untouchable", NULL);
+
+       prop = of_get_flat_dt_prop(rmem->fdt_node, "ion,alignment", &len);
+       if (prop && (be32_to_cpu(prop[0]) >= PAGE_SIZE)) {
+               alloc_align = be32_to_cpu(prop[0]);
+               if ((alloc_align & (alloc_align - 1)) != 0)
+                       alloc_align = 1 << (get_order(alloc_align) + PAGE_SHIFT);
+       }
+
+       prop = of_get_flat_dt_prop(rmem->fdt_node, "ion,heapname", &len);
+       if (!prop) {
+               pr_err("%s: 'ion,heapname' is missing in '%s' node\n",
+                      __func__, rmem->name);
+               return -EINVAL;
+       }
+       heapname = (char *)prop;
+
+       if (reserved_mem_count == ARRAY_SIZE(ion_reserved_mem)) {
+               pr_err("%s: Not enough reserved_mem slot for %s\n",
+                      __func__, rmem->name);
+               return -ENOMEM;
+       }
+
+       ion_reserved_mem[reserved_mem_count].base = rmem->base;
+       ion_reserved_mem[reserved_mem_count].size = rmem->size;
+       ion_reserved_mem[reserved_mem_count].heapname = heapname;
+       ion_reserved_mem[reserved_mem_count].alloc_align = alloc_align;
+       ion_reserved_mem[reserved_mem_count].untouchable = untch;
+       reserved_mem_count++;
+
+       return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(ion, "exynos9820-ion", exynos_ion_reserved_mem_setup);
+
+static int __init exynos_ion_register_heaps(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < reserved_mem_count; i++) {
+               struct ion_platform_heap pheap;
+               struct ion_heap *heap;
+
+               pheap.type        = ION_HEAP_TYPE_CARVEOUT;
+               pheap.name        = ion_reserved_mem[i].heapname;
+               pheap.base        = ion_reserved_mem[i].base;
+               pheap.size        = ion_reserved_mem[i].size;
+               pheap.align       = ion_reserved_mem[i].alloc_align;
+               pheap.untouchable = ion_reserved_mem[i].untouchable;
+
+               heap = ion_carveout_heap_create(&pheap);
+               if (IS_ERR(heap)) {
+                       pr_err("%s: failed to register '%s' heap\n",
+                              __func__, pheap.name);
+                       continue;
+               }
+
+               ion_device_add_heap(heap);
+               pr_info("ION: registered '%s' heap\n", pheap.name);
+       }
+
+       return 0;
+}
+device_initcall(exynos_ion_register_heaps);