mdm9625: Add support to use non contiguous DDR regions for SCRATCH space.

Change-Id: I28727f5e3245ac5dbca3ca5d33bcca86061bb211
diff --git a/platform/mdm9x25/include/platform/iomap.h b/platform/mdm9x25/include/platform/iomap.h
index d227057..ee8b165 100644
--- a/platform/mdm9x25/include/platform/iomap.h
+++ b/platform/mdm9x25/include/platform/iomap.h
@@ -29,11 +29,14 @@
 #ifndef _PLATFORM_MDM9625_IOMAP_H_
 #define _PLATFORM_MDM9625_IOMAP_H_
 
-/*SDRAM start address */
-#define SDRAM_START_ADDR          0x0
+#define MSM_IOMAP_BASE            0xF9000000
+#define MSM_IOMAP_END             0xFEFFFFFF
 
 #define MSM_SHARED_BASE           0x00000000
 
+/*SDRAM start address */
+#define SDRAM_START_ADDR          0x00000000
+
 #define MSM_SHARED_IMEM_BASE      0xFC42B000
 #define RESTART_REASON_ADDR       (MSM_SHARED_IMEM_BASE + 0x65C)
 
diff --git a/platform/mdm9x25/platform.c b/platform/mdm9x25/platform.c
index 0b38493..0c7d280 100644
--- a/platform/mdm9x25/platform.c
+++ b/platform/mdm9x25/platform.c
@@ -32,6 +32,51 @@
 #include <qtimer.h>
 #include <board.h>
 #include <qpic_nand.h>
+#include <mmu.h>
+#include <arch/arm/mmu.h>
+#include <platform/iomap.h>
+#include <target.h>
+#include <smem.h>
+#include <reg.h>
+
+extern struct smem_ram_ptable* target_smem_ram_ptable_init();
+
+#define MB                                  (1024*1024)
+
+#define MSM_IOMAP_SIZE                      ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
+
+/* LK memory - Strongly ordered, executable */
+#define LK_MEMORY                             (MMU_MEMORY_TYPE_STRONGLY_ORDERED | \
+                                              MMU_MEMORY_AP_READ_WRITE)
+/* Scratch memory - Strongly ordered, non-executable */
+#define SCRATCH_MEMORY                        (MMU_MEMORY_TYPE_STRONGLY_ORDERED | \
+                                              MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+/* Peripherals - shared device */
+#define IOMAP_MEMORY                          (MMU_MEMORY_TYPE_DEVICE_SHARED | \
+                                              MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+#define SCRATCH_REGION1_VIRT_START            (MEMBASE + MEMSIZE)
+#define SCRATCH_REGION2_VIRT_START            (SCRATCH_REGION1_VIRT_START + \
+                                              (SCRATCH_REGION1_SIZE))
+
+#define SDRAM_BANK0_LAST_FIXED_ADDR           (SCRATCH_REGION2 + SCRATCH_REGION2_SIZE)
+
+/* Map all the accesssible memory according to the following rules:
+ * 1. Map 1MB from MSM_SHARED_BASE with 1 -1 mapping.
+ * 2. Map MEMBASE - MEMSIZE with 1 -1 mapping.
+ * 3. Map all the scratch regions immediately after Appsbl memory.
+ *     Virtual addresses start right after Appsbl Virtual address.
+ * 4. Map all the IOMAP space with 1 - 1 mapping.
+ * 5. Map all the rest of the SDRAM/ IMEM regions as 1 -1.
+ */
+mmu_section_t mmu_section_table[] = {
+/*   Physical addr,         Virtual addr,               Size (in MB),              Flags   */
+	{MSM_SHARED_BASE,       MSM_SHARED_BASE,            1,                         SCRATCH_MEMORY},
+	{MEMBASE,               MEMBASE,                    MEMSIZE / MB,              LK_MEMORY},
+	{SCRATCH_REGION1,       SCRATCH_REGION1_VIRT_START, SCRATCH_REGION1_SIZE / MB, SCRATCH_MEMORY},
+	{SCRATCH_REGION2,       SCRATCH_REGION2_VIRT_START, SCRATCH_REGION2_SIZE / MB, SCRATCH_MEMORY},
+	{MSM_IOMAP_BASE,        MSM_IOMAP_BASE,             MSM_IOMAP_SIZE,            IOMAP_MEMORY},
+};
 
 void platform_early_init(void)
 {
@@ -58,3 +103,111 @@
 	qtimer_uninit();
 	qpic_nand_uninit();
 }
