Merge "[msm] Update smem to be 8 byte align to match with everything around us"
diff --git a/platform/init.c b/platform/init.c
index c6982da..488d744 100644
--- a/platform/init.c
+++ b/platform/init.c
@@ -48,3 +48,7 @@
 __WEAK void secondary_core(unsigned sec_entry)
 {
 }
+
+__WEAK void platform_config_interleaved_mode_gpios(void)
+{
+}
diff --git a/platform/msm7x30/gpio.c b/platform/msm7x30/gpio.c
index 0b1272b..c9662f2 100644
--- a/platform/msm7x30/gpio.c
+++ b/platform/msm7x30/gpio.c
@@ -209,4 +209,12 @@
 	return (readl(r->in) & b) ? 1 : 0;
 }
 
-
+void platform_config_interleaved_mode_gpios(void)
+{
+        /* configure EB2_CS1 through GPIO86 */
+	writel (GPIO_ALT_FUNC_PAGE_REG, 0x56);
+	writel (GPIO_ALT_FUNC_CFG_REG, 0x04);
+	/* configure the EBI2_BUSY1_N through GPIO115 */
+	writel (GPIO_ALT_FUNC_PAGE_REG, 0x73);
+	writel (GPIO_ALT_FUNC_CFG_REG, 0x08);
+}
diff --git a/platform/msm7x30/gpio_hw.h b/platform/msm7x30/gpio_hw.h
index 3ef40f6..e9ff8ed 100644
--- a/platform/msm7x30/gpio_hw.h
+++ b/platform/msm7x30/gpio_hw.h
@@ -26,8 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef __PLATFORM_QSD8K_GPIO_HW_H
-#define __PLATFORM_QSD8K_GPIO_HW_H
+#ifndef __PLATFORM_MSM7X30_GPIO_HW_H
+#define __PLATFORM_MSM7X30_GPIO_HW_H
 
 #define MSM_GPIO1_BASE 0xA9000000
 #define MSM_GPIO2_BASE 0xA9100000
@@ -115,4 +115,9 @@
 #define GPIO_INT_STATUS_6  GPIO1_REG(0x103)
 #define GPIO_INT_STATUS_7  GPIO1_REG(0x108)
 
+
+#define GPIO_OUT_VAL_REG_BASE     0xABC00000
+#define GPIO_ALT_FUNC_PAGE_REG    (GPIO_OUT_VAL_REG_BASE + 0x20)
+#define GPIO_ALT_FUNC_CFG_REG     (GPIO_OUT_VAL_REG_BASE + 0x24)
+
 #endif
diff --git a/platform/msm_shared/nand.c b/platform/msm_shared/nand.c
index a91e85d..0a72902 100755
--- a/platform/msm_shared/nand.c
+++ b/platform/msm_shared/nand.c
@@ -42,6 +42,7 @@
 
 static void *flash_spare;
 static void *flash_data;
+void platform_config_interleaved_mode_gpios(void);
 
 typedef struct dmov_ch dmov_ch;
 struct dmov_ch
@@ -106,6 +107,7 @@
 
 static struct flash_info flash_info;
 static unsigned flash_pagesize = 0;
+static int interleaved_mode = 0;
 
 struct flash_identification {
 	unsigned flash_id;
@@ -3206,6 +3208,9 @@
 	switch(flash_info.type) {
 		case FLASH_8BIT_NAND_DEVICE:
 		case FLASH_16BIT_NAND_DEVICE:
+		  if(interleaved_mode)
+			return flash_nand_read_page_interleave(cmdlist, ptrlist, page, _addr, _spareaddr);
+		  else
 			return _flash_nand_read_page(cmdlist, ptrlist, page, _addr, _spareaddr);
 		case FLASH_ONENAND_DEVICE:
 			return _flash_onenand_read_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0);
@@ -3234,6 +3239,9 @@
 	switch(flash_info.type) {
 		case FLASH_8BIT_NAND_DEVICE:
 		case FLASH_16BIT_NAND_DEVICE:
+		  if(interleaved_mode)
+			return flash_nand_write_page_interleave(cmdlist, ptrlist, page, _addr, _spareaddr, 0);
+		  else
 			return _flash_nand_write_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0);
 		case FLASH_ONENAND_DEVICE:
 			return _flash_onenand_write_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0);
@@ -3447,3 +3455,14 @@
 {
 	return flash_pagesize;
 }
+
+void enable_interleave_mode(int status)
+{
+  interleaved_mode = status;
+  if(status)
+  {
+        flash_pagesize *= 2;
+	platform_config_interleaved_mode_gpios();
+  }
+  return;
+}
diff --git a/target/msm7630_surf/init.c b/target/msm7630_surf/init.c
index 1761780..4d3e468 100644
--- a/target/msm7630_surf/init.c
+++ b/target/msm7630_surf/init.c
@@ -32,10 +32,12 @@
 
 #include <debug.h>
 #include <dev/keys.h>
+#include <dev/gpio.h>
 #include <dev/gpio_keypad.h>
 #include <lib/ptable.h>
 #include <dev/flash.h>
 #include <smem.h>
+#include <reg.h>
 
 #define LINUX_MACHTYPE_7x30_SURF          1007016
 #define LINUX_MACHTYPE_7x30_FFA           1007017
@@ -110,6 +112,7 @@
 
 void smem_ptable_init(void);
 unsigned smem_get_apps_flash_start(void);
+unsigned smem_read_alloc_entry_offset(smem_mem_type_t, void *, int, int);
 
 void keypad_init(void);
 
@@ -117,6 +120,51 @@
 int target_is_emmc_boot(void);
 static int platform_version = -1;
 static int target_msm_id = -1;
+static int interleaved_mode_enabled = -1;
+void enable_interleave_mode(int);
+
+int target_is_interleaved_mode(void)
+{
+    struct smem_board_info_v4 board_info_v4;
+    unsigned int board_info_len = 0;
+    unsigned smem_status;
+    char *build_type;
+    unsigned format = 0;
+
+    if (interleaved_mode_enabled != -1)
+    {
+        return interleaved_mode_enabled;
+    }
+
+    smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
+					       &format, sizeof(format), 0);
+    if(!smem_status)
+    {
+	if ((format == 3) || (format == 4))
+	{
+	    if (format == 4)
+		board_info_len = sizeof(board_info_v4);
+	    else
+		board_info_len = sizeof(board_info_v4.board_info_v3);
+
+	    smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
+					    &board_info_v4, board_info_len);
+	    if(!smem_status)
+	    {
+		build_type = (char *)(board_info_v4.board_info_v3.build_id) + 9;
+
+		interleaved_mode_enabled = 0;
+
+		if (*build_type == 'C')
+		{
+		    interleaved_mode_enabled = 1;
+		}
+	    }
+	}
+    }
+
+    return interleaved_mode_enabled;
+}
 
 void target_init(void)
 {
@@ -143,6 +191,7 @@
 	flash_init();
 	flash_info = flash_get_info();
 	ASSERT(flash_info);
+	enable_interleave_mode(target_is_interleaved_mode());
 
 	offset = smem_get_apps_flash_start();
 	if (offset == 0xffffffff)
@@ -175,8 +224,14 @@
 			ASSERT(len >= 0);
 		}
 		next_ptr_start_adr = ptn->start + len;
-		ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
-			   len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
+		if(target_is_interleaved_mode()) {
+		        ptable_add(&flash_ptable, ptn->name, offset + (ptn->start / 2),
+				   (len / 2), ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
+		}
+		else {
+		        ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
+				   len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
+		}
 	}
 
 	smem_add_modem_partitions(&flash_ptable);