target/platfrom: mdmfermium: map scratch region based on ddr size

Scratch region, size will be different for 128 and 256MB DDR varaints
of fermium targets. Added support to map these areas dynamically by
detecting the DDR size on the go.

Change-Id: I329e129ac8d476cdbc6dd38eb7277a31c660a323
diff --git a/platform/mdmfermium/platform.c b/platform/mdmfermium/platform.c
index 2c38ec7..457274c 100644
--- a/platform/mdmfermium/platform.c
+++ b/platform/mdmfermium/platform.c
@@ -50,7 +50,12 @@
 /* Peripherals - shared device */
 #define IOMAP_MEMORY                          (MMU_MEMORY_TYPE_DEVICE_SHARED | \
                                                                  MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+#define SCRATCH_REGION1_VIRT_START_128            0x88000000
+#define SCRATCH_REGION2_VIRT_START_128            (SCRATCH_REGION1_VIRT_START_128 + SCRATCH_REGION1_SIZE_128)
 
+static void ddr_based_mmu_mappings(mmu_section_t *table, uint32_t table_size);
+static uint64_t ddr_size;
+static void board_ddr_detect();
 
 /* Map all the accesssible memory according to the following rules:
  * 1. Map 1MB from MSM_SHARED_BASE with 1 -1 mapping.
@@ -67,10 +72,28 @@
 	{MSM_IOMAP_BASE,          MSM_IOMAP_BASE,                 MSM_IOMAP_SIZE,                 IOMAP_MEMORY},
 	{A7_SS_BASE,              A7_SS_BASE,                     A7_SS_SIZE,                     IOMAP_MEMORY},
 	{MSM_SHARED_IMEM_BASE,    MSM_SHARED_IMEM_BASE,           1,                              IOMAP_MEMORY},
-	{SCRATCH_REGION1,         SCRATCH_REGION1,                SCRATCH_REGION1_SIZE / MB,      SCRATCH_MEMORY},
-	{KERNEL_REGION,           KERNEL_REGION,                  KERNEL_REGION_SIZE / MB,        SCRATCH_MEMORY},
 };
 
+mmu_section_t mmu_section_table_128[] = {
+	{SCRATCH_REGION1_128,         SCRATCH_REGION1_VIRT_START_128,     SCRATCH_REGION1_SIZE_128/ MB,      SCRATCH_MEMORY},
+	{SCRATCH_REGION2_128,         SCRATCH_REGION2_VIRT_START_128,     SCRATCH_REGION2_SIZE_128/ MB,      SCRATCH_MEMORY},
+};
+
+mmu_section_t mmu_section_table_256[] = {
+	{SCRATCH_REGION_256,         SCRATCH_REGION_256,          SCRATCH_REGION_SIZE_256/ MB,      SCRATCH_MEMORY},
+	{KERNEL_REGION,              KERNEL_REGION,               KERNEL_REGION_SIZE/ MB,           SCRATCH_MEMORY},
+};
+
+static void board_ddr_detect()
+{
+	ddr_size = smem_get_ddr_size();
+	/*128MB DDR*/
+	if(ddr_size == 0x8000000)
+		ddr_based_mmu_mappings(mmu_section_table_128, ARRAY_SIZE(mmu_section_table_128));
+	else
+		ddr_based_mmu_mappings(mmu_section_table_256, ARRAY_SIZE(mmu_section_table_256));
+}
+
 void platform_early_init(void)
 {
 	board_init();
@@ -78,6 +101,7 @@
 	qgic_init();
 	qtimer_init();
 	scm_init();
+	board_ddr_detect();
 }
 
 void platform_init(void)
