Merge "msm8960: Fix memory address and atags."
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 2f526f4..1d7d286 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -328,7 +328,7 @@
 	}
 
 	if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
-		dprintf(CRITICAL, "ERROR: Invaled boot image header\n");
+		dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
                 return -1;
 	}
 
@@ -424,12 +424,12 @@
 	offset += page_size;
 
 	if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
-		dprintf(CRITICAL, "ERROR: Invaled boot image heador\n");
+		dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
 		return -1;
 	}
 
 	if (hdr->page_size != page_size) {
-		dprintf(CRITICAL, "ERROR: Invaled boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size);
+		dprintf(CRITICAL, "ERROR: Invalid boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size);
 		return -1;
 	}
 
diff --git a/platform/msm7x30/include/platform/adm.h b/platform/msm7x30/include/platform/adm.h
new file mode 100644
index 0000000..fc703eb
--- /dev/null
+++ b/platform/msm7x30/include/platform/adm.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_ADM_H
+#define __PLATFORM_ADM_H
+
+/* Channel #s and security domain */
+#define ADM_CHN         8
+#define ADM_SD          2
+
+#endif
diff --git a/platform/msm7x30/include/platform/iomap.h b/platform/msm7x30/include/platform/iomap.h
index 76351c1..68a990c 100644
--- a/platform/msm7x30/include/platform/iomap.h
+++ b/platform/msm7x30/include/platform/iomap.h
@@ -78,6 +78,9 @@
 #define SH2_OWN_ROW2_BASE_REG   REG_BASE(0x0424)
 #define SH2_OWN_APPS2_BASE_REG  REG_BASE(0x0414)
 
+#define MSM_ADM_BASE            0xAC200000
+#define MSM_ADM_SD_OFFSET       0x00100400
+
 #define MSM_SAW_BASE            0xC0102000
 
 #define PLL_ENA_REG             REG_SH2_BASE(0x0264)
diff --git a/platform/msm7x30/platform.c b/platform/msm7x30/platform.c
index 95ddde7..cba3d08 100644
--- a/platform/msm7x30/platform.c
+++ b/platform/msm7x30/platform.c
@@ -57,6 +57,12 @@
        GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
 };
 
+/* CRCI - mmc slot mapping.
+ * mmc slot numbering start from 1.
+ * entry at index 0 is just dummy.
+ */
+uint8_t sdc_crci_map[5] = {0, 6, 7, 12, 13};
+
 void uart2_mux_init(void)
 {
        platform_gpios_enable(uart2_gpio_table, ARRAY_SIZE(uart2_gpio_table));
diff --git a/platform/msm8x60/include/platform/adm.h b/platform/msm8x60/include/platform/adm.h
new file mode 100644
index 0000000..05468d9
--- /dev/null
+++ b/platform/msm8x60/include/platform/adm.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_ADM_H
+#define __PLATFORM_ADM_H
+
+/* Channel #s and security domain */
+#define ADM_CHN         8
+#define ADM_SD          1
+
+#endif
diff --git a/platform/msm8x60/include/platform/iomap.h b/platform/msm8x60/include/platform/iomap.h
index bc2ec30..9f9a9c0 100755
--- a/platform/msm8x60/include/platform/iomap.h
+++ b/platform/msm8x60/include/platform/iomap.h
@@ -139,4 +139,7 @@
 #define USB_HS1_XVCR_FS_CLK_MD 0x00902908
 #define USB_HS1_XVCR_FS_CLK_NS 0x0090290C
 
+#define MSM_ADM_BASE            0x18400000
+#define MSM_ADM_SD_OFFSET       0x00020800
+
 #endif
diff --git a/platform/msm8x60/platform.c b/platform/msm8x60/platform.c
index 645b8aa..07f2f4d 100644
--- a/platform/msm8x60/platform.c
+++ b/platform/msm8x60/platform.c
@@ -67,6 +67,12 @@
 
 struct fbcon_config *lcdc_init(void);
 
+/* CRCI - mmc slot mapping.
+ * mmc slot numbering start from 1.
+ * entry at index 0 is just dummy.
+ */
+uint8_t sdc_crci_map[5] = {0, 1, 4, 2, 5};
+
 void platform_early_init(void)
 {
     uart_init();
diff --git a/platform/msm_shared/adm.c b/platform/msm_shared/adm.c
new file mode 100755
index 0000000..c5bf140
--- /dev/null
+++ b/platform/msm_shared/adm.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdlib.h>
+#include <reg.h>
+
+#include "adm.h"
+#include <platform/adm.h>
+
+/* TODO: This ADM implementation is very specific for use by MMC.
+ *       Replace with a generic ADM driver that can also be used
+ *       by other peripherals such as usb/uart/nand/display etc.
+ */
+
+
+/* TODO:
+ * adm module shouldn't have to include mmc.h.
+ * clean this up when generic adm interface is implemented.
+ */
+#include "mmc.h"
+
+extern void mdelay(unsigned msecs);
+extern void dmb(void);
+
+/* limit the max_row_len to fifo size so that
+ * the same src and dst row attributes can be used.
+ */
+#define MAX_ROW_LEN     MMC_BOOT_MCI_FIFO_SIZE
+#define MAX_ROW_NUM     0xFFFF
+
+/* Structures for use with ADM:
+ * Must be aligned on 8 byte boundary.
+ */
+static uint32_t adm_cmd_ptr_list[8] __attribute__ ((aligned(8)));
+static uint32_t box_mode_entry[8]   __attribute__ ((aligned(8)));
+
+adm_result_t adm_transfer_start(uint32_t adm_chn, uint32_t *cmd_ptr_list);
+
+
+/* CRCI - mmc slot mapping. */
+extern uint8_t sdc_crci_map[5];
+
+
+/* TODO:
+ * This interface is very specific to MMC.
+ * We need a generic ADM interface that can be easily
+ * used by other modules such as usb/uart/nand.
+ */
+adm_result_t adm_transfer_mmc_data(unsigned char slot,
+				   unsigned char* data_ptr,
+				   unsigned int data_len,
+				   unsigned char direction)
+{
+	uint32_t num_rows;
+	uint16_t row_len;
+	uint16_t row_offset;
+	uint32_t row_num;
+	uint32_t adm_crci_num;
+	adm_result_t result = ADM_RESULT_SUCCESS;
+
+
+	/* Make sure slot value is in the range 1..4 */
+	ASSERT( (slot >= 1) && (slot <= 4));
+
+	adm_crci_num     = sdc_crci_map[slot];
+	row_len          = MMC_BOOT_MCI_FIFO_SIZE;
+	num_rows         = data_len/MMC_BOOT_MCI_FIFO_SIZE;
+
+
+	/* While there is data to be transferred */
+	while(data_len)
+	{
+		if(data_len <= MAX_ROW_LEN)
+		{
+			row_len    = data_len;
+			row_offset = 0;
+			row_num    = 1;
+		}
+		else
+		{
+			row_len    = MAX_ROW_LEN;
+			row_offset = MAX_ROW_LEN;
+			row_num    = data_len/MAX_ROW_LEN;
+
+			/* Limit the number of row to the max value allowed */
+			if(row_num > MAX_ROW_NUM)
+			{
+				row_num = MAX_ROW_NUM;
+			}
+		}
+
+		/* Program ADM registers and initiate data transfer */
+
+		/*  Initialize the Box Mode command entry (single entry) */
+		box_mode_entry[0] = ( ADM_CMD_LIST_LC    |
+				      (adm_crci_num << 3) |
+				      ADM_ADDR_MODE_BOX);
+
+		if(direction == ADM_MMC_READ)
+		{
+			box_mode_entry[1] = MMC_BOOT_MCI_FIFO;   /* SRC addr    */
+			box_mode_entry[2] = (uint32_t) data_ptr; /* DST addr    */
+			box_mode_entry[3] = ((row_len << 16) |   /* SRC row len */
+					     (row_len << 0));    /* DST row len */
+			box_mode_entry[4] = ((row_num << 16) |   /* SRC row #   */
+					     (row_num << 0));    /* DST row #   */
+			box_mode_entry[5] = ((0 << 16) |         /* SRC offset  */
+					     (row_offset << 0)); /* DST offset  */
+		}
+		else
+		{
+			box_mode_entry[1] = (uint32_t) data_ptr; /* SRC addr    */
+			box_mode_entry[2] =  MMC_BOOT_MCI_FIFO;  /* DST addr    */
+			box_mode_entry[3] = ((row_len << 16) |   /* SRC row len */
+					     (row_len << 0));    /* DST row len */
+			box_mode_entry[4] = ((row_num << 16) |   /* SRC row #   */
+					     (row_num << 0));    /* DST row #   */
+			box_mode_entry[5] = ((row_offset << 16)| /* SRC offset  */
+					     (0 << 0));          /* DST offset  */
+		}
+
+		/*  Initialize the ADM Command Pointer List (single entry) */
+		adm_cmd_ptr_list[0] = (ADM_CMD_PTR_LP |
+				       ADM_CMD_PTR_CMD_LIST |
+				       (((uint32_t)(&box_mode_entry[0])) >> 3));
+
+
+		/* Start ADM transfer, this is a blocking call. */
+		result = adm_transfer_start(ADM_CHN, adm_cmd_ptr_list);
+
+		if(result != ADM_RESULT_SUCCESS)
+		{
+			break;
+		}
+
+		/* Update the data ptr and data len by the amount
+		 * we just transferred.
+		 */
+		data_ptr += (row_len*row_num);
+		data_len -= (row_len*row_num);
+	}
+
+	return result;
+}
+
+/*
+ * Start the ADM data transfer and return the result of the transfer.
+ * Blocks until transfer is completed.
+ */
+adm_result_t adm_transfer_start(uint32_t adm_chn, uint32_t *cmd_ptr_list)
+{
+	uint32_t reg_value;
+	uint32_t timeout     = 1;
+	uint32_t delay_count = 100;
+
+
+	/* Memory barrier to ensure that all ADM command list structure
+	 * writes have completed before starting the ADM transfer.
+	 */
+	dmb();
+
+	/* Start the ADM transfer by writing the command ptr */
+	writel( ((uint32_t)cmd_ptr_list) >> 3,
+		ADM_REG_CMD_PTR(adm_chn, ADM_SD));
+
+	/* Poll the status register to check for transfer complete.
+	 * Bail out if transfer is not finished within 1 sec.
+	 * Note: This time depends on the amount of data being transferred.
+	 * Increase the delay_count if this is not sufficient.
+	 */
+	do
+	{
+		reg_value = readl(ADM_REG_STATUS(adm_chn, ADM_SD));
+		if((reg_value & ADM_REG_STATUS__RSLT_VLD___M) != 0)
+		{
+			timeout = 0;
+			break;
+		}
+
+		/* 10ms wait */
+		mdelay(10);
+
+	} while(delay_count--);
+
+	/* Read out the IRQ register to clear the interrupt.
+	 * Even though we are not using interrupts,
+	 * kernel is not clearing the interupts during its
+	 * ADM initialization, causing it to crash.
+	 */
+	reg_value = readl(ADM_REG_IRQ(ADM_SD));
+
+	if(timeout)
+	{
+		return ADM_RESULT_TIMEOUT;
+	}
+	else
+	{
+		/* Get the result from the RSLT FIFO */
+		reg_value = readl(ADM_REG_RSLT(adm_chn, ADM_SD));
+
+		/* Check for any error */
+		if(((reg_value & ADM_REG_RSLT__ERR___M) != 0)  ||
+		   ((reg_value & ADM_REG_RSLT__TPD___M) == 0)  ||
+		   ((reg_value & ADM_REG_RSLT__V___M) == 0))
+		{
+			return ADM_RESULT_FAILURE;
+		}
+	}
+
+	return ADM_RESULT_SUCCESS;
+}
diff --git a/platform/msm_shared/adm.h b/platform/msm_shared/adm.h
new file mode 100755
index 0000000..bcf2ee3
--- /dev/null
+++ b/platform/msm_shared/adm.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_MSM_SHARED_ADM_H
+#define __PLATFORM_MSM_SHARED_ADM_H
+
+#include <platform/iomap.h>
+
+
+/* ADM base address for channel (n) and security_domain (s) */
+#define ADM_BASE_ADDR(n, s) (MSM_ADM_BASE + 4*(n) + ((MSM_ADM_SD_OFFSET)*(s)))
+
+/* ADM registers */
+#define ADM_REG_CMD_PTR(n, s)   (ADM_BASE_ADDR(n, s) + 0x000)
+#define ADM_REG_RSLT(n, s)      (ADM_BASE_ADDR(n, s) + 0x040)
+#define ADM_REG_STATUS(n, s)    (ADM_BASE_ADDR(n, s) + 0x200)
+#define ADM_REG_IRQ(s)          (ADM_BASE_ADDR(0, s) + 0x380)
+
+/* Result reg bit masks */
+#define ADM_REG_RSLT__V___M         (1 << 31)
+#define ADM_REG_RSLT__ERR___M       (1 << 3)
+#define ADM_REG_RSLT__TPD___M       (1 << 1)
+
+/* Status reg bit masks */
+#define ADM_REG_STATUS__RSLT_VLD___M    (1 << 1)
+
+
+/* Command Pointer List Entry bit masks */
+#define ADM_CMD_PTR_LP          (1 << 31) /* Last pointer */
+#define ADM_CMD_PTR_CMD_LIST    (0 << 29) /* Command List */
+
+/* Command List bit masks */
+#define ADM_CMD_LIST_LC         (1 << 31) /* Last command             */
+#define ADM_CMD_LIST_OCU        (1 << 21) /* Other channel unblock    */
+#define ADM_CMD_LIST_OCB        (1 << 20) /* Other channel block      */
+#define ADM_CMD_LIST_TCB        (1 << 19) /* This channel block       */
+#define ADM_ADDR_MODE_BOX       (3 << 0)  /* Box address mode         */
+#define ADM_ADDR_MODE_SI        (0 << 0)  /* Single item address mode */
+
+
+/* ADM external inteface */
+
+/* result type */
+typedef enum
+{
+
+ ADM_RESULT_SUCCESS = 0,
+ ADM_RESULT_FAILURE = 1,
+ ADM_RESULT_TIMEOUT = 2
+
+} adm_result_t;
+
+
+/* direction type */
+typedef enum
+{
+
+ ADM_MMC_READ = 0,
+ ADM_MMC_WRITE
+
+} adm_dir_t;
+
+adm_result_t adm_transfer_mmc_data(unsigned char slot,
+				   unsigned char* data_ptr,
+				   unsigned int data_len,
+				   adm_dir_t dir);
+#endif
diff --git a/platform/msm_shared/include/mmc.h b/platform/msm_shared/include/mmc.h
index 5bcd963..5564101 100755
--- a/platform/msm_shared/include/mmc.h
+++ b/platform/msm_shared/include/mmc.h
@@ -33,6 +33,8 @@
 #define MMC_SLOT            0

 #endif

 

+extern unsigned int mmc_boot_mci_base;

+

 #define MMC_BOOT_MCI_REG(offset)          ((mmc_boot_mci_base) + offset)

 

 /*

@@ -367,6 +369,7 @@
 #define MMC_BOOT_E_RX_OVRRUN              18

 #define MMC_BOOT_E_VREG_SET_FAILED        19

 #define MMC_BOOT_E_GPIO_CFG_FAIL          20

+#define MMC_BOOT_E_DATA_ADM_ERR           21

 

 /* EXT_CSD */

 #define MMC_BOOT_ACCESS_WRITE             0x3

@@ -593,9 +596,9 @@
 #define MMC_BOOT_WR_BLOCK_LEN         512

 

 /* We have 16 32-bits FIFO registers */

-#define MMC_BOOT_MCI_FIFO_COUNT       16

-#define MMC_BOOT_MCI_HFIFO_COUNT      ( MMC_BOOT_MCI_FIFO_COUNT / 2 )

-#define MMC_BOOT_MCI_FIFO_SIZE        ( MMC_BOOT_MCI_FIFO_COUNT * 4 )

+#define MMC_BOOT_MCI_FIFO_DEPTH       16

+#define MMC_BOOT_MCI_HFIFO_COUNT      ( MMC_BOOT_MCI_FIFO_DEPTH / 2 )

+#define MMC_BOOT_MCI_FIFO_SIZE        ( MMC_BOOT_MCI_FIFO_DEPTH * 4 )

 

 /*Need to put at proper place*/

 #define SDC1_CLK    19  /* Secure Digital Card clocks */

diff --git a/platform/msm_shared/mmc.c b/platform/msm_shared/mmc.c
index f29421a..aefccef 100644
--- a/platform/msm_shared/mmc.c
+++ b/platform/msm_shared/mmc.c
@@ -33,10 +33,28 @@
 #include "mmc.h"

 #include <platform/iomap.h>

 

+#if MMC_BOOT_ADM

+#include "adm.h"

+#endif

+

 #ifndef NULL

 #define NULL        0

 #endif

 

+#define MMC_BOOT_DATA_READ     0

+#define MMC_BOOT_DATA_WRITE    1

+

+

+static unsigned int mmc_boot_fifo_data_transfer(unsigned int* data_ptr,

+                                                unsigned int  data_len,

+                                                unsigned char direction);

+

+static unsigned int mmc_boot_fifo_read(unsigned int* data_ptr,

+                                       unsigned int data_len);

+

+static unsigned int mmc_boot_fifo_write(unsigned int* data_ptr,

+                                        unsigned int data_len);

+

 #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))

 

 /* data access time unit in ns */

@@ -1124,10 +1142,7 @@
     struct mmc_boot_command cmd;

     unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

     unsigned int mmc_reg = 0;

-    unsigned int mmc_status = 0;

     unsigned int* mmc_ptr = (unsigned int *)buf;

-    unsigned int mmc_count = 0;

-    unsigned int read_error;

 

     memset(buf,0, 512);

 

@@ -1163,6 +1178,11 @@
     /* Set appropriate fields and write the MCI_DATA_CTL register. */

     /* Set ENABLE bit to 1 to enable the data transfer. */

     mmc_reg = MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (512 << MMC_BOOT_MCI_BLKSIZE_POS);

+

+#if MMC_BOOT_ADM

+    mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;

+#endif

+

     writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );

 

     memset( (struct mmc_boot_command *)&cmd, 0,

@@ -1180,56 +1200,10 @@
         return mmc_ret;

     }

 

-    read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \

-                 MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \

-                 MMC_BOOT_MCI_STAT_RX_OVRRUN;

+    /* Read the transfer data from SDCC FIFO. */

+    mmc_ret = mmc_boot_fifo_data_transfer(mmc_ptr, 512, MMC_BOOT_DATA_READ);

 

-    /* Read the transfer data from SDCC2 FIFO. If Data Mover is not used

-       read the data from the MCI_FIFO register as long as RXDATA_AVLBL

-       bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL,

-       DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0.

-       Continue the reads until the whole transfer data is received */

-

-    do

-    {

-        mmc_ret = MMC_BOOT_E_SUCCESS;

-        mmc_status = readl( MMC_BOOT_MCI_STATUS );

-

-        if( mmc_status & read_error )

-        {

-            mmc_ret = mmc_boot_status_error(mmc_status);

-            break;

-        }

-

-        if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL )

-        {

-            unsigned read_count = 1;

-            if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)

-            {

-                read_count = MMC_BOOT_MCI_HFIFO_COUNT;

-            }

-

-            for (int i=0; i<read_count; i++)

-            {

-                /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

-                *mmc_ptr = readl( MMC_BOOT_MCI_FIFO +

-                        ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

-                mmc_ptr++;

-                /* increase mmc_count by word size */

-                mmc_count += sizeof( unsigned int );

-            }

-            /* quit if we have read enough of data */

-            if (mmc_count >= 512)

-                break;

-        }

-        else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_END )

-        {

-            break;

-        }

-    }while(1);

