Merge "msm7630_surf: Enable LCDC Splash screen for 7x30 target"
diff --git a/platform/msm8960/acpuclock.c b/platform/msm8960/acpuclock.c
index 1b4a11e..0301de8 100644
--- a/platform/msm8960/acpuclock.c
+++ b/platform/msm8960/acpuclock.c
@@ -264,3 +264,25 @@
 	writel((1 << 4), CE1_CORE_CLK_CTL);
 	return;
 }
+
+/* Async Reset CE1 */
+void ce_async_reset()
+{
+	/* Enable Async reset bit for HCLK CE1 */
+	writel((1<<7) | (1 << 4), CE1_HCLK_CTL);
+	/* Enable Async reset bit for core clk for CE1 */
+	writel((1<<7) | (1 << 4), CE1_CORE_CLK_CTL);
+
+	/* Add a small delay between switching the
+	 * async intput from high to low
+	 */
+	 udelay(2);
+
+	/* Disable Async reset bit for HCLK for CE1 */
+	writel((1 << 4), CE1_HCLK_CTL);
+	/* Disable Async reset bit for core clk for CE1 */
+	writel((1 << 4), CE1_CORE_CLK_CTL);
+
+	return;
+}
+
diff --git a/platform/msm8960/platform.c b/platform/msm8960/platform.c
index 3579a6e..d45b699 100644
--- a/platform/msm8960/platform.c
+++ b/platform/msm8960/platform.c
@@ -36,7 +36,6 @@
 #include <dev/fbcon.h>
 #include <mmu.h>
 #include <arch/arm/mmu.h>
-#include <partition_parser.h>
 
 extern void platform_init_timer(void);
 extern void platform_panel_backlight_on(void);
@@ -119,31 +118,12 @@
 		mipi_dsi_shutdown();
 }
 
-/*
- * Write-protect partition list.
- *
- * Partition added in this list should have (size + padding) in multiple of
- * mmc write protect group size. Otherwise this can end up write protecting
- * some blocks from next partition.
- */
-char *wp_list[] = {"fsg", NULL};
-
-void platform_wp_paritition(void)
-{
-	int count = 0;
-	while(wp_list[count] != NULL)
-	{
-		paritition_wp_by_name(wp_list[count]);
-		count++;
-	}
-}
-
 void platform_uninit(void)
 {
 #if DISPLAY_SPLASH_SCREEN
 	display_shutdown();
 #endif
-	platform_wp_paritition();
+
 	platform_uninit_timer();
 }
 
@@ -154,11 +134,6 @@
 	uint32_t sections;
 	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
 