@@ -103,14 +127,115 @@
 
 addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
 {
-	/* Fixed 1-1 mapping */
-	return 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;
+		}
+	}
+	if(ddr_size == 0x8000000)
+	{
+		table_size = ARRAY_SIZE(mmu_section_table_128);
+		for (uint32_t i = 0; i < table_size; i++)
+		{
+			limit = (mmu_section_table_128[i].num_of_sections * MB) - 0x1;
+
+			if (virt_addr >= mmu_section_table_128[i].vaddress &&
+				virt_addr <= (mmu_section_table_128[i].vaddress + limit))
+			{
+				paddr = mmu_section_table_128[i].paddress + (virt_addr - mmu_section_table_128[i].vaddress);
+				return paddr;
+			}
+		}
+	}
+	else
+	{
+		/* Any DDR > 256MB would be mapped here & LK would use only first 256 MB */
+		table_size = ARRAY_SIZE(mmu_section_table_256);
+		for (uint32_t i = 0; i < table_size; i++)
+		{
+			limit = (mmu_section_table_256[i].num_of_sections * MB) - 0x1;
+
+			if (virt_addr >= mmu_section_table_256[i].vaddress &&
+				virt_addr <= (mmu_section_table_256[i].vaddress + limit))
+			{
+				paddr = mmu_section_table_256[i].paddress + (virt_addr - mmu_section_table_256[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)
 {
-        /* Fixed 1-1 mapping */
-	return 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;
+		}
+	}
+	if(ddr_size == 0x8000000)
+	{
+		table_size = ARRAY_SIZE(mmu_section_table_128);
+		for (uint32_t i = 0; i < table_size; i++)
+		{
+			limit = (mmu_section_table_128[i].num_of_sections * MB) - 0x1;
+
+			if (phys_addr >= mmu_section_table_128[i].paddress &&
+				phys_addr <= (mmu_section_table_128[i].paddress + limit))
+			{
+				vaddr = mmu_section_table_128[i].vaddress + (phys_addr - mmu_section_table_128[i].paddress);
+				return vaddr;
+			}
+		}
+	}
+	else
+	{
+		/* Any DDR > 256MB would be mapped here & LK would use only first 256 MB */
+		table_size = ARRAY_SIZE(mmu_section_table_256);
+		for (uint32_t i = 0; i < table_size; i++)
+		{
+			limit = (mmu_section_table_256[i].num_of_sections * MB) - 0x1;
+
+			if (phys_addr >= mmu_section_table_256[i].paddress &&
+				phys_addr <= (mmu_section_table_256[i].paddress + limit))
+			{
+				vaddr = mmu_section_table_256[i].vaddress + (phys_addr - mmu_section_table_256[i].paddress);
+				return vaddr;
+			}
+		}
+	}
+
+	/* No special mapping found.
+	 * Assume 1-1 mapping.
+	 */
+	 vaddr = phys_addr;
+
+	return vaddr;
 }
 
 /* Setup memory for this platform */
@@ -136,6 +261,31 @@
 		}
 	}
 }