-

-    return MMC_BOOT_E_SUCCESS;

-

+    return mmc_ret;

 }

 

 /*

@@ -1477,12 +1451,9 @@
 {

     unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

     unsigned int mmc_status = 0;

-    unsigned int* mmc_ptr = in;

-    unsigned int mmc_count = 0;

     unsigned int mmc_reg = 0;

     unsigned int addr;

     unsigned int xfer_type;

-    unsigned int write_error;

     unsigned int status;

 

     if( ( host == NULL ) || ( card == NULL ) )

@@ -1508,7 +1479,7 @@
         MMC_BOOT_XFER_SINGLE_BLOCK;

 

     /* For MMCHC/SDHC data address is specified in unit of 512B */

-    addr = ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) ) 

+    addr = ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) )

         ? (unsigned int) data_addr : (unsigned int) (data_addr / 512);

 

     /* Set the FLOW_ENA bit of MCI_CLK register to 1 */

@@ -1543,63 +1514,20 @@
     /* Clear MODE bit to 0 to enable block oriented data transfer. For

        MMC cards only, if stream data transfer mode is desired, set

        MODE bit to 1. */

+

     /* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */

+

+#if MMC_BOOT_ADM

+    mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;

+#endif

+

     /* Write size of block to be used during the data transfer to

        BLOCKSIZE field */

     mmc_reg |= card->wr_block_len << MMC_BOOT_MCI_BLKSIZE_POS;

     writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );

 

