msm: 9615: Add support for ION

ION is a memory manager used by kernel and user
space clients to efficiently share buffers.

Add support for ION to 9615 target, as it is needed
for audio and power collapse. This commit will reserve
a total of 1mb of system memory (as reservations are
rounded up to megabyte boundaries).

A corresponding change to power management boot code
is also needed with this. When ION is enabled, the
method previously used by the PM code to allocate and
map the boot area for 9x15 does not work anymore. That
area must be allocated with a different API.

Change-Id: Id4354362dc9eccabd78943317a9e45d6844b3bd2
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index f085d77..ebb78d4 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -206,6 +206,8 @@
 CONFIG_WCD9310_CODEC=y
 CONFIG_REGULATOR_PM8XXX=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 0202746..f19e66e 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -263,6 +263,7 @@
 	select MULTI_IRQ_HANDLER
 	select MSM_PM8X60 if PM
 	select MSM_XO
+	select MSM_MULTIMEDIA_USE_ION
 	select MSM_QDSP6_APR
 	select MSM_AUDIO_QDSP6 if SND_SOC
 	select FIQ
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index e0bfc16..8a8e575 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -28,6 +28,8 @@
 #include <linux/leds-pm8xxx.h>
 #include <linux/power/ltc4088-charger.h>
 #include <linux/msm_tsens.h>
+#include <linux/ion.h>
+#include <linux/memory.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -39,6 +41,8 @@
 #include <mach/msm_bus_board.h>
 #include <mach/msm_xo.h>
 #include <mach/dma.h>
+#include <mach/ion.h>
+#include <mach/msm_memtypes.h>
 #include "timer.h"
 #include "devices.h"
 #include "board-9615.h"
@@ -47,6 +51,80 @@
 #include "acpuclock.h"
 #include "pm-boot.h"
 
+#ifdef CONFIG_ION_MSM
+#define MSM_ION_AUDIO_SIZE	0xAF000
+#define MSM_ION_HEAP_NUM	3
+#define MSM_KERNEL_EBI_SIZE	0x51000
+
+static struct memtype_reserve msm9615_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
+
+static int msm9615_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_SYSTEM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+		{
+			.id	= ION_IOMMU_HEAP_ID,
+			.type	= ION_HEAP_TYPE_IOMMU,
+			.name	= ION_IOMMU_HEAP_NAME,
+		},
+		{
+			.id	= ION_AUDIO_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_AUDIO_HEAP_NAME,
+			.size	= MSM_ION_AUDIO_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+
+static void reserve_ion_memory(void)
+{
+	msm9615_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+}
+
+static void __init msm9615_calculate_reserve_sizes(void)
+{
+	reserve_ion_memory();
+	msm9615_reserve_table[MEMTYPE_EBI1].size += MSM_KERNEL_EBI_SIZE;
+}
+
+static struct reserve_info msm9615_reserve_info __initdata = {
+	.memtype_reserve_table = msm9615_reserve_table,
+	.calculate_reserve_sizes = msm9615_calculate_reserve_sizes,
+	.paddr_to_memtype = msm9615_paddr_to_memtype,
+};
+#endif
+
 static struct pm8xxx_adc_amux pm8018_adc_channels_data[] = {
 	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
 		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
@@ -634,6 +712,9 @@
 #ifdef CONFIG_HW_RANDOM_MSM
 	&msm_device_rng,
 #endif
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
 
 	&msm_pcm,
 	&msm_multi_ch_pcm,
@@ -679,7 +760,10 @@
 
 static void __init msm9615_reserve(void)
 {
-	msm_pm_boot_pdata.p_addr = memblock_alloc(SZ_8, SZ_64K);
+#ifdef CONFIG_ION_MSM
+	reserve_info = &msm9615_reserve_info;
+	msm_reserve();
+#endif
 }
 
 static void __init msm9615_common_init(void)
@@ -715,6 +799,7 @@
 	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
 	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
 						msm_pm_data);
+	msm_pm_boot_pdata.p_addr = allocate_contiguous_ebi_nomap(SZ_8, SZ_64K);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 	msm_tsens_early_init(&msm_tsens_pdata);
 }
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index 8d4ca8b..6308453 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -126,6 +126,8 @@
 		break;
 	case MSM_PM_BOOT_CONFIG_REMAP_BOOT_ADDR:
 		if (!cpu_is_msm8625()) {
+			void *remapped;
+
 			/*
 			 * Set the boot remap address and enable remapping of
 			 * reset vector
@@ -133,8 +135,8 @@
 			if (!pdata->p_addr || !pdata->v_addr)
 				return -ENODEV;
 
-			ret = msm_pm_boot_reset_vector_init(
-							__va(pdata->p_addr));
+			remapped = ioremap_nocache(pdata->p_addr, SZ_8);
+			ret = msm_pm_boot_reset_vector_init(remapped);
 
 			__raw_writel((pdata->p_addr | BOOT_REMAP_ENABLE),
 					pdata->v_addr);