-	/* TODO: Caches are not working correctly on APQ8064 platform.
-	 *       Disabling caches for now. Need to fix it.
-	 */
-	return;
-
 	for (i = 0; i < table_size; i++) {
 		sections = mmu_section_table[i].num_of_sections;
 
@@ -191,4 +166,3 @@
 {
 	return ticks_per_sec;
 }
-
diff --git a/platform/msm_shared/crypto4_eng.c b/platform/msm_shared/crypto4_eng.c
old mode 100644
new mode 100755
index 2f7cdc5..62f5666
--- a/platform/msm_shared/crypto4_eng.c
+++ b/platform/msm_shared/crypto4_eng.c
@@ -34,8 +34,10 @@
 #include <platform/iomap.h>
 #include <crypto4_eng.h>
 #include <crypto_hash.h>
+#include <scm.h>
 
 extern void dsb(void);
+extern void ce_async_reset();
 
 /*
  * Function to reset the crypto engine.
@@ -43,9 +45,27 @@
 
 void crypto_eng_reset(void)
 {
+	ce_async_reset();
 	return;
 }
 
+
+/* Function to switch the CE1 context
+ * from register to ADM
+ */
+void crypto_eng_cleanup(void)
+{
+
+    unsigned int val;
+
+    enum ap_ce_channel_type chn = AP_CE_ADM_USE;
+    /* Make a SMC call to TZ to make CE1 use ADM interface for HLOS*/
+    val = switch_ce_chn_cmd(chn);
+    dprintf(INFO, "TZ channel swith returned %d\n", val);
+
+}
+
+
 /*
  * Function to initialize the crypto engine for a new session. It enables the
  * auto shutdown feature of CRYPTO and mask various interrupts since we use
@@ -55,12 +75,12 @@
 void crypto_eng_init(void)
 {
 	unsigned int val;
-	val = (AUTO_SHUTDOWN_EN | MASK_ERR_INTR | MASK_DIN_INTR |
-	       MASK_DOUT_INTR | HIGH_SPD_IN_EN_N | HIGH_SPD_OUT_EN_N);
 
-	val |= MASK_OP_DONE_INTR;
+	enum ap_ce_channel_type chn = AP_CE_REGISTER_USE;
+	/* Make a SMC call to TZ to make CE1 use register interface */
+	val = switch_ce_chn_cmd(chn);
+	dprintf(INFO, "TZ channel swith returned %d\n", val);
 
-	wr_ce(val, CRYPTO_CONFIG);
 }
 
 /*
diff --git a/platform/msm_shared/crypto_hash.c b/platform/msm_shared/crypto_hash.c
index 4993622..363e682 100644
--- a/platform/msm_shared/crypto_hash.c
+++ b/platform/msm_shared/crypto_hash.c
@@ -37,6 +37,10 @@
 
 extern void ce_clock_init(void);
 
+__WEAK void crypto_eng_cleanup()
+{
+}
+
 /*
  * Top level function which calculates SHAx digest with given data and size.
  * Digest varies based on the authentication algorithm.
@@ -68,6 +72,9 @@
 	if (ret_val != CRYPTO_SHA_ERR_NONE) {
 		dprintf(CRITICAL, "crypto_sha256 returns error %d\n", ret_val);
 	}
+
+	crypto_eng_cleanup();
+
 }
 
 /*
diff --git a/platform/msm_shared/include/mmc.h b/platform/msm_shared/include/mmc.h
index 6c754ff..a07d169 100644
--- a/platform/msm_shared/include/mmc.h
+++ b/platform/msm_shared/include/mmc.h
@@ -374,7 +374,6 @@
 #define MMC_BOOT_E_DATA_ADM_ERR           21
 
 /* EXT_CSD */
-#define MMC_BOOT_ACCESS_BIT_SET           0x1
 #define MMC_BOOT_ACCESS_WRITE             0x3
 
 #define MMC_BOOT_EXT_USER_WP              171
@@ -594,10 +593,6 @@
 unsigned int mmc_erase_card(unsigned long long data_addr,
 			    unsigned long long data_len);
 
-unsigned int mmc_wp(unsigned int sector, unsigned int size,
-				unsigned char set_clear_wp);
-
 struct mmc_boot_host *get_mmc_host(void);
 struct mmc_boot_card *get_mmc_card(void);
-
 #endif
diff --git a/platform/msm_shared/include/partition_parser.h b/platform/msm_shared/include/partition_parser.h
index 48fd982..8e0f2ee 100644
--- a/platform/msm_shared/include/partition_parser.h
+++ b/platform/msm_shared/include/partition_parser.h
@@ -176,7 +176,6 @@
 		       struct mmc_boot_host *mmc_host,
 		       struct mmc_boot_card *mmc_card);
 unsigned int write_partition(unsigned size, unsigned char *partition);
-unsigned int paritition_wp_by_name(const char *name);
 
 /* For Debugging */
 void partition_dump(void);
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
old mode 100644
new mode 100755
index 3e78cf7..668e32c
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -67,11 +67,27 @@
 static uint32 smc(uint32 cmd_addr);
 int decrypt_img_scm(uint32 ** img_ptr, uint32 * img_len_ptr);
 
-#define SCM_SVC_FUSE            0x08
-#define SCM_BLOW_SW_FUSE_ID     0x01
-#define SCM_IS_SW_FUSE_BLOWN_ID 0x02
+#define SCM_SVC_FUSE                0x08
+#define SCM_BLOW_SW_FUSE_ID         0x01
+#define SCM_IS_SW_FUSE_BLOWN_ID     0x02
 