-    write_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \

-                  MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \

-                  MMC_BOOT_MCI_STAT_TX_UNDRUN;

-

-    /* Write the transfer data to SDCC3 FIFO */

-    /* If Data Mover is used for data transfer, prepare a command list entry

-       and enable the Data Mover to work with SDCC2 */

-    /* If Data Mover is NOT used for data xfer: */

-    do

-    {

-        mmc_ret = MMC_BOOT_E_SUCCESS;

-        mmc_status = readl( MMC_BOOT_MCI_STATUS );

-

-        if( mmc_status & write_error )

-        {

-            mmc_ret = mmc_boot_status_error(mmc_status);

-            break;

-        }

-

-        /* Write the data in MCI_FIFO register as long as TXFIFO_FULL bit of

-           MCI_STATUS register is 0. Continue the writes until the whole

-           transfer data is written. */

-        if (((data_len-mmc_count) >= MMC_BOOT_MCI_FIFO_SIZE/2) &&

-                ( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL ))

-        {

-            for (int i=0; i < MMC_BOOT_MCI_HFIFO_COUNT; i++ )

-            {

-                /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

-                writel( *mmc_ptr, MMC_BOOT_MCI_FIFO +

-                        ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

-                mmc_ptr++;

-                /* increase mmc_count by word size */

-                mmc_count += sizeof( unsigned int );

-            }

-

-        }

-        else if( !( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_FULL ) && (mmc_count != data_len))

-        {

-            /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

-            writel( *mmc_ptr, MMC_BOOT_MCI_FIFO +

-                    ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

-            mmc_ptr++;

-            /* increase mmc_count by word size */

-            mmc_count += sizeof( unsigned int );

-        }

-        else if((mmc_status & MMC_BOOT_MCI_STAT_DATA_END))

-        {

-            break; //success

-        }

-

-    } while(1);

+    /* write data to FIFO */

+    mmc_ret = mmc_boot_fifo_data_transfer(in, data_len, MMC_BOOT_DATA_WRITE);

 

     if( mmc_ret != MMC_BOOT_E_SUCCESS )

     {

@@ -1750,9 +1678,6 @@
         unsigned int* out )

 {

     unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

-    unsigned int mmc_status = 0;

-    unsigned int* mmc_ptr = out;

-    unsigned int mmc_count = 0;

     unsigned int mmc_reg = 0;

     unsigned int xfer_type;

     unsigned int addr = 0;

@@ -1806,7 +1731,6 @@
 

     /* If Data Mover is used for data transfer then prepare Command

        List Entry and enable the Data mover to work with SDCC2 */

-    /* Note: Data Mover not used */

 

     /* Write data timeout period to MCI_DATA_TIMER register. */

     /* Data timeout period should be in card bus clock periods */

@@ -1834,7 +1758,13 @@
     /* Clear MODE bit to 0 to enable block oriented data transfer. For

        MMC cards only, if stream data transfer mode is desired, set

        MODE bit to 1. */

-    /* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */

+

+    /* If DMA is to be used, Set DM_ENABLE bit to 1 */

+

+#if MMC_BOOT_ADM

+        mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;

+#endif

+

     /* Write size of block to be used during the data transfer to

        BLOCKSIZE field */

     mmc_reg |= (card->rd_block_len << MMC_BOOT_MCI_BLKSIZE_POS);

@@ -1850,53 +1780,8 @@
         return mmc_ret;

     }

 

-    read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \

-                 MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \

-                 MMC_BOOT_MCI_STAT_RX_OVRRUN;

-

-    /* Read the transfer data from SDCC2 FIFO. If Data Mover is not used

-       read the data from the MCI_FIFO register as long as RXDATA_AVLBL

-       bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL,

-       DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0.

-       Continue the reads until the whole transfer data is received */

-

-    do

-    {

-        mmc_ret = MMC_BOOT_E_SUCCESS;

-        mmc_status = readl( MMC_BOOT_MCI_STATUS );

-

-        if( mmc_status & read_error )

-        {

-            mmc_ret = mmc_boot_status_error(mmc_status);

-            break;

-        }

-

-        if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL )

-        {

-            unsigned read_count = 1;

-            if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)

-            {

-                read_count = MMC_BOOT_MCI_HFIFO_COUNT;

-            }

-

-            for (int i=0; i<read_count; i++)

-            {

-                /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

-                *mmc_ptr = readl( MMC_BOOT_MCI_FIFO +

-                        ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

-                mmc_ptr++;

-                /* increase mmc_count by word size */

-                mmc_count += sizeof( unsigned int );

-            }

-            /* quit if we have read enough of data */

-            if (mmc_count == data_len)

-                break;

-        }

-        else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_END )

-        {

-            break;

-        }

-    }while(1);

