Merge "platform: msm_shared: Remove addition of nand partitions to the device tree."
diff --git a/platform/msm8226/acpuclock.c b/platform/msm8226/acpuclock.c
index f45a4b1..96e8687 100644
--- a/platform/msm8226/acpuclock.c
+++ b/platform/msm8226/acpuclock.c
@@ -60,9 +60,6 @@
 	iclk = clk_get("usb_iface_clk");
 	cclk = clk_get("usb_core_clk");
 
-	/* Disable USB all clock init */
-	writel(0, USB_BOOT_CLOCK_CTL);
-
 	clk_disable(iclk);
 	clk_disable(cclk);
 
@@ -169,7 +166,118 @@
 	}
 }
 
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+	if (instance == 1)
+	{
+		/* Start the block reset for CE */
+		writel(1, GCC_CE1_BCR);
+
+		udelay(2);
+
+		/* Take CE block out of reset */
+		writel(0, GCC_CE1_BCR);
+
+		udelay(2);
+	}
+	else
+	{
+		dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
+		ASSERT(0);
+	}
+}
+
+void clock_ce_enable(uint8_t instance)
+{
+	int ret;
+	char clk_name[64];
+
+	snprintf(clk_name, 64, "ce%u_src_clk", instance);
+	ret = clk_get_set_enable(clk_name, 100000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_core_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Wait for 48 * #pipes cycles.
+	 * This is necessary as immediately after an access control reset (boot up)
+	 * or a debug re-enable, the Crypto core sequentially clears its internal
+	 * pipe key storage memory. If pipe key initialization writes are attempted
+	 * during this time, they may be overwritten by the internal clearing logic.
+	 */
+	udelay(1);
+}
+
+void clock_ce_disable(uint8_t instance)
+{
+	struct clk *ahb_clk;
+	struct clk *cclk;
+	struct clk *axi_clk;
+	struct clk *src_clk;
+	char clk_name[64];
+
+	snprintf(clk_name, 64, "ce%u_src_clk", instance);
+	src_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+	ahb_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+	axi_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_core_clk", instance);
+	cclk    = clk_get(clk_name);
+
+	clk_disable(ahb_clk);
+	clk_disable(axi_clk);
+	clk_disable(cclk);
+	clk_disable(src_clk);
+
+	/* Some delay for the clocks to stabalize. */
+	udelay(1);
+}
+
 void clock_config_ce(uint8_t instance)
 {
+	/* Need to enable the clock before disabling since the clk_disable()
+	 * has a check to default to nop when the clk_enable() is not called
+	 * on that particular clock.
+	 */
+	clock_ce_enable(instance);
+
+	clock_ce_disable(instance);
+
+	ce_async_reset(instance);
+
+	clock_ce_enable(instance);
+
 }
 
diff --git a/platform/msm8226/include/platform/iomap.h b/platform/msm8226/include/platform/iomap.h
index 9519882..d459984 100644
--- a/platform/msm8226/include/platform/iomap.h
+++ b/platform/msm8226/include/platform/iomap.h
@@ -72,7 +72,6 @@
 #define GCC_WDOG_DEBUG              (CLK_CTL_BASE +  0x00001780)
 
 #define USB_HS_BCR                  (CLK_CTL_BASE + 0x480)
-#define USB_BOOT_CLOCK_CTL          (CLK_CTL_BASE + 0x1A00)
 
 #define SPMI_BASE                   0xFC4C0000
 #define SPMI_GENI_BASE              (SPMI_BASE + 0xA000)
@@ -94,6 +93,14 @@
 #define APCS_GPLL_ENA_VOTE          (CLK_CTL_BASE + 0x1480)
 #define APCS_CLOCK_BRANCH_ENA_VOTE  (CLK_CTL_BASE + 0x1484)
 
+/* CE 1 */
+#define  GCC_CE1_BCR                (CLK_CTL_BASE + 0x1040)
+#define  GCC_CE1_CMD_RCGR           (CLK_CTL_BASE + 0x1050)
+#define  GCC_CE1_CFG_RCGR           (CLK_CTL_BASE + 0x1054)
+#define  GCC_CE1_CBCR               (CLK_CTL_BASE + 0x1044)
+#define  GCC_CE1_AXI_CBCR           (CLK_CTL_BASE + 0x1048)
+#define  GCC_CE1_AHB_CBCR           (CLK_CTL_BASE + 0x104C)
+
 /* SDCC */
 #define SDCC1_BCR                   (CLK_CTL_BASE + 0x4C0) /* block reset */
 #define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x4C4) /* branch control */
diff --git a/platform/msm8226/msm8226-clock.c b/platform/msm8226/msm8226-clock.c
index 9f5818b..ccec8fc 100644
--- a/platform/msm8226/msm8226-clock.c
+++ b/platform/msm8226/msm8226-clock.c
@@ -270,6 +270,59 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F( 50000000,  gpll0,  12,   0,   0),
+	F(100000000,  gpll0,   6,   0,   0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_CE1_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_CE1_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct vote_clk gcc_ce1_clk = {
+	.cbcr_reg      = (uint32_t *) GCC_CE1_CBCR,
+	.vote_reg      = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask       = BIT(5),
+
+	.c = {
+		.dbg_name  = "gcc_ce1_clk",
+		.ops       = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CE1_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(3),
+
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CE1_AXI_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(4),
+
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+
 /* Clock lookup table */
 static struct clk_lookup msm_clocks_8226[] =
 {
@@ -281,6 +334,11 @@
 
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
 	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
+
+	CLK_LOOKUP("ce1_ahb_clk",  gcc_ce1_ahb_clk.c),
+	CLK_LOOKUP("ce1_axi_clk",  gcc_ce1_axi_clk.c),
+	CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
+	CLK_LOOKUP("ce1_src_clk",  ce1_clk_src.c),
 };
 
 void platform_clock_init(void)
diff --git a/platform/msm8960/acpuclock.c b/platform/msm8960/acpuclock.c
index 2681138..0375c15 100644
--- a/platform/msm8960/acpuclock.c
+++ b/platform/msm8960/acpuclock.c
@@ -227,6 +227,9 @@
 	case MMC_CLK_50MHZ: /* Max supported is 48MHZ */
 		rate = 48000000;
 		break;
+	case MMC_CLK_96MHZ:
+		rate = 96000000;
+		break;
 	default:
 		ASSERT(0);
 
diff --git a/platform/msm8974/acpuclock.c b/platform/msm8974/acpuclock.c
index d466f40..9392c69 100644
--- a/platform/msm8974/acpuclock.c
+++ b/platform/msm8974/acpuclock.c
@@ -130,6 +130,10 @@
 	{
 		ret = clk_get_set_enable(clk_name, 50000000, 1);
 	}
+	else if(freq == MMC_CLK_96MHZ)
+	{
+		ret = clk_get_set_enable(clk_name, 100000000, 1);
+	}
 	else
 	{
 		dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
diff --git a/platform/msm8974/gpio.c b/platform/msm8974/gpio.c
index 13097da..d36cd6d 100644
--- a/platform/msm8974/gpio.c
+++ b/platform/msm8974/gpio.c
@@ -89,3 +89,32 @@
 		};
 	}
 }
+
+static void tlmm_set_sdc_pins(struct tlmm_cfgs *cfg)
+{
+	uint32_t reg_val;
+
+	reg_val = readl(SDC1_HDRV_PULL_CTL);
+
+	reg_val &= ~(cfg->mask << cfg->off);
+
+	reg_val |= (cfg->val << cfg->off);
+
+	writel(reg_val, SDC1_HDRV_PULL_CTL);
+}
+
+void tlmm_set_hdrive_ctrl(struct tlmm_cfgs *hdrv_cfgs, uint8_t sz)
+{
+	uint8_t i;
+
+	for (i = 0; i < sz; i++)
+		tlmm_set_sdc_pins(&hdrv_cfgs[i]);
+}
+
+void tlmm_set_pull_ctrl(struct tlmm_cfgs *pull_cfgs, uint8_t sz)
+{
+	uint8_t i;
+
+	for (i = 0; i < sz; i++)
+		tlmm_set_sdc_pins(&pull_cfgs[i]);
+}
diff --git a/platform/msm8974/include/platform/gpio.h b/platform/msm8974/include/platform/gpio.h
index 27d5358..8c4bba8 100644
--- a/platform/msm8974/include/platform/gpio.h
+++ b/platform/msm8974/include/platform/gpio.h
@@ -53,7 +53,36 @@
 #define GPIO_ENABLE     0
 #define GPIO_DISABLE    1
 
+#define TLMM_PULL_MASK  0x3
+#define TLMM_HDRV_MASK  0x7
+
+enum {
+	TLMM_CUR_VAL_16MA = 0x7,
+	TLMM_CUR_VAL_10MA = 0x4,
+} tlmm_drive_config;
+
+enum {
+	TLMM_PULL_UP = 0x3,
+	TLMM_NO_PULL = 0x0,
+} tlmm_pull_values;
+
+enum {
+	SDC1_DATA_HDRV_CTL_OFF = 0,
+	SDC1_CMD_HDRV_CTL_OFF  = 3,
+	SDC1_CLK_HDRV_CTL_OFF  = 6,
+	SDC1_DATA_PULL_CTL_OFF = 9,
+	SDC1_CMD_PULL_CTL_OFF  = 11,
+	SDC1_CLK_PULL_CTL_OFF  = 13,
+} tlmm_drv_ctrl;
+
+struct tlmm_cfgs {
+	uint32_t off;
+	uint8_t val;
+	uint8_t mask;
+};
+
 void gpio_config_uart_dm(uint8_t id);
 void gpio_config_blsp_i2c(uint8_t, uint8_t);
-
+void tlmm_set_hdrive_ctrl(struct tlmm_cfgs *, uint8_t);
+void tlmm_set_pull_ctrl(struct tlmm_cfgs *, uint8_t);
 #endif
diff --git a/platform/msm8974/include/platform/iomap.h b/platform/msm8974/include/platform/iomap.h
index a033ac8..b873889 100644
--- a/platform/msm8974/include/platform/iomap.h
+++ b/platform/msm8974/include/platform/iomap.h
@@ -166,4 +166,6 @@
 #define MDP_BASE                    (0xfd900000)
 #define REG_MDP(off)                (MDP_BASE + (off))
 
+/* DRV strength for sdcc */
+#define SDC1_HDRV_PULL_CTL           (TLMM_BASE_ADDR + 0x00002044)
 #endif
diff --git a/platform/msm_shared/include/mmc.h b/platform/msm_shared/include/mmc.h
index 39b1786..4feaab6 100644
--- a/platform/msm_shared/include/mmc.h
+++ b/platform/msm_shared/include/mmc.h
@@ -81,6 +81,16 @@
 #define MMC_BOOT_BUS_WIDTH_4_BIT          2
 #define MMC_BOOT_BUS_WIDTH_8_BIT          3
 
+/* Bus width support for DDR mode */
+#define MMC_DDR_BUS_WIDTH_4_BIT           6
+#define MMC_DDR_BUS_WIDTH_8_BIT           7
+
+/* DDR mode select */
+#define MMC_MCI_MODE_SELECT               14
+#define MMC_MCI_DDR_MODE_EN               0x3
+
+#define MMC_DEVICE_TYPE                   196
+
 #define MMC_BOOT_MCI_ARGUMENT             MMC_BOOT_MCI_REG(0x008)	/* 32 bits */
 
 #define MMC_BOOT_MCI_CMD                  MMC_BOOT_MCI_REG(0x00C)	/* 16 bits */
@@ -507,11 +517,20 @@
 #define MMC_BOOT_XFER_MULTI_BLOCK        0
 #define MMC_BOOT_XFER_SINGLE_BLOCK       1
 
+/* Capabilities for the mmc host */
+struct mmc_caps {
+	uint8_t ddr_mode;      /* DDR mode support */
+	uint8_t hs200_mode;    /* HS200 mode support */
+	uint8_t bus_width;     /* bus width */
+	uint32_t hs_clk_rate;  /* Clock rate for high speed mode */
+};
+
 struct mmc_host {
 	unsigned int mclk_rate;
 	unsigned int ocr;
 	unsigned int cmd_retry;
 	uint32_t mmc_cont_version;
+	struct mmc_caps caps;
 };
 
 /* MACRO used to evoke regcomp */
@@ -577,6 +596,7 @@
 #define MMC_CLK_25MHZ                 25000000
 #define MMC_CLK_48MHZ                 48000000
 #define MMC_CLK_50MHZ                 49152000
+#define MMC_CLK_96MHZ                 96000000
 
 #define MMC_CLK_ENABLE      1
 #define MMC_CLK_DISABLE     0
@@ -606,4 +626,6 @@
 void mmc_mclk_reg_wr_delay();
 void mmc_boot_mci_clk_enable();
 void mmc_boot_mci_clk_disable();
+uint8_t card_supports_ddr_mode();
+uint8_t card_supports_hs200_mode();
 #endif
diff --git a/platform/msm_shared/mmc.c b/platform/msm_shared/mmc.c
index 5fb0b40..8ed7ec6 100644
--- a/platform/msm_shared/mmc.c
+++ b/platform/msm_shared/mmc.c
@@ -34,6 +34,7 @@
 #include <partition_parser.h>
 #include <platform/iomap.h>
 #include <platform/timer.h>
+#include <bits.h>
 
 #if MMC_BOOT_ADM
 #include "adm.h"
@@ -1292,6 +1293,7 @@
 	} else if (width == MMC_BOOT_BUS_WIDTH_8_BIT) {
 		mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
 	}
+
 	writel(mmc_reg, MMC_BOOT_MCI_CLK);
 
 	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
@@ -1301,6 +1303,104 @@
 }
 
 /*
+ * Function to enable HS200 mode
+ * 1. Set the clock frequency to 100 MHZ
+ * 2. Set the bus width to 4/8 bit SDR as supported byt the target & host
+ * 3. Set the HS_TIMING on ext_csd 185 for the card
+ */
+static uint32_t mmc_set_hs200_mode(struct mmc_host *host,
+								   struct mmc_card *card)
+{
+	uint32_t mmc_ret = MMC_BOOT_E_SUCCESS;
+
+	/* Set Clock @ 100 MHZ */
+	clock_config_mmc(mmc_slot, host->caps.hs_clk_rate);
+	host->mclk_rate = host->caps.hs_clk_rate;
+
+	/* Set 4/8 bit SDR bus width */
+	mmc_ret = mmc_boot_set_bus_width(card, host->caps.bus_width);
+	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+		dprintf(CRITICAL,
+			"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
+			mmc_ret, card->rca);
+			return mmc_ret;
+	}
+
+	/* Setting HS200 in HS_TIMING using EXT_CSD (CMD6) */
+	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
+				      MMC_BOOT_EXT_CMMC_HS_TIMING, 2);
+
+	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+		dprintf(CRITICAL, "Switch cmd returned failure %d\n", __LINE__);
+		return mmc_ret;
+	}
+
+	return mmc_ret;
+}
+
+/*
+ * Function to enable DDR mode
+ * 1. Set the bus width to 8 bit DDR
+ * 1. Set the clock frequency to 100 MHZ
+ * 3. Set DDR mode in mci clk register
+ * 4. Set Widebus enable in mci clock register
+ */
+static uint32_t mmc_set_ddr_mode(struct mmc_host *host,
+								 struct mmc_card *card)
+{
+	uint8_t mmc_ret = MMC_BOOT_E_SUCCESS;
+	uint32_t mmc_reg = 0;
+	uint32_t width = 0;
+
+	switch (host->caps.bus_width) {
+		case MMC_BOOT_BUS_WIDTH_4_BIT:
+			width = MMC_DDR_BUS_WIDTH_4_BIT;
+			break;
+		case MMC_BOOT_BUS_WIDTH_8_BIT:
+			width = MMC_DDR_BUS_WIDTH_8_BIT;
+			break;
+		default:
+			dprintf(CRITICAL, "Invalid bus width, DDR mode is not enabled\n");
+			mmc_ret = MMC_BOOT_E_FAILURE;
+			goto end;
+	};
+
+	/* Set width for 4/8 bit DDR bus width */
+	mmc_ret = mmc_boot_set_bus_width(card, width);
+
+	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+		dprintf(CRITICAL,
+			"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
+			mmc_ret, card->rca);
+		return mmc_ret;
+	}
+
+	/* Bump up the clock frequency */
+	clock_config_mmc(mmc_slot, host->caps.hs_clk_rate);
+	host->mclk_rate = host->caps.hs_clk_rate;
+
+	/* Select DDR mode in mci register */
+	mmc_reg = readl(MMC_BOOT_MCI_CLK);
+	mmc_reg |= (MMC_MCI_DDR_MODE_EN << MMC_MCI_MODE_SELECT);
+
+	writel(mmc_reg, MMC_BOOT_MCI_CLK);
+
+	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
+	mmc_mclk_reg_wr_delay();
+
+	/* Enable wide bus for DDR */
+	mmc_reg = readl(MMC_BOOT_MCI_CLK);
+	mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+	writel(mmc_reg, MMC_BOOT_MCI_CLK);
+
+	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
+	mmc_mclk_reg_wr_delay();
+
+end:
+	return MMC_BOOT_E_SUCCESS;
+}
+
+/*
  * A command to start data read from card. Either a single block or
  * multiple blocks can be read. Multiple blocks read will continuously
  * transfer data from card to host unless requested to stop by issuing
@@ -2206,19 +2306,39 @@
 				mmc_return);
 			return mmc_return;
 		}
-
-		/* enable wide bus */
-		mmc_bus_width = target_mmc_bus_width();
-		mmc_return =
-		    mmc_boot_set_bus_width(card, mmc_bus_width);
-		if (mmc_return != MMC_BOOT_E_SUCCESS) {
-			dprintf(CRITICAL,
-				"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
-				mmc_return, card->rca);
-			return mmc_return;
-		}
 	}
 