-#define HLOS_IMG_TAMPER_FUSE    0
+#define HLOS_IMG_TAMPER_FUSE        0
+
+
+#define SCM_SVC_CE_CHN_SWITCH_ID    0x04
+#define SCM_CE_CHN_SWITCH_ID        0x02
+
+enum ap_ce_channel_type {
+AP_CE_REGISTER_USE = 0,
+AP_CE_ADM_USE = 1
+};
+
+/* Apps CE resource. */
+#define TZ_RESOURCE_CE_AP  2
+
+uint8_t switch_ce_chn_cmd(enum ap_ce_channel_type channel);
+
+
 void set_tamper_fuse_cmd();
 
 /**
@@ -118,4 +134,6 @@
 	uint32_t is_complete;
 };
 
+
+
 #endif
diff --git a/platform/msm_shared/mmc.c b/platform/msm_shared/mmc.c
index 2d86ba1..b1fc977 100644
--- a/platform/msm_shared/mmc.c
+++ b/platform/msm_shared/mmc.c
@@ -85,6 +85,8 @@
 struct mmc_boot_host mmc_host;
 struct mmc_boot_card mmc_card;
 
+static unsigned int mmc_wp(unsigned int addr, unsigned int size,
+			   unsigned char set_clear_wp);
 static unsigned int mmc_boot_send_ext_cmd(struct mmc_boot_card *card,
 					  unsigned char *buf);
 static unsigned int mmc_boot_read_reg(struct mmc_boot_card *card,
@@ -2282,7 +2284,7 @@
 	       sizeof(struct mmc_boot_command));
 
 	/* Disabling PERM_WP for USER AREA (CMD6) */
-	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_BIT_SET,
+	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
 				      MMC_BOOT_EXT_USER_WP,
 				      MMC_BOOT_US_PERM_WP_DIS);
 
@@ -2336,14 +2338,14 @@
 		    (card->csd.erase_grp_mult + 1) * (card->csd.wp_grp_size +
 						      1);
 	}
-	dprintf(SPEW, "Write protect size: %d bytes\n", (wp_group_size * MMC_BOOT_WR_BLOCK_LEN));
+
 	if (wp_group_size == 0) {
 		return MMC_BOOT_E_FAILURE;
 	}
 
 	/* Setting POWER_ON_WP for USER AREA (CMD6) */
 
-	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_BIT_SET,
+	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
 				      MMC_BOOT_EXT_USER_WP,
 				      MMC_BOOT_US_PWR_WP_EN);
 
@@ -2371,9 +2373,6 @@
 
 	if (size % wp_group_size) {
 		loop_count = (size / wp_group_size) + 1;
-		dprintf(CRITICAL, "WARNING: Size passed to write protect is not multiple of wp_group_size!\n");
-		dprintf(CRITICAL, "WARNING: Write protecting %d extra bytes.\n",
-						((loop_count * wp_group_size) - size) * MMC_BOOT_WR_BLOCK_LEN);
 	} else {
 		loop_count = (size / wp_group_size);
 	}
@@ -2434,9 +2433,9 @@
 }
 
 /*
- * Function for setting Write protect for given sector
+ * Test Function for setting Write protect for given sector
  */
-unsigned int
+static unsigned int
 mmc_wp(unsigned int sector, unsigned int size, unsigned char set_clear_wp)
 {
 	unsigned int rc = MMC_BOOT_E_SUCCESS;
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 2becaed..45f5413 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -946,42 +946,3 @@
 
 	return 0;
 }