+    /* Read the transfer data from SDCC FIFO. */

+    mmc_ret = mmc_boot_fifo_data_transfer(out, data_len, MMC_BOOT_DATA_READ);

 

     if( mmc_ret != MMC_BOOT_E_SUCCESS )

     {

@@ -2656,6 +2541,8 @@
             memcpy(mbr_ent->name,"efs2",4);

             break;

         case MMC_USERDATA_TYPE:

+            if (ext3_count == sizeof(ext3_partitions) / sizeof(char*))

+                return;

             strcpy((char *)mbr_ent->name,(const char *)ext3_partitions[ext3_count]);

             ext3_count++;

             break;

@@ -2700,12 +2587,7 @@
 {

     struct mmc_boot_command cmd;

     unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

-    unsigned int mmc_status = 0;

-    unsigned int* mmc_ptr = out;

-    unsigned int mmc_count = 0;

     unsigned int mmc_reg = 0;

-    unsigned int xfer_type;

-    unsigned int read_error;

 

     /* Set the FLOW_ENA bit of MCI_CLK register to 1 */

     mmc_reg = readl( MMC_BOOT_MCI_CLK );

@@ -2721,6 +2603,11 @@
     /* Set appropriate fields and write the MCI_DATA_CTL register. */

     /* Set ENABLE bit to 1 to enable the data transfer. */

     mmc_reg = MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (data_len << MMC_BOOT_MCI_BLKSIZE_POS);

+

+#if MMC_BOOT_ADM

+    mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;

+#endif

+

     writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );

 

     memset( (struct mmc_boot_command *)&cmd, 0,

@@ -2738,47 +2625,8 @@
         return mmc_ret;

     }

 

-    read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \

-                 MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \

-                 MMC_BOOT_MCI_STAT_RX_OVRRUN;

-

-    do

-    {

-        mmc_ret = MMC_BOOT_E_SUCCESS;

-        mmc_status = readl( MMC_BOOT_MCI_STATUS );

-

-        if( mmc_status & read_error )

-        {

-            mmc_ret = mmc_boot_status_error(mmc_status);

-            break;

-        }

-

-        if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL )

-        {

-            unsigned read_count = 1;

-            if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)

-            {

-                read_count = MMC_BOOT_MCI_HFIFO_COUNT;

-            }

-

-            for (int i=0; i<read_count; i++)

-            {

-                /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

-                *mmc_ptr = readl( MMC_BOOT_MCI_FIFO +

-                        ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

-                mmc_ptr++;

-                /* increase mmc_count by word size */

-                mmc_count += sizeof( unsigned int );

-            }

-            /* quit if we have read enough of data */

-            if (mmc_count == data_len)

-                break;

-        }

-        else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_END )