+		/* Enable HS200 mode by default if supported,
+		 * else if DDR mode is supported enable it.
+		 * else use default 4/8 bit mode
+		 */
+		if (card_supports_hs200_mode() && host->caps.hs200_mode) {
+			mmc_return = mmc_set_hs200_mode(host, card);
+			if (mmc_return != MMC_BOOT_E_SUCCESS) {
+				dprintf(CRITICAL,
+					"Error No.%d: Failure to set HS200 mode for Card(RCA:%x)\n",
+					mmc_return, card->rca);
+				return mmc_return;
+			}
+		} else if (card_supports_ddr_mode() && host->caps.ddr_mode) {
+			mmc_return = mmc_set_ddr_mode(host, card);
+			if (mmc_return != MMC_BOOT_E_SUCCESS) {
+				dprintf(CRITICAL,
+					"Error No.%d: Failure to set DDR mode for Card(RCA:%x)\n",
+					mmc_return, card->rca);
+				return mmc_return;
+			}
+		} else {
+			mmc_return =
+				mmc_boot_set_bus_width(card, host->caps.bus_width);
+			if (mmc_return != MMC_BOOT_E_SUCCESS) {
+				dprintf(CRITICAL,
+					"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
+					mmc_return, card->rca);
+				return mmc_return;
+			}
+		}
+
 	/* Just checking whether we're in TRAN state after changing speed and bus width */
 	mmc_return = mmc_boot_get_card_status(card, 0, &status);
 	if (mmc_return != MMC_BOOT_E_SUCCESS) {
@@ -2263,6 +2383,9 @@
 	mmc_slot = slot;
 	mmc_boot_mci_base = base;
 
+	/* Get the capabilities for the host/target */
+	target_mmc_caps(&mmc_host);
+
 	/* Initialize necessary data structure and enable/set clock and power */
 	dprintf(SPEW, " Initializing MMC host data structure and clock!\n");
 	mmc_ret = mmc_boot_init(&mmc_host);
@@ -3262,3 +3385,27 @@
 }
 
 #endif
