From f5a876c48039b58ac40cdbe66619db353f178b93 Mon Sep 17 00:00:00 2001 From: CMY Date: Fri, 10 Oct 2014 15:07:17 +0800 Subject: [PATCH] rk: ion: finished ION memory reserve more gracefully --- arch/arm/boot/dts/rk3036.dtsi | 3 +- arch/arm/boot/dts/rk312x.dtsi | 3 +- arch/arm/boot/dts/rk3288-fpga.dts | 13 +- arch/arm/boot/dts/rk3288.dtsi | 3 +- arch/arm/mach-rockchip/common.c | 7 +- drivers/staging/android/ion/ion.c | 18 ++- .../android/ion/rockchip/rockchip_ion.c | 141 ++++-------------- 7 files changed, 67 insertions(+), 121 deletions(-) diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index aae2e657041a..c035f206edf8 100755 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -637,11 +637,12 @@ #size-cells = <0>; ion_cma: rockchip,ion-heap@1 { /* CMA HEAP */ - compatible = "rockchip,ion-reserve"; + compatible = "rockchip,ion-heap"; rockchip,ion_heap = <1>; reg = <0x00000000 0x00000000>; /* 0MB */ }; rockchip,ion-heap@3 { /* VMALLOC HEAP */ + compatible = "rockchip,ion-heap"; rockchip,ion_heap = <3>; }; }; diff --git a/arch/arm/boot/dts/rk312x.dtsi b/arch/arm/boot/dts/rk312x.dtsi index 378761b4b720..cdff07885d4f 100755 --- a/arch/arm/boot/dts/rk312x.dtsi +++ b/arch/arm/boot/dts/rk312x.dtsi @@ -918,11 +918,12 @@ #size-cells = <0>; ion_cma: rockchip,ion-heap@1 { /* CMA HEAP */ - compatible = "rockchip,ion-reserve"; + compatible = "rockchip,ion-heap"; rockchip,ion_heap = <1>; reg = <0x00000000 0x800000>; /* 8MB */ }; rockchip,ion-heap@3 { /* VMALLOC HEAP */ + compatible = "rockchip,ion-heap"; rockchip,ion_heap = <3>; }; }; diff --git a/arch/arm/boot/dts/rk3288-fpga.dts b/arch/arm/boot/dts/rk3288-fpga.dts index 9bc5586386ce..bca81c030d9a 100755 --- a/arch/arm/boot/dts/rk3288-fpga.dts +++ b/arch/arm/boot/dts/rk3288-fpga.dts @@ -265,13 +265,14 @@ compatible = "rockchip,ion"; #address-cells = <1>; #size-cells = <0>; - rockchip,ion-heap@1 { /* CMA HEAP */ - compatible = "rockchip,ion-reserve"; - reg = <1>; - memory-reservation = <0x00000000 0x04000000>; /* 64MB */ + ion_cma: rockchip,ion-heap@1 { /* CMA HEAP */ + compatible = "rockchip,ion-heap"; + rockchip,ion_heap = <1>; + reg = <0x00000000 0x04000000>; /* 64MB */ }; - rockchip,ion-heap@3 { /* SYSTEM HEAP */ - reg = <3>; + rockchip,ion-heap@3 { /* VMALLOC HEAP */ + compatible = "rockchip,ion-heap"; + rockchip,ion_heap = <3>; }; }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 29c20c0accfe..2bc7971ea148 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -992,11 +992,12 @@ #size-cells = <0>; ion_cma: rockchip,ion-heap@1 { /* CMA HEAP */ - compatible = "rockchip,ion-reserve"; + compatible = "rockchip,ion-heap"; rockchip,ion_heap = <1>; reg = <0x00000000 0x20000000>; /* 512MB */ }; rockchip,ion-heap@3 { /* VMALLOC HEAP */ + compatible = "rockchip,ion-heap"; rockchip,ion_heap = <3>; }; }; diff --git a/arch/arm/mach-rockchip/common.c b/arch/arm/mach-rockchip/common.c index 5a34f4be0e64..9ee976af9b7e 100755 --- a/arch/arm/mach-rockchip/common.c +++ b/arch/arm/mach-rockchip/common.c @@ -273,13 +273,16 @@ int (*ddr_change_freq)(uint32_t nMHz) = NULL; long (*ddr_round_rate)(uint32_t nMHz) = NULL; void (*ddr_set_auto_self_refresh)(bool en) = NULL; -extern int __init rockchip_ion_find_reserve_mem(unsigned long node, +extern struct ion_platform_data ion_pdata; +extern void __init ion_reserve(struct ion_platform_data *data); +extern int __init rockchip_ion_find_heap(unsigned long node, const char *uname, int depth, void *data); void __init rockchip_ion_reserve(void) { #ifdef CONFIG_ION_ROCKCHIP printk("%s\n", __func__); - of_scan_flat_dt(rockchip_ion_find_reserve_mem, NULL); + of_scan_flat_dt(rockchip_ion_find_heap, (void*)&ion_pdata); + ion_reserve(&ion_pdata); #endif } diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index cc036a43e0ea..99030be56d1b 100755 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -2022,7 +2022,19 @@ void __init ion_reserve(struct ion_platform_data *data) if (data->heaps[i].size == 0) continue; - if (data->heaps[i].base == 0) { + if (data->heaps[i].id==ION_CMA_HEAP_ID) { + struct device *dev = (struct device*)data->heaps[i].priv; + int ret = dma_declare_contiguous(dev, + data->heaps[i].size, + data->heaps[i].base, + MEMBLOCK_ALLOC_ANYWHERE); + if (ret) { + pr_err("%s: dma_declare_contiguous failed %d\n", + __func__, ret); + continue; + }; + data->heaps[i].base = PFN_PHYS(dev_get_cma_area(dev)->base_pfn); + } else if (data->heaps[i].base == 0) { phys_addr_t paddr; paddr = memblock_alloc_base(data->heaps[i].size, data->heaps[i].align, @@ -2037,10 +2049,12 @@ void __init ion_reserve(struct ion_platform_data *data) } else { int ret = memblock_reserve(data->heaps[i].base, data->heaps[i].size); - if (ret) + if (ret) { pr_err("memblock reserve of %zx@%lx failed\n", data->heaps[i].size, data->heaps[i].base); + continue; + } } pr_info("%s: %s reserved base %lx size %zu\n", __func__, data->heaps[i].name, diff --git a/drivers/staging/android/ion/rockchip/rockchip_ion.c b/drivers/staging/android/ion/rockchip/rockchip_ion.c index 113dfea29e36..28cc13246b7f 100755 --- a/drivers/staging/android/ion/rockchip/rockchip_ion.c +++ b/drivers/staging/android/ion/rockchip/rockchip_ion.c @@ -45,20 +45,27 @@ extern struct ion_handle *ion_handle_get_by_id(struct ion_client *client, int id); extern int ion_handle_put(struct ion_handle *handle); +#define MAX_ION_HEAP 10 +static struct ion_platform_heap ion_plat_heap[MAX_ION_HEAP]; +struct ion_platform_data ion_pdata = { + .nr = 0, + .heaps = ion_plat_heap, +}; + static struct ion_heap_desc ion_heap_meta[] = { { - .id = ION_VMALLOC_HEAP_ID, + .id = ION_VMALLOC_HEAP_ID, .type = ION_HEAP_TYPE_SYSTEM, .name = ION_VMALLOC_HEAP_NAME, }, { - .id = ION_CMA_HEAP_ID, + .id = ION_CMA_HEAP_ID, .type = ION_HEAP_TYPE_DMA, .name = ION_CMA_HEAP_NAME, }, { - .id = ION_IOMMU_HEAP_ID, - .type = ION_HEAP_TYPE_DMA,//ION_HEAP_TYPE_IOMMU, + .id = ION_IOMMU_HEAP_ID, + .type = ION_HEAP_TYPE_DMA, .name = ION_IOMMU_HEAP_NAME, }, { @@ -98,80 +105,6 @@ static int rockchip_ion_populate_heap(struct ion_platform_heap *heap) return ret; } -static int rockchip_ion_get_heap_base_size(struct device_node *node, - struct ion_platform_heap *heap) -{ - unsigned int val[2]; - int ret = 0; - - ret = of_property_read_u32_array(node, - "reg", val, 2); - if (!ret) { - heap->base = val[0]; - heap->size = val[1]; - } - - pr_debug("heap: %x@%lx\n", heap->size, heap->base); - - return 0; -} - -static struct ion_platform_data *rockchip_ion_parse_dt( - struct device *dev) -{ - struct device_node *dt_node = dev->of_node; - struct ion_platform_data *pdata = 0; - struct device_node *node; - uint32_t val = 0; - int ret = 0; - uint32_t num_heaps = 0; - int idx = 0; - - for_each_child_of_node(dt_node, node) - num_heaps++; - - pr_info("%s: num_heaps = %d\n", __func__, num_heaps); - - if (!num_heaps) - return ERR_PTR(-EINVAL); - - pdata = kzalloc(sizeof(struct ion_platform_data) + - num_heaps*sizeof(struct ion_platform_heap), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - pdata->heaps = (struct ion_platform_heap*)((void*)pdata+sizeof(struct ion_platform_data)); - pdata->nr = num_heaps; - - for_each_child_of_node(dt_node, node) { - ret = of_property_read_u32(node, "rockchip,ion_heap", &val); - if (ret) { - pr_err("%s: Unable to find reg key", __func__); - goto free_heaps; - } - pdata->heaps[idx].id = val; - - ret = rockchip_ion_populate_heap(&pdata->heaps[idx]); - if (ret) - goto free_heaps; - -// rockchip_ion_get_heap_align(node, &pdata->heaps[idx]); - ret = rockchip_ion_get_heap_base_size(node, &pdata->heaps[idx]); - if (ret) - goto free_heaps; - -// rockchip_ion_get_heap_adjacent(node, &pdata->heaps[idx]); - pr_info("%d: %d %d %s 0x%p\n", idx, pdata->heaps[idx].type, pdata->heaps[idx].id, pdata->heaps[idx].name, pdata->heaps[idx].priv); - - ++idx; - } - - return pdata; - -free_heaps: - kfree(pdata); - return ERR_PTR(ret); -} - struct ion_client *rockchip_ion_client_create(const char *name) { return ion_client_create(idev, name); @@ -262,7 +195,6 @@ static long rockchip_custom_ioctl (struct ion_client *client, unsigned int cmd, static int rockchip_ion_probe(struct platform_device *pdev) { struct ion_platform_data *pdata; - unsigned int pdata_needs_to_be_freed; int err; int i; @@ -273,14 +205,12 @@ static int rockchip_ion_probe(struct platform_device *pdev) } if (pdev->dev.of_node) { - pdata = rockchip_ion_parse_dt(&pdev->dev); + pdata = &ion_pdata; if (IS_ERR(pdata)) { return PTR_ERR(pdata); } - pdata_needs_to_be_freed = 1; } else { pdata = pdev->dev.platform_data; - pdata_needs_to_be_freed = 0; } num_heaps = pdata->nr; @@ -303,8 +233,6 @@ static int rockchip_ion_probe(struct platform_device *pdev) ion_device_add_heap(idev, heaps[i]); } platform_set_drvdata(pdev, idev); - if (pdata_needs_to_be_freed) - kfree(pdata); pr_info("Rockchip ion module is successfully loaded (%s)\n", ROCKCHIP_ION_VERSION); return 0; @@ -313,8 +241,6 @@ err: if (heaps[i]) ion_heap_destroy(heaps[i]); } - if (pdata_needs_to_be_freed) - kfree(pdata); kfree(heaps); return err; } @@ -331,43 +257,42 @@ static int rockchip_ion_remove(struct platform_device *pdev) return 0; } -int __init rockchip_ion_find_reserve_mem(unsigned long node, const char *uname, +int __init rockchip_ion_find_heap(unsigned long node, const char *uname, int depth, void *data) { -#ifdef CONFIG_CMA const __be32 *prop; int len; - phys_addr_t size; - phys_addr_t base; - u32 heap_type; + struct ion_platform_heap* heap; + struct ion_platform_data* pdata = (struct ion_platform_data*)data; - if (!of_flat_dt_is_compatible(node, "rockchip,ion-reserve")) - return 0; + if (pdata==NULL || pdata->nr >= MAX_ION_HEAP) { + // break now + pr_err("ion heap is too much!\n"); + return 1; + } - prop = of_get_flat_dt_prop(node, "reg", &len); - if (!prop || (len != 2 * sizeof(unsigned long))) + if (!of_flat_dt_is_compatible(node, "rockchip,ion-heap")) return 0; - base = be32_to_cpu(prop[0]); - size = be32_to_cpu(prop[1]); - prop = of_get_flat_dt_prop(node, "rockchip,ion_heap", &len); if (!prop || (len != sizeof(unsigned long))) return 0; - heap_type = be32_to_cpu(prop[0]); - - pr_info("%s: heap type is %x\n", __func__, heap_type); + heap = &pdata->heaps[pdata->nr++]; + heap->base = heap->size = heap->align = 0; + heap->id = be32_to_cpu(prop[0]); + rockchip_ion_populate_heap(heap); - if (heap_type==ION_CARVEOUT_HEAP_ID) { - pr_info("%s: reserve carveout memory: %x@%x\n", __func__, size, base); - memblock_remove(base, size); - } else { - pr_info("%s: reserve cma memory: %x@%x\n", __func__, size, base); - dma_declare_contiguous(&rockchip_ion_cma_dev, size, base, 0); + prop = of_get_flat_dt_prop(node, "reg", &len); + if (prop && (len >= 2*sizeof(unsigned long))) { + heap->base = be32_to_cpu(prop[0]); + heap->size = be32_to_cpu(prop[1]); + if (len==3*sizeof(unsigned long)) + heap->align = be32_to_cpu(prop[2]); } -#endif + pr_info("ion heap(%s): base(%lx) size(%x) align(%lx)\n", heap->name, + heap->base, heap->size, heap->align); return 0; } -- 2.34.1