-        {

-            break;

-        }

-    }while(1);

+    /* Read the transfer data from SDCC FIFO. */

+    mmc_ret = mmc_boot_fifo_data_transfer(out, data_len, MMC_BOOT_DATA_READ);

 

     if( mmc_ret != MMC_BOOT_E_SUCCESS )

     {

@@ -3015,4 +2863,171 @@
 unsigned mmc_get_psn(void)

 {

 	return mmc_card.cid.psn;

+}
+
+/*

+ * Read/write data from/to SDC FIFO.

+ */

+static unsigned int mmc_boot_fifo_data_transfer(unsigned int* data_ptr,

+                                                unsigned int  data_len,

+                                                unsigned char direction)

+{

+        unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

+

+#if MMC_BOOT_ADM

+        adm_result_t ret;

+        adm_dir_t adm_dir;

+

+        if(direction == MMC_BOOT_DATA_READ)

+        {

+                adm_dir = ADM_MMC_READ;

+        }

+        else

+        {

+                adm_dir = ADM_MMC_WRITE;

+        }

+

+        ret = adm_transfer_mmc_data(mmc_slot,

+                                    (unsigned char*) data_ptr,

+                                    data_len,

+                                    adm_dir);

+

+        if(ret != ADM_RESULT_SUCCESS)

+        {

+                dprintf(CRITICAL, "MMC ADM transfer error: %d\n", ret);

+                mmc_ret = MMC_BOOT_E_FAILURE;

+        }

+#else

+

+        if(direction == MMC_BOOT_DATA_READ)

+        {

+                mmc_ret = mmc_boot_fifo_read(data_ptr, data_len);

+        }

+        else

+        {

+                mmc_ret = mmc_boot_fifo_write(data_ptr, data_len);

+        }

+#endif

+        return mmc_ret;

+}

+

+/*

+ * Read data to SDC FIFO.

+ */

+static unsigned int mmc_boot_fifo_read(unsigned int* mmc_ptr,

+                                       unsigned int  data_len)

+{

+    unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

+    unsigned int mmc_status = 0;

+    unsigned int mmc_count = 0;

+    unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \

+                                 MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \

+                                 MMC_BOOT_MCI_STAT_RX_OVRRUN;

+

+

+    /* Read the data from the MCI_FIFO register as long as RXDATA_AVLBL

+       bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL,

+       DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0.

+       Continue the reads until the whole transfer data is received */

+

+    do

+    {

+        mmc_ret = MMC_BOOT_E_SUCCESS;

+        mmc_status = readl( MMC_BOOT_MCI_STATUS );

+

+        if( mmc_status & read_error )

+        {

+            mmc_ret = mmc_boot_status_error(mmc_status);

+            break;

+        }

+

+        if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL )

+        {

+            unsigned read_count = 1;

+            if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)

+            {

+                read_count = MMC_BOOT_MCI_HFIFO_COUNT;

+            }

+

+            for (unsigned int i=0; i<read_count; i++)

+            {

+                /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

+                *mmc_ptr = readl( MMC_BOOT_MCI_FIFO +

+                        ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

+                mmc_ptr++;

+                /* increase mmc_count by word size */

+                mmc_count += sizeof( unsigned int );

+            }

+            /* quit if we have read enough of data */

+            if (mmc_count == data_len)

+                break;

+        }

+        else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_END )

+        {

+            break;

+        }

+    }while(1);