+
+/*
+ * Check if card supports DDR mode
+ */
+uint8_t card_supports_ddr_mode()
+{
+	if (IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 2) ||
+		IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 3))
+		return 1;
+	else
+		return 0;
+}
+
+/*
+ * Check if card suppports HS200 mode
+ */
+uint8_t card_supports_hs200_mode()
+{
+	if (IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 4) ||
+		IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 5))
+		return 1;
+	else
+		return 0;
+}
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index d52b007..6a386ce 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -1246,8 +1246,6 @@
 	uint32_t i;
 	int nand_ret;
 
-	qpic_nand_clock_init();
-
 	nand_base = config->nand_base;
 
 	qpic_bam_init(config);
diff --git a/target/init.c b/target/init.c
index fc5c34a..78a7bad 100644
--- a/target/init.c
+++ b/target/init.c
@@ -119,8 +119,13 @@
 {
 }
 
-/* Default target specific function for mmc bus width */
-__WEAK int target_mmc_bus_width()
+/*
+ * Default target specific function to set the capabilities for the host
+ */
+__WEAK void target_mmc_caps(struct mmc_host *host)
 {
-	return MMC_BOOT_BUS_WIDTH_4_BIT;
+	host->caps.ddr_mode = 0;
+	host->caps.hs200_mode = 0;
+	host->caps.bus_width = MMC_BOOT_BUS_WIDTH_4_BIT;
+	host->caps.hs_clk_rate = MMC_CLK_50MHZ;
 }
