8960: Add support for using CMA with Ion heaps

Adjust the memory reservation/placing code in the board
file to account for heaps that might use CMA. This includes
both dedicated CMA heaps and cp heaps marked as using CMA.

Change-Id: Ifb715bc2d4bf7fbba78a7201a68ccf3ec93c38b2
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
This commit is contained in:
Laura Abbott 2012-08-03 17:32:09 -07:00 committed by Stephen Boyd
parent ff7c655e76
commit ca2ad08656

View file

@ -30,6 +30,7 @@
#include <linux/android_pmem.h>
#endif
#include <linux/cyttsp-qc.h>
#include <linux/dma-contiguous.h>
#include <linux/dma-mapping.h>
#include <linux/platform_data/qcom_crypto_device.h>
#include <linux/platform_data/qcom_wcnss_device.h>
@ -387,6 +388,17 @@ static struct ion_co_heap_pdata fw_co_msm8960_ion_pdata = {
};
#endif
static u64 msm_dmamask = DMA_BIT_MASK(32);
static struct platform_device ion_mm_heap_device = {
.name = "ion-mm-heap-device",
.id = -1,
.dev = {
.dma_mask = &msm_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
}
};
/**
* These heaps are listed in the order they will be allocated. Due to
* video hardware restrictions and content protection the FW heap has to
@ -412,6 +424,7 @@ struct ion_platform_heap msm8960_heaps[] = {
.size = MSM_ION_MM_SIZE,
.memory_type = ION_EBI_TYPE,
.extra_data = (void *) &cp_mm_msm8960_ion_pdata,
.priv = &ion_mm_heap_device.dev,
},
{
.id = ION_MM_FIRMWARE_HEAP_ID,
@ -548,21 +561,29 @@ static void __init reserve_ion_memory(void)
{
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
unsigned int i;
int ret;
unsigned int fixed_size = 0;
unsigned int fixed_low_size, fixed_middle_size, fixed_high_size;
unsigned long fixed_low_start, fixed_middle_start, fixed_high_start;
unsigned long cma_alignment;
unsigned int low_use_cma = 0;
unsigned int middle_use_cma = 0;
unsigned int high_use_cma = 0;
adjust_mem_for_liquid();
fixed_low_size = 0;
fixed_middle_size = 0;
fixed_high_size = 0;
cma_alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order);
for (i = 0; i < msm8960_ion_pdata.nr; ++i) {
struct ion_platform_heap *heap =
&(msm8960_ion_pdata.heaps[i]);
int align = SZ_4K;
int iommu_map_all = 0;
int adjacent_mem_id = INVALID_HEAP_ID;
int use_cma = 0;
if (heap->extra_data) {
int fixed_position = NOT_FIXED;
@ -576,7 +597,16 @@ static void __init reserve_ion_memory(void)
iommu_map_all =
((struct ion_cp_heap_pdata *)
heap->extra_data)->iommu_map_all;
if (((struct ion_cp_heap_pdata *)
heap->extra_data)->is_cma) {
heap->size = ALIGN(heap->size,
cma_alignment);
use_cma = 1;
}
break;
case ION_HEAP_TYPE_DMA:
use_cma = 1;
/* Purposely fall through here */
case ION_HEAP_TYPE_CARVEOUT:
fixed_position = ((struct ion_co_heap_pdata *)
heap->extra_data)->fixed_position;
@ -600,28 +630,71 @@ static void __init reserve_ion_memory(void)
else
reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
if (fixed_position == FIXED_LOW)
if (fixed_position == FIXED_LOW) {
fixed_low_size += heap->size;
else if (fixed_position == FIXED_MIDDLE)
low_use_cma = use_cma;
} else if (fixed_position == FIXED_MIDDLE) {
fixed_middle_size += heap->size;
else if (fixed_position == FIXED_HIGH)
middle_use_cma = use_cma;
} else if (fixed_position == FIXED_HIGH) {
fixed_high_size += heap->size;
high_use_cma = use_cma;
} else if (use_cma) {
/*
* Heaps that use CMA but are not part of the
* fixed set. Create wherever.
*/
dma_declare_contiguous(
heap->priv,
heap->size,
0,
0xb0000000);
}
}
}
if (!fixed_size)
return;
/* Since the fixed area may be carved out of lowmem,
* make sure the length is a multiple of 1M.
/*
* Given the setup for the fixed area, we can't round up all sizes.
* Some sizes must be set up exactly and aligned correctly. Incorrect
* alignments are considered a configuration issue
*/
fixed_size = (fixed_size + MSM_MM_FW_SIZE + SECTION_SIZE - 1)
& SECTION_MASK;
msm8960_reserve_fixed_area(fixed_size);
fixed_low_start = MSM8960_FIXED_AREA_START;
if (low_use_cma) {
BUG_ON(!IS_ALIGNED(fixed_low_start, cma_alignment));
BUG_ON(!IS_ALIGNED(fixed_low_size + HOLE_SIZE, cma_alignment));
} else {
BUG_ON(!IS_ALIGNED(fixed_low_size + HOLE_SIZE, SECTION_SIZE));
ret = memblock_remove(fixed_low_start,
fixed_low_size + HOLE_SIZE);
BUG_ON(ret);
}
fixed_middle_start = fixed_low_start + fixed_low_size + HOLE_SIZE;
if (middle_use_cma) {
BUG_ON(!IS_ALIGNED(fixed_middle_start, cma_alignment));
BUG_ON(!IS_ALIGNED(fixed_middle_size, cma_alignment));
} else {
BUG_ON(!IS_ALIGNED(fixed_middle_size, SECTION_SIZE));
ret = memblock_remove(fixed_middle_start, fixed_middle_size);
BUG_ON(ret);
}
fixed_high_start = fixed_middle_start + fixed_middle_size;
if (high_use_cma) {
fixed_high_size = ALIGN(fixed_high_size, cma_alignment);
BUG_ON(!IS_ALIGNED(fixed_high_start, cma_alignment));
} else {
/* This is the end of the fixed area so it's okay to round up */
fixed_high_size = ALIGN(fixed_high_size, SECTION_SIZE);
ret = memblock_remove(fixed_high_start, fixed_high_size);
BUG_ON(ret);
}
for (i = 0; i < msm8960_ion_pdata.nr; ++i) {
struct ion_platform_heap *heap = &(msm8960_ion_pdata.heaps[i]);
@ -637,6 +710,7 @@ static void __init reserve_ion_memory(void)
fixed_position = pdata->fixed_position;
break;
case ION_HEAP_TYPE_CARVEOUT:
case ION_HEAP_TYPE_DMA:
fixed_position = ((struct ion_co_heap_pdata *)
heap->extra_data)->fixed_position;
break;
@ -650,6 +724,14 @@ static void __init reserve_ion_memory(void)
break;
case FIXED_MIDDLE:
heap->base = fixed_middle_start;
if (middle_use_cma) {
ret = dma_declare_contiguous(
&ion_mm_heap_device.dev,
heap->size,
fixed_middle_start,
0xa0000000);
WARN_ON(ret);
}
pdata->secure_base = fixed_middle_start
- HOLE_SIZE;
pdata->secure_size = HOLE_SIZE + heap->size;