+

+    return mmc_ret;

+}

+

+/*

+ * Write data to SDC FIFO.

+ */

+static unsigned int mmc_boot_fifo_write(unsigned int* mmc_ptr,

+                                        unsigned int data_len)

+{

+    unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

+    unsigned int mmc_status = 0;

+    unsigned int mmc_count = 0;

+    unsigned int write_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \

+                               MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \

+                               MMC_BOOT_MCI_STAT_TX_UNDRUN;

+

+

+    /* Write the transfer data to SDCC3 FIFO */

+    do

+    {

+        mmc_ret = MMC_BOOT_E_SUCCESS;

+        mmc_status = readl( MMC_BOOT_MCI_STATUS );

+

+        if( mmc_status & write_error )

+        {

+            mmc_ret = mmc_boot_status_error(mmc_status);

+            break;

+        }

+

+        /* Write the data in MCI_FIFO register as long as TXFIFO_FULL bit of

+           MCI_STATUS register is 0. Continue the writes until the whole

+           transfer data is written. */

+        if (((data_len-mmc_count) >= MMC_BOOT_MCI_FIFO_SIZE/2) &&

+                ( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL ))

+        {

+            for (int i=0; i < MMC_BOOT_MCI_HFIFO_COUNT; i++ )

+            {

+                /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

+                writel( *mmc_ptr, MMC_BOOT_MCI_FIFO +

+                        ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

+                mmc_ptr++;

+                /* increase mmc_count by word size */

+                mmc_count += sizeof( unsigned int );

+            }

+

+        }

+        else if( !( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_FULL ) && (mmc_count != data_len))

+        {

+            /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/

+            writel( *mmc_ptr, MMC_BOOT_MCI_FIFO +

+                    ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );

+            mmc_ptr++;

+            /* increase mmc_count by word size */

+            mmc_count += sizeof( unsigned int );

+        }

+        else if((mmc_status & MMC_BOOT_MCI_STAT_DATA_END))

+        {

+            break; //success

+        }

+

+    } while(1);

+    return mmc_ret;

 }

diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 25cba45..57827c5 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -22,7 +22,10 @@
 ifeq ($(PLATFORM),msm8x60)
 	OBJS += $(LOCAL_DIR)/mipi_dsi.o \
 	        $(LOCAL_DIR)/i2c_qup.o \
-	        $(LOCAL_DIR)/uart_dm.o
+	        $(LOCAL_DIR)/uart_dm.o \
+	        $(LOCAL_DIR)/crypto_eng.o \
+	        $(LOCAL_DIR)/crypto_hash.o \
+		$(LOCAL_DIR)/scm_decrypt.o
 endif
 
 ifeq ($(PLATFORM),msm8960)
@@ -42,9 +45,3 @@
 	OBJS += $(LOCAL_DIR)/crypto_eng.o \
 	        $(LOCAL_DIR)/crypto_hash.o
 endif
-
-ifeq ($(PLATFORM),msm8x60)
-	OBJS += $(LOCAL_DIR)/crypto_eng.o \
-	        $(LOCAL_DIR)/crypto_hash.o \
-		$(LOCAL_DIR)/scm_decrypt.o
-endif
diff --git a/target/msm7627a/init.c b/target/msm7627a/init.c
index a591f46..86ceef7 100644
--- a/target/msm7627a/init.c
+++ b/target/msm7627a/init.c
@@ -288,3 +288,13 @@
 void target_battery_charging_enable(unsigned enable, unsigned disconnect)
 {
 }
+
+#if _EMMC_BOOT
+void target_serialno(unsigned char *buf)
+{
+	unsigned int serialno;
+	serialno =  mmc_get_psn();
+	sprintf(buf,"%x",serialno);
+}
+#endif
+
diff --git a/target/msm7630_surf/rules.mk b/target/msm7630_surf/rules.mk
index e318b14..3c1efac 100644
--- a/target/msm7630_surf/rules.mk
+++ b/target/msm7630_surf/rules.mk
@@ -20,6 +20,7 @@
 DEFINES += DISPLAY_SPLASH_SCREEN=0
 DEFINES += DISPLAY_TYPE_MDDI=0
 DEFINES += DISPLAY_TYPE_LCDC=0
+DEFINES += MMC_BOOT_ADM=0
 
 MODULES += \
 	dev/keys \
diff --git a/target/msm8660_surf/rules.mk b/target/msm8660_surf/rules.mk
index 960d8be..6c6c3a0 100755
--- a/target/msm8660_surf/rules.mk
+++ b/target/msm8660_surf/rules.mk
@@ -21,6 +21,7 @@
 DEFINES += DISPLAY_TYPE_MIPI=0
 DEFINES += DISPLAY_MIPI_PANEL_NOVATEK_BLUE=0
 DEFINES += DISPLAY_MIPI_PANEL_TOSHIBA=0
+DEFINES += MMC_BOOT_ADM=0
 
 MODULES += \
 	dev/keys \
diff --git a/target/msm8960/init.c b/target/msm8960/init.c
index 8e7c430..7e9ab59 100755
--- a/target/msm8960/init.c
+++ b/target/msm8960/init.c
@@ -35,13 +35,19 @@
 #include <smem.h>
 #include <platform/iomap.h>
 #include <reg.h>
+#include <dev/keys.h>
 
 #define LINUX_MACHTYPE_8960_SIM     3230
 #define LINUX_MACHTYPE_8960_RUMI3   3231
+#define LINUX_MACHTYPE_8960_CDP     3396
+#define LINUX_MACHTYPE_8960_MTP     3397
+#define LINUX_MACHTYPE_8960_FLUID   3398
+#define LINUX_MACHTYPE_8960_APQ     3399
 
 extern unsigned int mmc_boot_main(unsigned char slot, unsigned int base);
 extern void mdelay(unsigned msecs);
 extern void dmb(void);
+extern void keypad_init(void);
 
 static unsigned mmc_sdc_base[] = { MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE};
 
@@ -51,6 +57,10 @@
 	unsigned char slot;
 	dprintf(INFO, "target_init()\n");
 
+	/* Keypad init */
+	keys_init();
+	keypad_init();
+
 	/* Trying Slot 1 first */
 	slot = 1;
 	base_addr = mmc_sdc_base[slot-1];
@@ -77,6 +87,9 @@
 	unsigned id = 0;
 	unsigned mach_id = LINUX_MACHTYPE_8960_RUMI3;
 
+	/* Until the bootchain is in, return CDP id. */
+	return LINUX_MACHTYPE_8960_CDP;
+
 	smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
 					&format, sizeof(format), 0);
 	if(!smem_status)
