From f5c4d1ac8ecda20dac30b9ccb75942582a5b638c Mon Sep 17 00:00:00 2001 From: CMY Date: Thu, 26 Jun 2014 11:21:41 +0800 Subject: [PATCH] rk: ion: Add support cma heap placed in highmem zone Add CONFIG_ION_CMA_HIGHMEM to support cma that placed in highmem zone. Use dma_alloc_attrs() with DMA_ATTR_NO_KERNEL_MAPPING to alloc memory from cma heap that placed in highmem zone, and use dma_free_attrs() with DMA_ATTR_NO_KERNEL_MAPPING to free the memory. Use ion_heap_map_kernel/ion_heap_unmap_kernel for map/unmap to the kernel when support cma in highmem. --- drivers/staging/android/ion/Kconfig | 35 +++++++++++++--------- drivers/staging/android/ion/ion_cma_heap.c | 30 ++++++++++++++----- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 7af1035cf650..521aa75270d0 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -34,26 +34,33 @@ config ION_TEGRA Choose this option if you wish to use ion on an nVidia Tegra. config ION_ROCKCHIP - tristate "Ion for Rockchip" - depends on ARCH_ROCKCHIP && ION - select ARM_HAS_SG_CHAIN - help - Choose this option if you wish to use ion on an Rockchip. + tristate "Ion for Rockchip" + depends on ARCH_ROCKCHIP && ION + select ARM_HAS_SG_CHAIN + help + Choose this option if you wish to use ion on an Rockchip. if ION_ROCKCHIP +config ION_CMA_HIGHMEM + bool "CMA Support HighMem Zone" + depends on ION_ROCKCHIP && CMA + help + Choose this option to support CMA regions placed in highmem zone. + This will allocate memory from CMA regions without mapping. + config ION_ROCKCHIP_SNAPSHOT - bool "Snapshot for rockchip ion" - depends on ION_ROCKCHIP - help + bool "Snapshot for rockchip ion" + depends on ION_ROCKCHIP + help Provide ion snapshot for debug config ION_SNAPSHOT_BUF_SHIFT - int "ION snapshot buffer size (18 => 256KB, 19 => 512KB)" - depends on ION_ROCKCHIP_SNAPSHOT - range 12 21 - default 18 - help - Select ION snapshot buffer size as a power of 2 + int "ION snapshot buffer size (18 => 256KB, 19 => 512KB)" + depends on ION_ROCKCHIP_SNAPSHOT + range 12 21 + default 18 + help + Select ION snapshot buffer size as a power of 2 endif diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index e93afd0e7270..f6b8789312ed 100755 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -47,9 +47,9 @@ struct ion_cma_buffer_info { * as soon as it will avalaible. */ static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt, - void *cpu_addr, dma_addr_t handle, size_t size) + dma_addr_t handle, size_t size) { - struct page *page = virt_to_page(cpu_addr); + struct page *page = phys_to_page(handle); int ret; ret = sg_alloc_table(sgt, 1, GFP_KERNEL); @@ -68,7 +68,11 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, struct ion_cma_heap *cma_heap = to_cma_heap(heap); struct device *dev = cma_heap->dev; struct ion_cma_buffer_info *info; + DEFINE_DMA_ATTRS(attrs); +#ifdef CONFIG_ION_CMA_HIGHMEM + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); +#endif dev_dbg(dev, "Request buffer allocation len %ld\n", len); if (buffer->flags & ION_FLAG_CACHED) @@ -83,8 +87,8 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, return ION_CMA_ALLOCATE_FAILED; } - info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), - GFP_HIGHUSER | __GFP_ZERO); + info->cpu_addr = dma_alloc_attrs(dev, len, &(info->handle), + GFP_HIGHUSER | __GFP_ZERO, &attrs); if (!info->cpu_addr) { dev_err(dev, "Fail to allocate(%lx) buffer\n", len); @@ -97,8 +101,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, goto free_mem; } - if (ion_cma_get_sgtable - (dev, info->table, info->cpu_addr, info->handle, len)) + if (ion_cma_get_sgtable(dev, info->table, info->handle, len)) goto free_table; /* keep this for memory release */ buffer->priv_virt = info; @@ -108,7 +111,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, free_table: kfree(info->table); free_mem: - dma_free_coherent(dev, len, info->cpu_addr, info->handle); + dma_free_attrs(dev, len, info->cpu_addr, info->handle, &attrs); err: kfree(info); return ION_CMA_ALLOCATE_FAILED; @@ -119,10 +122,14 @@ static void ion_cma_free(struct ion_buffer *buffer) struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); struct device *dev = cma_heap->dev; struct ion_cma_buffer_info *info = buffer->priv_virt; + DEFINE_DMA_ATTRS(attrs); +#ifdef CONFIG_ION_CMA_HIGHMEM + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); +#endif dev_dbg(dev, "Release buffer %p\n", buffer); /* release memory */ - dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle); + dma_free_attrs(dev, buffer->size, info->cpu_addr, info->handle, &attrs); /* release sg table */ sg_free_table(info->table); kfree(info->table); @@ -171,6 +178,7 @@ static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer, buffer->size); } +#ifndef CONFIG_ION_CMA_HIGHMEM static void *ion_cma_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { @@ -183,6 +191,7 @@ static void ion_cma_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { } +#endif #ifdef CONFIG_ROCKCHIP_IOMMU // get device's vaddr @@ -226,8 +235,13 @@ static struct ion_heap_ops ion_cma_ops = { .unmap_dma = ion_cma_heap_unmap_dma, .phys = ion_cma_phys, .map_user = ion_cma_mmap, +#ifdef CONFIG_ION_CMA_HIGHMEM + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, +#else .map_kernel = ion_cma_map_kernel, .unmap_kernel = ion_cma_unmap_kernel, +#endif #ifdef CONFIG_ROCKCHIP_IOMMU .map_iommu = ion_cma_map_iommu, .unmap_iommu = ion_cma_unmap_iommu, -- 2.34.1