+
+void platform_init_mmu_mappings(void)
+{
+	struct smem_ram_ptable *ram_ptable;
+	uint32_t i;
+	uint32_t sections;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t last_fixed_addr = SDRAM_BANK0_LAST_FIXED_ADDR;
+
+	ram_ptable = target_smem_ram_ptable_init();
+
+	/* Configure the MMU page entries for SDRAM and IMEM memory read
+	   from the smem ram table*/
+	for(i = 0; i < ram_ptable->len; i++)
+	{
+		if((ram_ptable->parts[i].category == IMEM) || (ram_ptable->parts[i].category == SDRAM))
+		{
+			/* First bank info is added according to the static table - mmu_section_table. */
+			if((ram_ptable->parts[i].start <= last_fixed_addr) &&
+			   ((ram_ptable->parts[i].start + ram_ptable->parts[i].size) >= last_fixed_addr))
+					continue;
+
+			/* Check to ensure that start address is 1MB aligned */
+			ASSERT((ram_ptable->parts[i].start & 0xFFFFF) == 0);
+
+			sections = (ram_ptable->parts[i].size) / MB;
+
+			while(sections--)
+			{
+				arm_mmu_map_section(ram_ptable->parts[i].start + sections * MB,
+									ram_ptable->parts[i].start + sections * MB,
+									SCRATCH_MEMORY);
+			}
+		}
+    }
+
+	/* Configure the MMU page entries for memory read from the
+	   mmu_section_table */
+	for (i = 0; i < table_size; i++)
+	{
+		sections = mmu_section_table[i].num_of_sections;
+
+		while (sections--)
+		{
+			arm_mmu_map_section(mmu_section_table[i].paddress + sections * MB,
+								mmu_section_table[i].vaddress + sections * MB,
+								mmu_section_table[i].flags);
+		}
+	}
+}
+
+addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
+{
+	uint32_t paddr;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t limit;
+
+	for (uint32_t i = 0; i < table_size; i++)
+	{
+		limit = (mmu_section_table[i].num_of_sections * MB) - 0x1;
+
+		if (virt_addr >= mmu_section_table[i].vaddress &&
+			virt_addr <= (mmu_section_table[i].vaddress + limit))
+		{
+				paddr = mmu_section_table[i].paddress + (virt_addr - mmu_section_table[i].vaddress);
+				return paddr;
+		}
+	}
+	/* No special mapping found.
+	 * Assume 1-1 mapping.
+	 */
+	 paddr = virt_addr;
+
+	return paddr;
+}
+
+addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr)
+{
+	uint32_t vaddr;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t limit;
+
+	for (uint32_t i = 0; i < table_size; i++)
+	{
+		limit = (mmu_section_table[i].num_of_sections * MB) - 0x1;
+
+		if (phys_addr >= mmu_section_table[i].paddress &&
+			phys_addr <= (mmu_section_table[i].paddress + limit))
+		{
+				vaddr = mmu_section_table[i].vaddress + (phys_addr - mmu_section_table[i].paddress);
+				return vaddr;
+		}
+	}
+
+	/* No special mapping found.
+	 * Assume 1-1 mapping.
+	 */
+	 vaddr = phys_addr;
+
+	return vaddr;
+}
+
+/* Do not use default identitiy mappings. */
+int platform_use_identity_mmu_mappings(void)
+{
+	return 0;
+}
+
diff --git a/target/mdm9625/meminfo.c b/target/mdm9625/meminfo.c
index 96b1b5b..7f88b56 100644
--- a/target/mdm9625/meminfo.c
+++ b/target/mdm9625/meminfo.c
@@ -32,6 +32,7 @@
 #include <smem.h>
 #include <stdint.h>
 #include <libfdt.h>