diff --git a/target/msm8960/keypad.c b/target/msm8960/keypad.c
old mode 100644
new mode 100755
index 9b87c87..af7d63f
--- a/target/msm8960/keypad.c
+++ b/target/msm8960/keypad.c
@@ -27,27 +27,35 @@
  *
  */
 
+#include <string.h>
 #include <dev/keys.h>
 #include <dev/gpio_keypad.h>
 
+#define NUM_OF_ROWS 12
+#define NUM_OF_COLS  8
+
 #define BITS_IN_ELEMENT(x) (sizeof(x)[0] * 8)
 
-static unsigned char qwerty_keys_old[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char qwerty_keys_new[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char qwerty_keys_old[NUM_OF_ROWS];
+static unsigned char qwerty_keys_new[NUM_OF_ROWS];
 
 #define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(qwerty_keys_new) + (col)
 
-static unsigned int qwerty_keymap[] = {
-	[KEYMAP_INDEX(1, 3)] = KEY_BACK,	/* Volume down key */
+unsigned int qwerty_keymap[] = {
+    [KEYMAP_INDEX(3, 4)] = KEY_VOLUMEUP,   /* Volume key on external Keyboard */
+    [KEYMAP_INDEX(4, 4)] = KEY_VOLUMEDOWN, /* Volume key on external Keyboard */
+    [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP,   /* Volume key on the device/CDP */
+    [KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN, /* Volume key on the device/CDP */
 };
 
-static struct qwerty_keypad_info qwerty_keypad = {
+
+struct qwerty_keypad_info qwerty_keypad = {
 	.keymap         = qwerty_keymap,
 	.old_keys       = qwerty_keys_old,
 	.rec_keys       = qwerty_keys_new,
-	.rows           = 6,
-	.columns        = 5,
-	.num_of_reads   = 6,
+	.rows           = NUM_OF_ROWS,
+	.columns        = NUM_OF_COLS,
+	.num_of_reads   = NUM_OF_ROWS,
 	.rd_func        = &pa1_ssbi2_read_bytes,
 	.wr_func        = &pa1_ssbi2_write_bytes,
 	.settle_time    = 5  /* msec */,
@@ -56,5 +64,8 @@
 
 void keypad_init(void)
 {
+	memset(qwerty_keys_old, 0, sizeof(qwerty_keys_old));
+	memset(qwerty_keys_new, 0, sizeof(qwerty_keys_new));
+
 	ssbi_keypad_init(&qwerty_keypad);
 }