-
-/*
- * Power on write protect partition by name.
- *
- * Partition passed to this function should have (size + padding) in multiple
- * of mmc write protect group size. Otherwise this can end up write protecting
- * some blocks from next partition.
- */
-
-unsigned int paritition_wp_by_name(const char *name)
-{
-	unsigned long long ptn = 0;
-	unsigned long long size = 0;
-	int index = INVALID_PTN;
-	unsigned int ret = MMC_BOOT_E_SUCCESS;
-
-	index = partition_get_index(name);
-	ptn = partition_get_offset(index);
-	if(ptn == 0) {
-		dprintf(CRITICAL, "%s partition not found.\n", name);
-		return 1;
-	}
-
-	size = partition_get_size(index);
-
-	/* Offset in sectors */
-	ptn = ptn / MMC_BOOT_RD_BLOCK_LEN;
-
-	/* Size in sectors */
-	size = size / MMC_BOOT_RD_BLOCK_LEN;
-
-	ret = mmc_wp((unsigned)ptn, (unsigned)size, 1);
-	if(ret)
-	{
-		dprintf(CRITICAL, "Failed to write protect: %s\n", name);
-		return 1;
-	}
-	return 0;
-}
diff --git a/platform/msm_shared/qtimer.c b/platform/msm_shared/qtimer.c
new file mode 100755
index 0000000..8af01f4
--- /dev/null
+++ b/platform/msm_shared/qtimer.c
@@ -0,0 +1,198 @@
+/* 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 <debug.h>
+#include <reg.h>
+#include <sys/types.h>
+
+#include <platform/timer.h>
+#include <platform/irqs.h>
+#include <platform/iomap.h>
+#include <platform/interrupts.h>
+#include <kernel/thread.h>
+
+#define QTMR_TIMER_CTRL_ENABLE          (1 << 0)
+#define QTMR_TIMER_CTRL_INT_MASK        (1 << 1)
+
+#define PLATFORM_TIMER_TYPE_PHYSICAL     1
+#define PLATFORM_TIMER_TYPE_VIRTUAL      2
+
+static platform_timer_callback timer_callback;
+static void *timer_arg;
+static time_t timer_interval;
+static unsigned int timer_type = PLATFORM_TIMER_TYPE_PHYSICAL;
+static volatile uint32_t ticks;
+
+static enum handler_return timer_irq(void *arg)
+{
+	ticks += timer_interval;
+
+	if (timer_type == PLATFORM_TIMER_TYPE_VIRTUAL)
+		__asm__("mcr p15, 0, %0, c14, c3, 0"::"r"(timer_interval));
+	else if (timer_type == PLATFORM_TIMER_TYPE_PHYSICAL)
+		__asm__("mcr p15, 0, %0, c14, c2, 0" : :"r" (timer_interval));
+
+	return timer_callback(timer_arg, ticks);
+}
+
+/* Programs the Virtual Down counter timer.
+ * interval : Counter ticks till expiry interrupt is fired.
+ */
+unsigned int platform_set_virtual_timer(uint32_t interval)
+{
+	uint32_t ctrl;
+
+	/* Program CTRL Register */
+	ctrl =0;
+	ctrl |= QTMR_TIMER_CTRL_ENABLE;
+	ctrl &= ~QTMR_TIMER_CTRL_INT_MASK;
+
+	__asm__("mcr p15, 0, %0, c14, c3, 1"::"r"(ctrl));
+
+	/* Set Virtual Down Counter */
+	__asm__("mcr p15, 0, %0, c14, c3, 0"::"r"(interval));
+
+	return INT_QTMR_VIRTUAL_TIMER_EXP;
+
+}
+
+/* Programs the Physical Secure Down counter timer.
+ * interval : Counter ticks till expiry interrupt is fired.
+ */
+unsigned int platform_set_physical_timer(uint32_t interval)
+{
+	uint32_t ctrl;
+
+	/* Program CTRL Register */
+	ctrl =0;
+	ctrl |= QTMR_TIMER_CTRL_ENABLE;
+	ctrl &= ~QTMR_TIMER_CTRL_INT_MASK;
+
+	__asm__("mcr p15, 0, %0, c14, c2, 1" : :"r" (ctrl));
+
+	/* Set Physical Down Counter */
+	__asm__("mcr p15, 0, %0, c14, c2, 0" : :"r" (interval));
+
+	return INT_QTMR_SECURE_PHYSICAL_TIMER_EXP;
+
+}
+
+
+status_t platform_set_periodic_timer(platform_timer_callback callback,
+	void *arg, time_t interval)
+{
+	uint32_t ppi_num;
+	unsigned long ctrl;
+	uint32_t tick_count = interval * platform_tick_rate() / 1000;
+
+	enter_critical_section();
+
+	timer_callback = callback;
+	timer_arg = arg;
+	timer_interval = interval;
+
+	if (timer_type == PLATFORM_TIMER_TYPE_VIRTUAL)
+		ppi_num = platform_set_virtual_timer(tick_count);
+	else if (timer_type == PLATFORM_TIMER_TYPE_PHYSICAL)
+		ppi_num = platform_set_physical_timer(tick_count);
+
+	register_int_handler(ppi_num, timer_irq, 0);
+	unmask_interrupt(ppi_num);
+
+	exit_critical_section();
+	return 0;
+}
+
+time_t current_time(void)
+{
+	return ticks;
+}
+
+void platform_uninit_timer(void)
+{
+	uint32_t ctrl;
+
+	unmask_interrupt(INT_DEBUG_TIMER_EXP);
+
+	/* program cntrl register */
+	ctrl =0;
+	ctrl |= ~QTMR_TIMER_CTRL_ENABLE;
+	ctrl &= QTMR_TIMER_CTRL_INT_MASK;
+
+	if (timer_type == PLATFORM_TIMER_TYPE_VIRTUAL)
+		__asm__("mcr p15, 0, %0, c14, c3, 1"::"r"(ctrl));
+	else if (timer_type == PLATFORM_TIMER_TYPE_PHYSICAL)
+		__asm__("mcr p15, 0, %0, c14, c2, 1" : :"r" (ctrl));
+
+}
+
+void mdelay(unsigned msecs)
+{
+	uint32_t phy_cnt_lo, phy_cnt_hi, cnt, timeout = 0;
+	uint64_t phy_cnt;
+	msecs = msecs *  platform_tick_rate() / 1000;
+
+	do{
+	/* read global counter */
+	__asm__("mrrc p15,0,%0,%1, c14":"=r"(phy_cnt_lo),"=r"(phy_cnt_hi));
+	phy_cnt = ((uint64_t)phy_cnt_hi << 32) | phy_cnt_lo;
+	/*Actual counter used in the simulation is only 32 bits
+	 * in reality the counter is actually 56 bits.
+	 */
+	cnt = phy_cnt & (uint32_t)~0;
+	if (timeout == 0)
+		timeout = cnt + msecs;
+	} while (cnt < timeout);
+
+}
+
+void udelay(unsigned usecs)
+{
+	uint32_t phy_cnt_lo, phy_cnt_hi, cnt, timeout = 0;
+	uint64_t phy_cnt;
+	usecs = (usecs * platform_tick_rate()) / 1000000;
+
+	do{
+	/* read global counter */
+	__asm__("mrrc p15,0,%0,%1, c14":"=r"(phy_cnt_lo),"=r"(phy_cnt_hi));
+	phy_cnt = ((uint64_t)phy_cnt_hi << 32) | phy_cnt_lo;
+
+	/*Actual counter used in the simulation is only 32 bits
+	 * in reality the counter is actually 56 bits.
+	 */
+	cnt = phy_cnt & (uint32_t)~0;
+	if (timeout == 0)
+		timeout = cnt + usecs;
+	} while (cnt < timeout);
+}
+
+/* Return current time in micro seconds */
+bigtime_t current_time_hires(void)
+{
+	return ticks * 1000000ULL;
+}
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
old mode 100644
new mode 100755
index 4905a9e..4c371d3
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -249,3 +249,38 @@
 	scm_call(svc_id, cmd_id, cmd_buf, cmd_len, &resp_buf, resp_len);
 	return resp_buf;
 }