diff --git a/target/msm8610/init.c b/target/msm8610/init.c
index 7e962b3..326b26f 100644
--- a/target/msm8610/init.c
+++ b/target/msm8610/init.c
@@ -40,6 +40,7 @@
 #include <baseband.h>
 #include <dev/keys.h>
 #include <pm8x41.h>
+#include <hsusb.h>
 
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
@@ -222,6 +223,30 @@
 	return 0;
 }
 
+void target_usb_stop(void)
+{
+	/* Disable VBUS mimicing in the controller. */
+	ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_CLEAR);
+}
+
+void target_usb_init(void)
+{
+	uint32_t val;
+
+	/* Select and enable external configuration with USB PHY */
+	ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
+
+	/* Enable sess_vld */
+	val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
+	writel(val, USB_GENCONFIG_2);
+
+	/* Enable external vbus configuration in the LINK */
+	val = readl(USB_USBCMD);
+	val |= SESS_VLD_CTRL;
+	writel(val, USB_USBCMD);
+}
+
+
 unsigned board_machtype(void)
 {
 	return 0;
diff --git a/target/msm8960/init.c b/target/msm8960/init.c
index f26f982..2eb3e55 100755
--- a/target/msm8960/init.c
+++ b/target/msm8960/init.c
@@ -515,7 +515,14 @@
 	}
 }
 