+#include <platform.h>
 #include <platform/iomap.h>
 #include <dev_tree.h>
 
@@ -42,6 +43,8 @@
 	uint32_t start_addr;
 }mem_info;
 
+static struct smem_ram_ptable ram_ptable;
+
 mem_info mdm9625_default_fixed_memory[] = {
 	{	.size = (29 * SIZE_1M),
 		.start_addr = SDRAM_START_ADDR +
@@ -53,6 +56,14 @@
 	},
 };
 
+struct smem_ram_ptable* target_smem_ram_ptable_init()
+{
+   /* Make sure RAM partition table is initialized */
+   ASSERT(smem_ram_ptable_init(&ram_ptable));
+
+   return &ram_ptable;
+}
+
 int target_add_first_mem_bank(void *fdt,
 							  uint32_t offset,
 							  mem_info usable_mem_map[],
@@ -81,15 +92,11 @@
  */
 uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
 {
-    struct smem_ram_ptable ram_ptable;
     uint32_t last_fixed_addr;
     int n;
     unsigned int i;
 	int ret;
 
-	/* Make sure RAM partition table is initialized */
-	ASSERT(smem_ram_ptable_init(&ram_ptable));
-
     n = ARRAY_SIZE(mdm9625_default_fixed_memory);
 
     last_fixed_addr = mdm9625_default_fixed_memory[n-1].start_addr +
@@ -155,10 +162,10 @@
 
 void *target_get_scratch_address(void)
 {
-	return ((void *)SCRATCH_ADDR);
+	return ((void *) VA((addr_t)SCRATCH_REGION1));
 }
 
 unsigned target_get_max_flash_size(void)
 {
-	return (28 * 1024 * 1024);
+	return (SCRATCH_REGION1_SIZE + SCRATCH_REGION2_SIZE);
 }
diff --git a/target/mdm9625/rules.mk b/target/mdm9625/rules.mk
index a784e6d..62b92f0 100644
--- a/target/mdm9625/rules.mk
+++ b/target/mdm9625/rules.mk
@@ -4,9 +4,13 @@
 
 PLATFORM := mdm9x25
 
-MEMBASE          := 0x01E00000
-MEMSIZE          := 0x00100000 # 1MB
-SCRATCH_ADDR     := 0x00200000
+MEMBASE                             := 0x01E00000
+MEMSIZE                             := 0x00100000 # 1MB
+SCRATCH_ADDR                        := 0x00200000
+SCRATCH_REGION1                     := 0x00200000
+SCRATCH_REGION1_SIZE                := 0x01C00000 #28 MB
+SCRATCH_REGION2                     := 0x07600000
+SCRATCH_REGION2_SIZE                := 0x00A00000 #10 MB
 
 DEFINES += NO_KEYPAD_DRIVER=1
 
@@ -18,7 +22,12 @@
 
 DEFINES += \
 	MEMBASE=$(MEMBASE) \
-	SCRATCH_ADDR=$(SCRATCH_ADDR)
+	SCRATCH_ADDR=$(SCRATCH_ADDR) \
+	SCRATCH_REGION1=$(SCRATCH_REGION1) \
+	SCRATCH_REGION2=$(SCRATCH_REGION2) \
+	MEMSIZE=$(MEMSIZE) \
+	SCRATCH_REGION1_SIZE=$(SCRATCH_REGION1_SIZE) \
+	SCRATCH_REGION2_SIZE=$(SCRATCH_REGION2_SIZE) \
 
 OBJS += \
 	$(LOCAL_DIR)/init.o \