+
+/*
+ * Switches the CE1 channel between ADM and register usage.
+ * channel : AP_CE_REGISTER_USE, CE1 uses register interface
+ *         : AP_CE_ADM_USE, CE1 uses ADM interface
+ */
+uint8_t switch_ce_chn_cmd(enum ap_ce_channel_type channel)
+{
+	uint32_t svc_id;
+	uint32_t cmd_id;
+	void *cmd_buf;
+	size_t cmd_len;
+	size_t resp_len = 0;
+	uint8_t resp_buf;
+
+	struct {
+		uint32_t resource;
+		uint32_t chn_id;
+		}__PACKED switch_ce_chn_buf;
+
+	switch_ce_chn_buf.resource = TZ_RESOURCE_CE_AP;
+	switch_ce_chn_buf.chn_id = channel;
+	cmd_buf = (void *)&switch_ce_chn_buf;
+	cmd_len = sizeof(switch_ce_chn_buf);
+
+	/*response */
+	resp_len = sizeof(resp_buf);
+
+	svc_id = SCM_SVC_CE_CHN_SWITCH_ID;
+	cmd_id = SCM_CE_CHN_SWITCH_ID;
+
+	scm_call(svc_id, cmd_id, cmd_buf, cmd_len, &resp_buf, resp_len);
+	return resp_buf;
+}
+
diff --git a/target/mdm9615/init.c b/target/mdm9615/init.c
index d1fc7b6..c285735 100644
--- a/target/mdm9615/init.c
+++ b/target/mdm9615/init.c
@@ -177,8 +177,8 @@
 {
 	int ret;
 	ret = fake_key_get_state();
-	/* Want to trigger when dip switch is off */
-	return (!ret);
+	/* Want to trigger when dip switch is on */
+	return (ret);
 }
 
 void update_ptable_modem_partitions(void)
