From: Cho KyongHo Date: Wed, 7 Feb 2018 11:36:08 +0000 (+0900) Subject: android: ion: add fdt handling for carveout_heap X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=f3f8b0077194f631c9396ccb40920a1fa8a29589;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git android: ion: add fdt handling for carveout_heap 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 --- diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index c7957dce7f64..4aed58a9a7de 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -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 diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile index 1a12b514ef1d..7b46caaab30b 100644 --- a/drivers/staging/android/ion/Makefile +++ b/drivers/staging/android/ion/Makefile @@ -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 index 000000000000..d0c8571a91c5 --- /dev/null +++ b/drivers/staging/android/ion/ion_exynos.h @@ -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 index 000000000000..65c25b3df9d8 --- /dev/null +++ b/drivers/staging/android/ion/ion_fdt_exynos.c @@ -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 +#include +#include + +#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);