msm: Enable fmem support on 7x27a
fmem makes better use of memory by allowing the system
to use pmem memory for other purposes when pmem is not
using it.
Make the pmem adsp region use fmem instead of the standard
carveout memory. When all the pmem is freed up, the pages will
be available for use by the system. The pages will be available
for pmem again when necessary.
Change-Id: Iefd2b17468fc21bf562bad5d53ca257a65d5e6a2
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 51da14b..a6b29dc 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -47,6 +47,7 @@
#include <mach/msm_battery.h>
#include <linux/smsc911x.h>
#include <linux/atmel_maxtouch.h>
+#include <linux/fmem.h>
#include "devices.h"
#include "timer.h"
#include "board-msm7x27a-regulator.h"
@@ -370,6 +371,9 @@
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 1,
.memory_type = MEMTYPE_EBI1,
+ .request_region = request_fmem_c_region,
+ .release_region = release_fmem_c_region,
+ .reusable = 1,
};
static struct platform_device android_pmem_adsp_device = {
@@ -672,6 +676,14 @@
static void msm7x27a_cfg_uart2dm_serial(void) { }
#endif
+struct fmem_platform_data fmem_pdata;
+
+struct platform_device fmem_device = {
+ .name = "fmem",
+ .id = -1,
+ .dev = { .platform_data = &fmem_pdata },
+};
+
static struct platform_device *rumi_sim_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
@@ -700,6 +712,7 @@
&msm_gsbi1_qup_i2c_device,
&msm_device_otg,
&msm_device_gadget_peripheral,
+ &fmem_device,
&android_usb_device,
&android_pmem_device,
&android_pmem_adsp_device,
@@ -744,8 +757,19 @@
},
};
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data *pmem_pdata_array[] __initdata = {
+ &android_pmem_adsp_pdata,
+ &android_pmem_audio_pdata,
+ &android_pmem_pdata,
+};
+#endif
+
static void __init size_pmem_devices(void)
{
+#ifdef CONFIG_ANDROID_PMEM
+ unsigned int i;
+ unsigned int reusable_count = 0;
if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
@@ -755,11 +779,30 @@
pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
}
-#ifdef CONFIG_ANDROID_PMEM
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_pdata.size = pmem_mdp_size;
android_pmem_audio_pdata.size = pmem_audio_size;
+
+ fmem_pdata.size = 0;
+
+ /* Find pmem devices that should use FMEM (reusable) memory.
+ */
+ for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
+ struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
+
+ if (!reusable_count && pdata->reusable)
+ fmem_pdata.size += pdata->size;
+
+ reusable_count += (pdata->reusable) ? 1 : 0;
+
+ if (pdata->reusable && reusable_count > 1) {
+ pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
+ __func__, pdata->name);
+ pdata->reusable = 0;
+ }
+ }
#endif
+
}
static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -770,9 +813,12 @@
static void __init reserve_pmem_memory(void)
{
#ifdef CONFIG_ANDROID_PMEM
- reserve_memory_for(&android_pmem_adsp_pdata);
- reserve_memory_for(&android_pmem_pdata);
- reserve_memory_for(&android_pmem_audio_pdata);
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
+ if (!pmem_pdata_array[i]->reusable)
+ reserve_memory_for(pmem_pdata_array[i]);
+ }
+
msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
#endif
}
@@ -798,6 +844,7 @@
{
reserve_info = &msm7x27a_reserve_info;
msm_reserve();
+ fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
}
static void __init msm8625_reserve(void)