+
+/* Setup memory for this platform */
+static void ddr_based_mmu_mappings(mmu_section_t *table,uint32_t table_size)
+{
+	uint32_t i;
+	uint32_t sections;
+
+	/* Configure the MMU page entries for memory read from the
+		 mmu_section_table */
+	for (i = 0; i < table_size; i++)
+	{
+		sections = table->num_of_sections;
+
+		while (sections--)
+		{
+			arm_mmu_map_section(table->paddress +
+								sections * MB,
+								table->vaddress +
+								sections * MB,
+								table->flags);
+		}
+	table++;
+	}
+}
+
 int platform_use_identity_mmu_mappings(void)
 {
 	/* Use only the mappings specified in this file. */
diff --git a/target/mdmfermium/meminfo.c b/target/mdmfermium/meminfo.c
index acaaa14..31eea83 100644
--- a/target/mdmfermium/meminfo.c
+++ b/target/mdmfermium/meminfo.c
@@ -85,10 +85,23 @@
 
 void *target_get_scratch_address(void)
 {
-	return ((void *)SCRATCH_ADDR);
+	uint64_t ddr_size = smem_get_ddr_size();
+	if (ddr_size == 0x8000000)
+		/*128MB DDR scratch address*/
+		return ((void *)VA((addr_t)SCRATCH_ADDR_128));
+	else
+		/*256MB DDR scratch address*/
+		return ((void *)VA((addr_t)SCRATCH_ADDR_256));
 }
-
+/*this function is to know max flashable size through fastboot*/
 unsigned target_get_max_flash_size(void)
 {
-	return (SCRATCH_REGION1_SIZE + SCRATCH_REGION2_SIZE);
+	uint64_t ddr_size = smem_get_ddr_size();
+
+	if (ddr_size == 0x8000000)
+		/*128MB DDR scratch size*/
+		return (SCRATCH_REGION1_SIZE_128 + SCRATCH_REGION2_SIZE_128);
+	else
+		/*256MB DDR scratch size*/
+		return (SCRATCH_REGION_SIZE_256);
 }
diff --git a/target/mdmfermium/rules.mk b/target/mdmfermium/rules.mk
index b614ea5..0bee605 100644
--- a/target/mdmfermium/rules.mk
+++ b/target/mdmfermium/rules.mk
@@ -7,16 +7,21 @@
 MEMBASE := 0x82900000 # SDRAM
 MEMSIZE := 0x00100000 # 1MB
 
-SCRATCH_ADDR                        := 0x88000000
-SCRATCH_REGION1                     := 0x88000000
-SCRATCH_REGION1_SIZE                := 0x08000000 # 128MB
-SCRATCH_REGION2                     := 0x0
-SCRATCH_REGION2_SIZE                := 0x0
+SCRATCH_ADDR                            := 0 # keeping for successful compilation
+SCRATCH_ADDR_128                        := 0x86000000
+SCRATCH_REGION1_128                     := 0x86000000
+SCRATCH_REGION1_SIZE_128                := 0x01c00000  # 28MB
+SCRATCH_REGION2_128                     := 0x80000000
+SCRATCH_REGION2_SIZE_128                := 0x02900000   # 41M
 
-KERNEL_REGION                       := 0x80000000
-KERNEL_REGION_SIZE                  := 0x2000000 # 20MB
+KERNEL_REGION                           := 0x80000000
+KERNEL_REGION_SIZE                      := 0x2000000 # 20MB
 
-BASE_ADDR                           := 0x80000000
+SCRATCH_ADDR_256                        := 0x88000000
+SCRATCH_REGION_256                      := 0x88000000
+SCRATCH_REGION_SIZE_256                 := 0x08000000  # 128MB
+
+BASE_ADDR                               := 0x80000000
 
 
 MODULES += \
@@ -31,9 +36,14 @@
 	MEMBASE=$(MEMBASE) \
 	BASE_ADDR=$(BASE_ADDR) \
 	SCRATCH_ADDR=$(SCRATCH_ADDR) \
-	SCRATCH_REGION1=$(SCRATCH_REGION1) \
-	SCRATCH_REGION1_SIZE=$(SCRATCH_REGION1_SIZE) \
-	SCRATCH_REGION2_SIZE=$(SCRATCH_REGION2_SIZE) \
+	SCRATCH_ADDR_128=$(SCRATCH_ADDR_128) \
+	SCRATCH_ADDR_256=$(SCRATCH_ADDR_256) \
+	SCRATCH_REGION_256=$(SCRATCH_REGION_256) \
+	SCRATCH_REGION1_128=$(SCRATCH_REGION1_128) \
+	SCRATCH_REGION2_128=$(SCRATCH_REGION2_128) \
+	SCRATCH_REGION1_SIZE_128=$(SCRATCH_REGION1_SIZE_128) \
+	SCRATCH_REGION2_SIZE_128=$(SCRATCH_REGION2_SIZE_128) \
+	SCRATCH_REGION_SIZE_256=$(SCRATCH_REGION_SIZE_256) \
 	KERNEL_REGION=$(KERNEL_REGION) \
 	KERNEL_REGION_SIZE=$(KERNEL_REGION_SIZE)