diff --git a/target/mdm9615/keypad.c b/target/mdm9615/keypad.c
index 93eeeeb..79855cf 100644
--- a/target/mdm9615/keypad.c
+++ b/target/mdm9615/keypad.c
@@ -30,17 +30,21 @@
 #include <platform/gpio.h>
 #include <platform/iomap.h>
 
+/* GPIO that controls the Dip Switch
+ * for FASTBOOT.
+ */
+#define DIP_SWITCH_GPIO        49
 /*
  * Fake keypad for 9x15
- * Returns 1 if dip switch is on, 0 if off
+ * Returns 0 if dip switch is off, 1 if on
  */
 int fake_key_get_state(void)
 {
 	int ret;
 	/* GPIO 49 connects to Boot Config5 */
-	gpio_tlmm_config(49, 0, GPIO_OUTPUT, GPIO_PULL_DOWN,
+	gpio_tlmm_config(DIP_SWITCH_GPIO, 0, GPIO_OUTPUT, GPIO_PULL_DOWN,
 			 GPIO_2MA, GPIO_ENABLE);
 
-	ret = readl(GPIO_IN_OUT_ADDR(49));
+	ret = readl(GPIO_IN_OUT_ADDR(DIP_SWITCH_GPIO));
 	return ret;
 }
diff --git a/target/msm7627_surf/tools/makefile b/target/msm7627_surf/tools/makefile
index f4fcd56..94357a2 100644
--- a/target/msm7627_surf/tools/makefile
+++ b/target/msm7627_surf/tools/makefile
@@ -38,3 +38,4 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
+	cp -f $(SRC_DIR)/mkheader $(BUILDDIR)/mkheader
diff --git a/target/msm7627a/init.c b/target/msm7627a/init.c
index 27c8ef5..7af1875 100644
--- a/target/msm7627a/init.c
+++ b/target/msm7627a/init.c
@@ -48,6 +48,7 @@
 #define MSM7X25A_SURF	3772
 #define MSM7X25A_FFA	3771
 #define MSM7X27A_EVB	3934
+#define MSM7X27A_QRD3	4005
 
 #define LINUX_MACHTYPE  MSM7X27A_SURF
 
@@ -264,7 +265,10 @@
 				hw_platform = MSM7X27A_FFA;
 			break;
 		case 0xB:
-			hw_platform = MSM7X27A_QRD1;
+			if(target_is_emmc_boot())
+				hw_platform = MSM7X27A_QRD1;
+			else
+				hw_platform = MSM7X27A_QRD3;
 			break;
 		case 0xC:
 			hw_platform = MSM7X27A_EVB;
@@ -418,3 +422,19 @@
 	else
 		return 0;
 }