-int target_mmc_bus_width()
+
+/*
+ * Function to set the capabilities for the host
+ */
+void target_mmc_caps(struct mmc_host *host)
 {
-	return MMC_BOOT_BUS_WIDTH_8_BIT;
+	host->caps.ddr_mode = 1;
+	host->caps.hs200_mode = 1;
+	host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
+	host->caps.hs_clk_rate = MMC_CLK_96MHZ;
 }
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index b21142f..a3d48b7 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -28,6 +28,7 @@
 
 #include <debug.h>
 #include <platform/iomap.h>
+#include <platform/gpio.h>
 #include <reg.h>
 #include <target.h>
 #include <platform.h>
@@ -47,6 +48,7 @@
 #include <platform/clock.h>
 
 extern  bool target_use_signed_kernel(void);
+static void set_sdc_power_ctrl();
 
 static unsigned int target_id;
 static uint32_t pmic_ver;
@@ -177,6 +179,12 @@
 	dprintf(INFO, "Display Init: Done\n");
 #endif
 
+	/*
+	 * Set drive strength & pull ctrl for
+	 * emmc
+	 */
+	set_sdc_power_ctrl();
+
 	/* Trying Slot 1*/
 	slot = 1;
 	base_addr = mmc_sdc_base[slot - 1];
@@ -435,3 +443,37 @@
 	dprintf(CRITICAL, "Shutdown failed\n");
 
 }
+
+/*
+ * Function to set the capabilities for the host
+ */
+void target_mmc_caps(struct mmc_host *host)
+{
+	host->caps.ddr_mode = 1;
+	host->caps.hs200_mode = 1;
+	host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
+	host->caps.hs_clk_rate = MMC_CLK_96MHZ;
+}
+
+static void set_sdc_power_ctrl()
+{
+	/* Drive strength configs for sdc pins */
+	struct tlmm_cfgs sdc1_hdrv_cfg[] =
+	{
+		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK },
+		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
+		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
+	};
+
+	/* Pull configs for sdc pins */
+	struct tlmm_cfgs sdc1_pull_cfg[] =
+	{
+		{ SDC1_CLK_PULL_CTL_OFF,  TLMM_NO_PULL, TLMM_PULL_MASK },
+		{ SDC1_CMD_PULL_CTL_OFF,  TLMM_PULL_UP, TLMM_PULL_MASK },
+		{ SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
+	};
+
+	/* Set the drive strength & pull control values */
+	tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
+	tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
+}