+
+int machine_is_7x27a_qrd3()
+{
+	if (board_machtype() == MSM7X27A_QRD3)
+		return 1;
+	else
+		return 0;
+}
+
+int machine_is_7x27a_qrd1()
+{
+	if (board_machtype() == MSM7X27A_QRD1)
+		return 1;
+	else
+		return 0;
+}
diff --git a/target/msm7627a/keypad.c b/target/msm7627a/keypad.c
index 386a40a..7244133 100644
--- a/target/msm7627a/keypad.c
+++ b/target/msm7627a/keypad.c
@@ -34,8 +34,6 @@
 #include <dev/ssbi.h>
 #include <dev/gpio_keypad.h>
 
-#define LINUX_MACHTYPE_7x27A_QRD 3756
-
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
 
 /* don't turn this on without updating the ffa support */
@@ -138,10 +136,7 @@
 
 void keypad_init(void)
 {
-	unsigned int mach_id;
-	mach_id = board_machtype();
-
-	if (mach_id == LINUX_MACHTYPE_7x27A_QRD)
+	if (machine_is_7x27a_qrd1() || machine_is_7x27a_qrd3())
 		gpio_keypad_init(&halibut_keypad_info_qrd);
 	else if (machine_is_7x27a_evb())
 		gpio_keypad_init(&halibut_keypad_info_evb);
diff --git a/target/msm7627a/tools/makefile b/target/msm7627a/tools/makefile
index f4fcd56..94357a2 100644
--- a/target/msm7627a/tools/makefile
+++ b/target/msm7627a/tools/makefile
@@ -38,3 +38,4 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
+	cp -f $(SRC_DIR)/mkheader $(BUILDDIR)/mkheader
diff --git a/target/msm7630_surf/init.c b/target/msm7630_surf/init.c
index 3353c55..9ebcc76 100644
--- a/target/msm7630_surf/init.c
+++ b/target/msm7630_surf/init.c
@@ -71,7 +71,7 @@
 static struct ptentry board_part_list[] = {
 	{
 	 .start = 0,
-	 .length = 5 /* In MB */ ,
+	 .length = 10 /* In MB */ ,
 	 .name = "boot",
 	 },
 	{
@@ -106,7 +106,7 @@
 	 },
 	{
 	 .start = DIFF_START_ADDR,
-	 .length = 5 /* In MB */ ,
+	 .length = 10 /* In MB */ ,
 	 .name = "recovery",
 	 },
 };
diff --git a/target/msm7630_surf/tools/makefile b/target/msm7630_surf/tools/makefile
index aedda70..5a33035 100644
--- a/target/msm7630_surf/tools/makefile
+++ b/target/msm7630_surf/tools/makefile
@@ -41,3 +41,4 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
+	cp -f $(SRC_DIR)/mkheader $(BUILDDIR)/mkheader
diff --git a/target/msm8660_surf/tools/makefile b/target/msm8660_surf/tools/makefile
index aedda70..5a33035 100644
--- a/target/msm8660_surf/tools/makefile
+++ b/target/msm8660_surf/tools/makefile
@@ -41,3 +41,4 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
+	cp -f $(SRC_DIR)/mkheader $(BUILDDIR)/mkheader
diff --git a/target/msm8960/tools/makefile b/target/msm8960/tools/makefile
index aedda70..5a33035 100644
--- a/target/msm8960/tools/makefile
+++ b/target/msm8960/tools/makefile
@@ -41,3 +41,4 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
+	cp -f $(SRC_DIR)/mkheader $(BUILDDIR)/mkheader