Merge "target: msm8226: Perform crypto cleanup."
diff --git a/app/aboot/fastboot.c b/app/aboot/fastboot.c
index 67bd760..b4e4922 100644
--- a/app/aboot/fastboot.c
+++ b/app/aboot/fastboot.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -302,24 +302,38 @@
 static int usb_write(void *buf, unsigned len)
 {
 	int r;
+	uint32_t xfer;
+	unsigned char *_buf = buf;
+	int count = 0;
 
 	if (fastboot_state == STATE_ERROR)
 		goto oops;
 
-	req->buf = PA((addr_t)buf);
-	req->length = len;
-	req->complete = req_complete;
-	r = udc_request_queue(in, req);
-	if (r < 0) {
-		dprintf(INFO, "usb_write() queue failed\n");
-		goto oops;
+	while (len > 0) {
+		xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
+		req->buf = PA((addr_t)_buf);
+		req->length = xfer;
+		req->complete = req_complete;
+		r = udc_request_queue(in, req);
+		if (r < 0) {
+			dprintf(INFO, "usb_write() queue failed\n");
+			goto oops;
+		}
+		event_wait(&txn_done);
+		if (txn_status < 0) {
+			dprintf(INFO, "usb_write() transaction failed\n");
+			goto oops;
+		}
+
+		count += req->length;
+		_buf += req->length;
+		len -= req->length;
+
+		/* short transfer? */
+		if (req->length != xfer) break;
 	}
-	event_wait(&txn_done);
-	if (txn_status < 0) {
-		dprintf(INFO, "usb_write() transaction failed\n");
-		goto oops;
-	}
-	return req->length;
+
+	return count;
 
 oops:
 	fastboot_state = STATE_ERROR;
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 8a5eaff..512657f 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -206,4 +206,5 @@
 void pm8x41_enable_mpp(struct pm8x41_mpp *mpp, enum mpp_en_ctl enable);
 uint8_t pm8x41_get_is_cold_boot();
 void pm8x41_diff_clock_ctrl(uint8_t enable);
+void pm8x41_clear_pmic_watchdog(void);
 #endif
diff --git a/dev/pmic/pm8x41/include/pm8x41_hw.h b/dev/pmic/pm8x41/include/pm8x41_hw.h
index 672514a..a1c2e6d 100644
--- a/dev/pmic/pm8x41/include/pm8x41_hw.h
+++ b/dev/pmic/pm8x41/include/pm8x41_hw.h
@@ -78,6 +78,7 @@
 #define PON_RESIN_N_RESET_S2_CTL              0x846  /* bit 7: S2_RESET_EN, bit 0:3 : RESET_TYPE  */
 #define PON_PS_HOLD_RESET_CTL                 0x85A  /* bit 7: S2_RESET_EN, bit 0:3 : RESET_TYPE  */
 #define PON_PS_HOLD_RESET_CTL2                0x85B
+#define PMIC_WD_RESET_S2_CTL2                 0x857
 
 /* PON Peripheral register bit values */
 #define RESIN_ON_INT_BIT                      1
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 2c14d3b..035c442 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -474,3 +474,8 @@
 
 	return batt_is_broken;
 }
+
+void pm8x41_clear_pmic_watchdog(void)
+{
+	pm8x41_reg_write(PMIC_WD_RESET_S2_CTL2, 0x0);
+}
diff --git a/include/dev/udc.h b/include/dev/udc.h
index 0dd1f86..aa1aadd 100644
--- a/include/dev/udc.h
+++ b/include/dev/udc.h
@@ -34,7 +34,7 @@
 struct udc_request {
 	void *buf;
 	unsigned length;
-	void (*complete)(struct udc_request *req, unsigned actual, int status);
+	void (*complete)();
 	void *context;
 };
 
diff --git a/platform/msm8974/acpuclock.c b/platform/msm8974/acpuclock.c
index da1b024..d7a6210 100644
--- a/platform/msm8974/acpuclock.c
+++ b/platform/msm8974/acpuclock.c
@@ -177,6 +177,12 @@
 	int ret = 0;
 	char clk_name[64];
 
+	/* CDC clocks are not supported for 8974 v1 & v2
+	 * only pro msm's support it
+	 */
+	if (platform_is_8974())
+		return;
+
 	snprintf(clk_name, sizeof(clk_name), "gcc_sdcc%u_cdccal_sleep_clk", interface);
 	ret = clk_get_set_enable(clk_name, 0 , 1);
 	if (ret)
diff --git a/platform/msm_shared/hsusb.c b/platform/msm_shared/hsusb.c
index 02a15db..a739f9b 100644
--- a/platform/msm_shared/hsusb.c
+++ b/platform/msm_shared/hsusb.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -476,7 +476,7 @@
 static struct udc_request *ep0req;
 
 static void
-ep0_setup_ack_complete(struct udc_endpoint *ep, struct usb_request *req)
+ep0_setup_ack_complete()
 {
 	uint32_t mode;
 
diff --git a/platform/msm_shared/image_verify.c b/platform/msm_shared/image_verify.c
index edca3bc..0d280f2 100644
--- a/platform/msm_shared/image_verify.c
+++ b/platform/msm_shared/image_verify.c
@@ -115,10 +115,12 @@
 
 	/*
 	 * Decrypt the pre-calculated expected image hash.
+	 * Return value, ret should be equal to hash_size. Otherwise it means a failure. With this check
+	 * we avoid a potential vulnerability due to trailing data placed at the end of digest.
 	 */
 	ret = image_decrypt_signature(signature_ptr, plain_text);
-	if (ret == -1) {
-		dprintf(CRITICAL, "ERROR: Image Invalid! Decryption failed!\n");
+	if (ret != hash_size) {
+		dprintf(CRITICAL, "ERROR: Image Invalid! signature check failed! ret %d\n", ret);
 		goto cleanup;
 	}
 
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index 1eb9745..d704d8c 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.h
@@ -294,6 +294,7 @@
 	uint32_t pwrctl_base;  /* Base address for power control registers */
 	uint16_t bus_width;    /* Bus width used */
 	uint32_t max_clk_rate; /* Max clock rate supported */
+	uint8_t hs400_support; /* SDHC HS400 mode supported or not */
 };
 
 /* mmc device structure */
diff --git a/platform/msm_shared/include/mmc_wrapper.h b/platform/msm_shared/include/mmc_wrapper.h
index 6d8f980..79f0442 100644
--- a/platform/msm_shared/include/mmc_wrapper.h
+++ b/platform/msm_shared/include/mmc_wrapper.h
@@ -30,7 +30,7 @@
 #define __MMC_WRAPPER_H__
 
 #include <mmc_sdhci.h>
-
+#define BOARD_KERNEL_PAGESIZE                2048
 /* Wrapper APIs */
 
 struct mmc_device *get_mmc_device();
@@ -42,4 +42,5 @@
 uint64_t mmc_get_device_capacity(void);
 uint32_t mmc_erase_card(uint64_t addr, uint64_t len);
 uint32_t mmc_get_device_blocksize();
+uint32_t mmc_page_size();
 #endif
diff --git a/platform/msm_shared/include/sdhci.h b/platform/msm_shared/include/sdhci.h
index a14b3b5..a243e84 100644
--- a/platform/msm_shared/include/sdhci.h
+++ b/platform/msm_shared/include/sdhci.h
@@ -33,6 +33,14 @@
 #include <bits.h>
 #include <kernel/event.h>
 
+//#define DEBUG_SDHCI
+
+#ifdef DEBUG_SDHCI
+#define DBG(...) dprintf(ALWAYS, __VA_ARGS__)
+#else
+#define DBG(...)
+#endif
+
 /*
  * Capabilities for the host controller
  * These values are read from the capabilities
@@ -123,7 +131,7 @@
 /*
  * Helper macros for writing byte, word & long registers
  */
-#define REG_READ8(host, a)                        readb(host->base + a);
+#define REG_READ8(host, a)                        readb(host->base + a)
 #define REG_WRITE8(host, v, a)                    writeb(v, (host->base + a))
 
 #define REG_READ32(host, a)                       readl(host->base + a)
@@ -155,9 +163,11 @@
 #define SDHCI_ERR_INT_STS_EN_REG                  (0x036)
 #define SDHCI_NRML_INT_SIG_EN_REG                 (0x038)
 #define SDHCI_ERR_INT_SIG_EN_REG                  (0x03A)
+#define SDHCI_AUTO_CMD_ERR                        (0x03C)
 #define SDHCI_HOST_CTRL2_REG                      (0x03E)
 #define SDHCI_CAPS_REG1                           (0x040)
 #define SDHCI_CAPS_REG2                           (0x044)
+#define SDHCI_ADM_ERR_REG                         (0x054)
 #define SDHCI_ADM_ADDR_REG                        (0x058)
 
 /*
diff --git a/platform/msm_shared/include/sdhci_msm.h b/platform/msm_shared/include/sdhci_msm.h
index a075460..180f23a 100644
--- a/platform/msm_shared/include/sdhci_msm.h
+++ b/platform/msm_shared/include/sdhci_msm.h
@@ -76,7 +76,8 @@
 #define CDC_SWITCH_BYPASS_OFF                     BIT(0)
 #define CDC_SWITCH_RC_EN                          BIT(1)
 #define START_CDC_TRAFFIC                         BIT(6)
-#define FW_CLK_SW_RST_DIS                         BIT(13)
+#define FF_CLK_SW_RST_DIS_START                   0xD
+#define FF_CLK_SW_RST_DIS_WIDTH                   0x1
 #define CDC_SW_TRIGGER_FULL_CALIB                 BIT(16)
 #define CDC_HW_AUTO_CAL_EN                        BIT(17)
 #define CDC_TIMER_EN                              BIT(16)
@@ -102,6 +103,9 @@
 #define CORE_VERSION_MAJOR_MASK                   0xF0000000
 #define CORE_VERSION_MAJOR_SHIFT                  0x1C
 
+#define SDHCI_DLL_TIMEOUT                         50
+#define CDC_STATUS_TIMEOUT                        50
+
 struct sdhci_msm_data
 {
 	uint32_t pwrctl_base;
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index 3fa2e28..09b5537 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -416,7 +416,7 @@
 }
 
 int mdss_dsi_host_init(struct mipi_dsi_panel_config *pinfo, uint32_t
-		broadcast)
+		dual_dsi, uint32_t broadcast)
 {
 	uint8_t DMA_STREAM1 = 0;	// for mdp display processor path
 	uint8_t EMBED_MODE1 = 1;	// from frame buffer
@@ -450,7 +450,7 @@
 	lane_swap = pinfo->lane_swap;
 	timing_ctl = ((pinfo->t_clk_post << 8) | pinfo->t_clk_pre);
 
-	if (broadcast) {
+	if (dual_dsi) {
 		writel(0x0001, MIPI_DSI1_BASE + SOFT_RESET);
 		writel(0x0000, MIPI_DSI1_BASE + SOFT_RESET);
 
@@ -1029,7 +1029,8 @@
 	if (pinfo->mipi.dual_dsi)
 		mdss_dsi_phy_init(&mipi_pinfo, MIPI_DSI1_BASE);
 
-	ret = mdss_dsi_host_init(&mipi_pinfo, pinfo->mipi.broadcast);
+	ret = mdss_dsi_host_init(&mipi_pinfo, pinfo->mipi.dual_dsi,
+						pinfo->mipi.broadcast);
 	if (ret) {
 		dprintf(CRITICAL, "dsi host init error\n");
 		goto error;
diff --git a/platform/msm_shared/mipi_dsi_phy.c b/platform/msm_shared/mipi_dsi_phy.c
index 62cabf0..834b335 100644
--- a/platform/msm_shared/mipi_dsi_phy.c
+++ b/platform/msm_shared/mipi_dsi_phy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -199,9 +199,9 @@
 
 void mdss_dsi_uniphy_pll_lock_detect_setting(uint32_t ctl_base)
 {
-	writel(0x04, ctl_base + 0x0264); /* LKDetect CFG2 */
+	writel(0x0c, ctl_base + 0x0264); /* LKDetect CFG2 */
 	udelay(100);
-	writel(0x05, ctl_base + 0x0264); /* LKDetect CFG2 */
+	writel(0x0d, ctl_base + 0x0264); /* LKDetect CFG2 */
 	mdelay(1);
 }
 
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index 0883c53..0d0b361 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -822,6 +822,8 @@
 {
 	uint32_t mmc_ret = 0;
 
+	DBG("\n Enabling HS200 Mode Start\n");
+
 	/* Set 4/8 bit SDR bus width */
 	mmc_ret = mmc_set_bus_width(host, card, width);
 	if (mmc_ret) {
@@ -844,9 +846,15 @@
 	/* Run the clock @ 400 Mhz */
 	if (host->caps.hs400_support && mmc_card_supports_hs400_mode(card))
 	{
-		clock_config_mmc(host->msm_host->slot, SDHCI_CLK_400MHZ);
 		/* Save the timing value, before changing the clock */
 		MMC_SAVE_TIMING(host, MMC_HS400_TIMING);
+		/*
+		* Set the MCI_CLK divider before changing the sdcc core
+		* core clk to ensure card receives no more than 200 MHZ
+		* clock frequency
+		*/
+		sdhci_msm_set_mci_clk(host);
+		clock_config_mmc(host->msm_host->slot, SDHCI_CLK_400MHZ);
 	}
 	else
 	{
@@ -858,6 +866,8 @@
 	if ((mmc_ret = sdhci_msm_execute_tuning(host, width)))
 		dprintf(CRITICAL, "Tuning for hs200 failed\n");
 
+	DBG("\n Enabling HS200 Mode Done\n");
+
 	return mmc_ret;
 }
 
@@ -871,6 +881,8 @@
 {
 	uint8_t mmc_ret = 0;
 
+	DBG("\n Enabling DDR Mode Start\n");
+
 	/* Set width for 8 bit DDR mode by default */
 	mmc_ret = mmc_set_bus_width(host, card, DATA_DDR_BUS_WIDTH_8BIT);
 
@@ -886,6 +898,8 @@
 	/* Set the DDR mode in controller */
 	sdhci_set_uhs_mode(host, SDHCI_DDR50_MODE);
 
+	DBG("\n Enabling DDR Mode Done\n");
+
 	return 0;
 }
 
@@ -941,6 +955,7 @@
 	 * 4. Enable HS400 mode & execute tuning
 	 */
 
+	DBG("\n Enabling HS400 Mode Start\n");
 	/* HS400 mode is supported only in DDR 8-bit */
 	if (width != DATA_BUS_WIDTH_8BIT)
 	{
@@ -993,11 +1008,17 @@
 	/* Save the timing value, before changing the clock */
 	MMC_SAVE_TIMING(host, MMC_HS400_TIMING);
 	sdhci_set_uhs_mode(host, SDHCI_SDR104_MODE);
+	/*
+	* Enable HS400 mode
+	*/
+	sdhci_msm_set_mci_clk(host);
 
 	/* 7. Execute Tuning for hs400 mode */
 	if ((mmc_ret = sdhci_msm_execute_tuning(host, width)))
 		dprintf(CRITICAL, "Tuning for hs400 failed\n");
 
+	DBG("\n Enabling HS400 Mode Done\n");
+
 	return mmc_ret;
 }
 
@@ -1025,6 +1046,7 @@
 
 	host->base = cfg->sdhc_base;
 	host->sdhc_event = &sdhc_event;
+	host->caps.hs400_support = cfg->hs400_support;
 
 	data = (struct sdhci_msm_data *) malloc(sizeof(struct sdhci_msm_data));
 	ASSERT(data);
@@ -1041,6 +1063,12 @@
 
 	clock_config_mmc(cfg->slot, cfg->max_clk_rate);
 
+	/* Configure the CDC clocks needed for emmc storage
+	 * we use slot '1' for emmc
+	 */
+	if (cfg->slot == 1)
+		clock_config_cdc(cfg->slot);
+
 	/*
 	 * MSM specific sdhc init
 	 */
@@ -1690,7 +1718,16 @@
 	else
 		cmd.cmd_index = CMD18_READ_MULTIPLE_BLOCK;
 
-	cmd.argument = blk_addr;
+	/*
+	 * Standard emmc cards use byte mode addressing
+	 * convert the block address to byte address before
+	 * sending the command
+	 */
+	if (card->type == MMC_TYPE_STD_MMC)
+		cmd.argument = blk_addr * card->block_size;
+	else
+		cmd.argument = blk_addr;
+
 	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
 	cmd.resp_type = SDHCI_CMD_RESP_R1;
 	cmd.trans_mode = SDHCI_MMC_READ;
@@ -1762,7 +1799,16 @@
 	else
 		cmd.cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
 
-	cmd.argument = blk_addr;
+	/*
+	 * Standard emmc cards use byte mode addressing
+	 * convert the block address to byte address before
+	 * sending the command
+	 */
+	if (card->type == MMC_TYPE_STD_MMC)
+		cmd.argument = blk_addr * card->block_size;
+	else
+		cmd.argument = blk_addr;
+
 	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
 	cmd.resp_type = SDHCI_CMD_RESP_R1;
 	cmd.trans_mode = SDHCI_MMC_WRITE;
@@ -1824,7 +1870,15 @@
 	else
 		cmd.cmd_index = CMD32_ERASE_WR_BLK_START;
 
-	cmd.argument = erase_start;
+	/*
+	 * Standard emmc cards use byte mode addressing
+	 * convert the block address to byte address before
+	 * sending the command
+	 */
+	if (card->type == MMC_TYPE_STD_MMC)
+		cmd.argument = erase_start * card->block_size;
+	else
+		cmd.argument = erase_start;
 	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
 	cmd.resp_type = SDHCI_CMD_RESP_R1;
 
@@ -1859,7 +1913,15 @@
 	else
 		cmd.cmd_index = CMD33_ERASE_WR_BLK_END;
 
-	cmd.argument = erase_end;
+	/*
+	 * Standard emmc cards use byte mode addressing
+	 * convert the block address to byte address before
+	 * sending the command
+	 */
+	if (card->type == MMC_TYPE_STD_MMC)
+		cmd.argument = erase_end * card->block_size;
+	else
+		cmd.argument = erase_end;
 	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
 	cmd.resp_type = SDHCI_CMD_RESP_R1;
 
diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index bfbdf95..d516738 100644
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -337,3 +337,14 @@
 
 	return card->block_size;
 }
+
+/*
+ * Function: storage page size
+ * Arg     : None
+ * Return  : Returns the page size for the card
+ * Flow    : Get the page size for storage
+ */
+uint32_t mmc_page_size()
+{
+	return BOARD_KERNEL_PAGESIZE;
+}
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 632de53..98f1da0 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -172,7 +172,8 @@
             $(LOCAL_DIR)/qpic_nand.o \
             $(LOCAL_DIR)/dev_tree.o \
             $(LOCAL_DIR)/scm.o \
-            $(LOCAL_DIR)/gpio.o
+            $(LOCAL_DIR)/gpio.o \
+            $(LOCAL_DIR)/shutdown_detect.o
 endif
 
 ifeq ($(PLATFORM),apq8084)
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index 547f4ec..cbcabff 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -39,6 +39,57 @@
 #include <sdhci.h>
 #include <sdhci_msm.h>
 
+static void sdhci_dumpregs(struct sdhci_host *host)
+{
+	DBG("****************** SDHC REG DUMP START ********************\n");
+
+	DBG("Version:      0x%08x\n", REG_READ32(host, SDHCI_ARG2_REG));
+	DBG("Arg2:         0x%08x\t Blk Cnt:      0x%08x\n",
+							REG_READ32(host, SDHCI_ARG2_REG),
+							REG_READ16(host, SDHCI_BLK_CNT_REG));
+	DBG("Arg1:         0x%08x\t Blk Sz :      0x%08x\n",
+							REG_READ32(host, SDHCI_ARGUMENT_REG),
+							REG_READ16(host, SDHCI_BLKSZ_REG));
+	DBG("Command:      0x%08x\t Trans mode:   0x%08x\n",
+							REG_READ16(host, SDHCI_CMD_REG),
+							REG_READ16(host, SDHCI_TRANS_MODE_REG));
+	DBG("Resp0:        0x%08x\t Resp1:        0x%08x\n",
+							REG_READ32(host, SDHCI_RESP_REG),
+							REG_READ32(host, SDHCI_RESP_REG + 0x4));
+	DBG("Resp2:        0x%08x\t Resp3:        0x%08x\n",
+							REG_READ32(host, SDHCI_RESP_REG + 0x8),
+							REG_READ32(host, SDHCI_RESP_REG + 0xC));
+	DBG("Prsnt State:  0x%08x\t Host Ctrl1:   0x%08x\n",
+							REG_READ32(host, SDHCI_PRESENT_STATE_REG),
+							REG_READ8(host, SDHCI_HOST_CTRL1_REG));
+	DBG("Timeout ctrl: 0x%08x\t Power Ctrl:   0x%08x\n",
+							REG_READ8(host, SDHCI_TIMEOUT_REG),
+							REG_READ8(host, SDHCI_PWR_CTRL_REG));
+	DBG("Error stat:   0x%08x\t Int Status:   0x%08x\n",
+							REG_READ32(host, SDHCI_ERR_INT_STS_REG),
+							REG_READ32(host, SDHCI_NRML_INT_STS_REG));
+	DBG("Host Ctrl2:   0x%08x\t Clock ctrl:   0x%08x\n",
+							REG_READ32(host, SDHCI_HOST_CTRL2_REG),
+							REG_READ32(host, SDHCI_CLK_CTRL_REG));
+	DBG("Caps1:        0x%08x\t Caps2:        0x%08x\n",
+							REG_READ32(host, SDHCI_CAPS_REG1),
+							REG_READ32(host, SDHCI_CAPS_REG1));
+	DBG("Adma Err:     0x%08x\t Auto Cmd err: 0x%08x\n",
+							REG_READ8(host, SDHCI_ADM_ERR_REG),
+							REG_READ16(host, SDHCI_AUTO_CMD_ERR));
+	DBG("Adma addr1:   0x%08x\t Adma addr2:   0x%08x\n",
+							REG_READ32(host, SDHCI_ADM_ADDR_REG),
+							REG_READ32(host, SDHCI_ADM_ADDR_REG + 0x4));
+
+	DBG("****************** SDHC REG DUMP END ********************\n");
+
+	DBG("************* SDHC VENDOR REG DUMPS START ***************\n");
+	DBG("SDCC_DLL_CONFIG_REG:       0x%08x\n", REG_READ32(host, SDCC_DLL_CONFIG_REG));
+	DBG("SDCC_VENDOR_SPECIFIC_FUNC: 0x%08x\n", REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC));
+	DBG("SDCC_REG_DLL_STATUS:       0x%08x\n", REG_READ32(host, SDCC_REG_DLL_STATUS));
+	DBG("************* SDHC VENDOR REG DUMPS END   ***************\n");
+}
+
 /*
  * Function: sdhci reset
  * Arg     : Host structure & mask to write to reset register
@@ -138,6 +189,8 @@
 
 	host->cur_clk_rate = clk;
 
+	DBG("\n %s: clock_rate: %d clock_div:0x%08x\n", __func__, clk, div);
+
 	return 0;
 }
 
@@ -203,6 +256,8 @@
 
 	voltage |= SDHCI_BUS_PWR_EN;
 
+	DBG("\n %s: voltage: 0x%02x\n", __func__, voltage);
+
 	REG_WRITE8(host, voltage, SDHCI_PWR_CTRL_REG);
 
 }
@@ -264,13 +319,6 @@
 
 	REG_WRITE16(host, ctrl, SDHCI_HOST_CTRL2_REG);
 
-	/*
-	 * SDHC spec does not have matching UHS mode
-	 * So we use Vendor specific registers to enable
-	 * HS400 mode
-	 */
-	sdhci_msm_set_mci_clk(host);
-
 	/* Run the clock back */
 	sdhci_clk_supply(host, clk_val);
 }
@@ -314,6 +362,8 @@
 			return 1;
 	}
 
+	DBG("\n %s: bus width:0x%04x\n", __func__, width);
+
 	REG_WRITE8(host, (reg | width), SDHCI_HOST_CTRL1_REG);
 
 	return 0;
@@ -392,6 +442,19 @@
 		if (int_status == SDHCI_INT_STS_CMD_COMPLETE)
 			break;
 
+		/*
+		 * If Tuning is in progress ignore cmd crc & cmd end bit errors
+		 */
+		if (host->tuning_in_progress)
+		{
+			err_status = REG_READ16(host, SDHCI_ERR_INT_STS_REG);
+			if ((err_status & SDHCI_CMD_CRC_MASK) || (err_status & SDHCI_DAT_END_BIT_MASK))
+			{
+				sdhci_reset(host, (SOFT_RESET_CMD | SOFT_RESET_DATA));
+				return 0;
+			}
+		}
+
 		retry++;
 		udelay(500);
 		if (retry == SDHCI_MAX_CMD_RETRY) {
@@ -493,8 +556,9 @@
 		}
 		else if (sdhci_cmd_err_status(host))
 		{
-			dprintf(CRITICAL, "Error: Command completed with errors\n");
 			ret = 1;
+			/* Dump sdhc registers on error */
+			sdhci_dumpregs(host);
 		}
 		/* Reset Command & Dat lines on error */
 		need_reset = 1;
@@ -535,7 +599,8 @@
 		sg_list[0].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA
 							  | SDHCI_ADMA_TRANS_END;
 
-		arch_clean_invalidate_cache_range((addr_t)sg_list, sizeof(struct desc_entry));
+		sg_len = 1;
+		table_len = sizeof(struct desc_entry);
 	} else {
 		/* Calculate the number of entries in desc table */
 		sg_len = len / SDHCI_ADMA_DESC_LINE_SZ;
@@ -588,6 +653,12 @@
 
 	arch_clean_invalidate_cache_range((addr_t)sg_list, table_len);
 
+	for (i = 0; i < sg_len; i++)
+	{
+		DBG("\n %s: sg_list: addr: 0x%08x len: 0x%04x attr: 0x%04x\n", __func__, sg_list[i].addr,
+			(sg_list[i].len ? sg_list[i].len : SDHCI_ADMA_DESC_LINE_SZ), sg_list[i].tran_att);
+	}
+
 	return sg_list;
 }
 
@@ -662,6 +733,9 @@
 	uint32_t flags;
 	struct desc_entry *sg_list = NULL;
 
+	DBG("\n %s: START: cmd:0x%04d, arg:0x%08x, resp_type:0x%04x, data_present:%d\n",
+				__func__, cmd->cmd_index, cmd->argument, cmd->resp_type, cmd->data_present);
+
 	if (cmd->data_present)
 		ASSERT(cmd->data.data_ptr);
 
@@ -731,6 +805,23 @@
 	flags |= (cmd->data_present << SDHCI_CMD_DATA_PRESENT_BIT);
 	flags |= (cmd->cmd_type << SDHCI_CMD_CMD_TYPE_BIT);
 
+	/* Enable Command CRC & Index check for commands with response
+	 * R1, R6, R7 & R1B. Also only CRC check for R2 response
+	 */
+	switch(cmd->resp_type) {
+		case SDHCI_CMD_RESP_R1:
+		case SDHCI_CMD_RESP_R6:
+		case SDHCI_CMD_RESP_R7:
+		case SDHCI_CMD_RESP_R1B:
+			flags |= (1 << SDHCI_CMD_CRC_CHECK_BIT) | (1 << SDHCI_CMD_IDX_CHECK_BIT);
+			break;
+		case SDHCI_CMD_RESP_R2:
+			flags |= (1 << SDHCI_CMD_CRC_CHECK_BIT);
+			break;
+		default:
+			break;
+	};
+
 	/* Set the timeout value */
 	REG_WRITE8(host, SDHCI_CMD_TIMEOUT, SDHCI_TIMEOUT_REG);
 
@@ -781,6 +872,9 @@
 	if (sg_list)
 		free(sg_list);
 
+	DBG("\n %s: END: cmd:%04d, arg:0x%08x, resp:0x%08x 0x%08x 0x%08x 0x%08x\n",
+				__func__, cmd->cmd_index, cmd->argument, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
+
 	return 0;
 }
 
@@ -805,6 +899,9 @@
 	caps[0] = REG_READ32(host, SDHCI_CAPS_REG1);
 	caps[1] = REG_READ32(host, SDHCI_CAPS_REG2);
 
+
+	DBG("\n %s: Host capability: cap1:0x%08x, cap2: 0x%08x\n", __func__, caps[0], caps[1]);
+
 	host->caps.base_clk_rate = (caps[0] & SDHCI_CLK_RATE_MASK) >> SDHCI_CLK_RATE_BIT;
 	host->caps.base_clk_rate *= 1000000;
 
diff --git a/platform/msm_shared/sdhci_msm.c b/platform/msm_shared/sdhci_msm.c
index 8677dbe..25b47e4 100644
--- a/platform/msm_shared/sdhci_msm.c
+++ b/platform/msm_shared/sdhci_msm.c
@@ -151,6 +151,9 @@
 	/* Enable sdhc mode */
 	writel(SDHCI_HC_MODE_EN, (config->pwrctl_base + SDCC_MCI_HC_MODE));
 
+	/* Set the FF_CLK_SW_RST_DIS to 1 */
+	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), FF_CLK_SW_RST_DIS_START, FF_CLK_SW_RST_DIS_WIDTH, 1);
+
 	/*
 	 * Reset the controller
 	 */
@@ -247,13 +250,16 @@
 	else if (host->cur_clk_rate <= 200000000)
 		reg_val = 0x7;
 
+	DBG("\n %s: DLL freq: 0x%08x\n", __func__, reg_val);
+
 	REG_RMW32(host, SDCC_DLL_CONFIG_REG, SDCC_DLL_CONFIG_MCLK_START, SDCC_DLL_CONFIG_MCLK_WIDTH, reg_val);
 }
 
 /* Initialize DLL (Programmable Delay Line) */
-static void sdhci_msm_init_dll(struct sdhci_host *host)
+static uint32_t sdhci_msm_init_dll(struct sdhci_host *host)
 {
 	uint32_t pwr_save = 0;
+	uint32_t timeout = SDHCI_DLL_TIMEOUT;
 
 	pwr_save = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & SDCC_DLL_PWR_SAVE_EN;
 
@@ -276,17 +282,31 @@
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_EN), SDCC_DLL_CONFIG_REG);
 	/* Write 1 to CLK_OUT_EN */
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG);
-	/* Wait for DLL_LOCK in DLL_STATUS register */
+	/* Wait for DLL_LOCK in DLL_STATUS register, wait time 50us */
 	while(!((REG_READ32(host, SDCC_REG_DLL_STATUS)) & SDCC_DLL_LOCK_STAT));
+	{
+		udelay(1);
+		timeout--;
+		if (!timeout)
+		{
+			dprintf(CRITICAL, "%s: Failed to get DLL lock: 0x%08x\n", __func__, REG_READ32(host, SDCC_REG_DLL_STATUS));
+			return 1;
+		}
+	}
+
 	/* Set the powersave back on */
 	if (pwr_save)
 		REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC);
+
+	return 0;
 }
 
 /* Configure DLL with delay value based on 'phase' */
-static void sdhci_msm_config_dll(struct sdhci_host *host, uint32_t phase)
+static uint32_t sdhci_msm_config_dll(struct sdhci_host *host, uint32_t phase)
 {
 	uint32_t core_cfg = 0;
+	uint32_t timeout = SDHCI_DLL_TIMEOUT;
+
 	/* Gray code values from SWI */
 	uint32_t gray_code [] = { 0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, 0xC, 0xD, 0xF, 0xE, 0xA, 0xB, 0x9, 0x8 };
 
@@ -304,8 +324,17 @@
 
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG);
 
-	/* Wait until CLK_OUT_EN is 1 */
-	while(!(REG_READ32(host, SDCC_DLL_CONFIG_REG) & SDCC_DLL_CLK_OUT_EN));
+	/* Wait until CLK_OUT_EN is 1, wait time 50us */
+	while(!(REG_READ32(host, SDCC_DLL_CONFIG_REG) & SDCC_DLL_CLK_OUT_EN))
+	{
+		timeout--;
+		udelay(1);
+		if (!timeout)
+		{
+			dprintf(CRITICAL, "%s: clk_out_en timed out: %08x\n", __func__, REG_READ32(host, SDCC_DLL_CONFIG_REG));
+			return 1;
+		}
+	}
 
 	core_cfg = REG_READ32(host, SDCC_DLL_CONFIG_REG);
 
@@ -314,7 +343,7 @@
 
 	REG_WRITE32(host, core_cfg, SDCC_DLL_CONFIG_REG);
 
-	return;
+	return 0;
 }
 
 /*
@@ -427,17 +456,15 @@
 	uint32_t timeout;
 	uint32_t cdc_err;
 
+	DBG("\n CDCLP533 Calibration Start\n");
+
 	/* Reset & Initialize the DLL block */
-	sdhci_msm_init_dll(host);
+	if (sdhci_msm_init_dll(host))
+		return 1;
 
 	/* Write the save phase */
-	sdhci_msm_config_dll(host, host->msm_host->saved_phase);
-
-	/* Configure the clocks needed for CDC */
-	clock_config_cdc(host->msm_host->slot);
-
-	/* Set the FF_CLK_SW_RST_DIS to 1 */
-	REG_WRITE32(host, (REG_READ32(host, SDCC_MCI_HC_MODE) | FW_CLK_SW_RST_DIS), SDCC_MCI_HC_MODE);
+	if (sdhci_msm_config_dll(host, host->msm_host->saved_phase))
+		return 1;
 
 	/* Write 1 to CMD_DAT_TRACK_SEL field in DLL_CONFIG */
 	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | CMD_DAT_TRACK_SEL), SDCC_DLL_CONFIG_REG);
@@ -492,7 +519,7 @@
 	REG_WRITE32(host, (REG_READ32(host, SDCC_CSR_CDC_CAL_TIMER_CFG0) | CDC_TIMER_EN), SDCC_CSR_CDC_CAL_TIMER_CFG0);
 
 	/* Wait for CALIBRATION_DONE in CDC_STATUS */
-	timeout = 50;
+	timeout = CDC_STATUS_TIMEOUT;
 	while (!(REG_READ32(host, SDCC_CSR_CDC_STATUS0) & BIT(0)))
 	{
 		timeout--;
@@ -513,6 +540,8 @@
 	/* Write 1 to START_CDC_TRAFFIC field in CORE_DDR200_CFG */
 	REG_WRITE32(host, (REG_READ32(host, SDCC_CDC_DDR200_CFG) | START_CDC_TRAFFIC), SDCC_CDC_DDR200_CFG);
 
+	DBG("\n CDCLP533 Calibration Done\n");
+
 	return 0;
 }
 
@@ -531,6 +560,7 @@
 	uint32_t phase = 0;
 	uint32_t tuned_phase_cnt = 0;
 	int ret = 0;
+	int i;
 	struct sdhci_msm_data *msm_host;
 
 	msm_host = host->msm_host;
@@ -563,14 +593,22 @@
 	ASSERT(tuning_data);
 
 	/* Reset & Initialize the DLL block */
-	sdhci_msm_init_dll(host);
+	if (sdhci_msm_init_dll(host))
+	{
+			ret = 1;
+			goto free;
+	}
 
 	while (phase < MAX_PHASES)
 	{
 		struct mmc_command cmd = {0};
 
 		/* configure dll to set phase delay */
-		sdhci_msm_config_dll(host, phase);
+		if (sdhci_msm_config_dll(host, phase))
+		{
+			ret = 1;
+			goto free;
+		}
 
 		cmd.cmd_index = CMD21_SEND_TUNING_BLOCK;
 		cmd.argument = 0x0;
@@ -592,6 +630,12 @@
 	/* Find the appropriate tuned phase */
 	if (tuned_phase_cnt)
 	{
+		DBG("\n Tuned phase\n");
+		for (i = 0 ; i < tuned_phase_cnt ; i++)
+		{
+			DBG("%d\t", tuned_phases[i]);
+		}
+
 		ret = sdhci_msm_find_appropriate_phase(host, tuned_phases, tuned_phase_cnt);
 
 		if (ret < 0)
@@ -604,7 +648,10 @@
 		phase = (uint32_t) ret;
 		ret = 0;
 
-		sdhci_msm_config_dll(host, phase);
+		DBG("\n: %s: Tuned Phase: 0x%08x\n", __func__, phase);
+
+		if (sdhci_msm_config_dll(host, phase))
+			goto free;
 
 		/* Save the tuned phase */
 		host->msm_host->saved_phase = phase;
diff --git a/platform/msm_shared/uart_dm.c b/platform/msm_shared/uart_dm.c
index f551a7a..c92a34f 100644
--- a/platform/msm_shared/uart_dm.c
+++ b/platform/msm_shared/uart_dm.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <debug.h>
+#include <kernel/thread.h>
 #include <reg.h>
 #include <sys/types.h>
 #include <platform/iomap.h>
@@ -339,6 +340,8 @@
 		}
 	}
 
+	//We need to make sure the DM_NO_CHARS_FOR_TX&DM_TF are are programmed atmoically.
+	enter_critical_section();
 	/* We are here. FIFO is ready to be written. */
 	/* Write number of characters to be written */
 	writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base));
@@ -366,6 +369,7 @@
 		tx_char_left = num_of_chars - (i + 1) * 4;
 		tx_data = tx_data + num_chars_written;
 	}
+	exit_critical_section();
 
 	return MSM_BOOT_UART_DM_E_SUCCESS;
 }
diff --git a/project/msm8610.mk b/project/msm8610.mk
index 3f7dcbb..5bcad33 100644
--- a/project/msm8610.mk
+++ b/project/msm8610.mk
@@ -10,6 +10,9 @@
 EMMC_BOOT := 1
 ENABLE_SDHCI_SUPPORT := 1
 
+#enable power on vibrator feature
+ENABLE_PON_VIB_SUPPORT := true
+
 #DEFINES += WITH_DEBUG_DCC=1
 DEFINES += WITH_DEBUG_UART=1
 DEFINES += WITH_DEBUG_LOG_BUF=1
@@ -29,6 +32,10 @@
 #is with the linker and file a bug report.
 ENABLE_THUMB := false
 
+ifeq ($(ENABLE_PON_VIB_SUPPORT),true)
+DEFINES += PON_VIB_SUPPORT=1
+endif
+
 ifeq ($(ENABLE_SDHCI_SUPPORT),1)
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
diff --git a/target/msm8226/init.c b/target/msm8226/init.c
index a3a75e4..e9bac7e 100644
--- a/target/msm8226/init.c
+++ b/target/msm8226/init.c
@@ -357,11 +357,17 @@
 
 void reboot_device(unsigned reboot_reason)
 {
+	int ret = 0;
+
 	writel(reboot_reason, RESTART_REASON_ADDR);
 
 	/* Configure PMIC for warm reset */
 	pm8x41_reset_configure(PON_PSHOLD_WARM_RESET);
 
+	ret = scm_halt_pmic_arbiter();
+	if (ret)
+		dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
+
 	/* Drop PS_HOLD for MSM */
 	writel(0x00, MPM2_MPM_PS_HOLD);
 
@@ -522,6 +528,8 @@
 	dload_util_write_cookie(mode == NORMAL_DLOAD ?
 		DLOAD_MODE_ADDR : EMERGENCY_DLOAD_MODE_ADDR, mode);
 
+	pm8x41_clear_pmic_watchdog();
+
 	return 0;
 }
 
diff --git a/target/msm8610/init.c b/target/msm8610/init.c
index fb6d24c..d085765 100644
--- a/target/msm8610/init.c
+++ b/target/msm8610/init.c
@@ -49,11 +49,14 @@
 #include <partition_parser.h>
 #include <platform/clock.h>
 #include <platform/timer.h>
+#include <shutdown_detect.h>
+#include <vibrator.h>
 
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
 
 #define TLMM_VOL_UP_BTN_GPIO    72
+#define VIBRATE_TIME    250
 
 enum target_subtype {
 	HW_PLATFORM_SUBTYPE_SKUAA = 1,
@@ -163,11 +166,19 @@
 	target_keystatus();
 
 	target_sdc_init();
+
+	shutdown_detect();
+
+	/* turn on vibrator to indicate that phone is booting up to end user */
+	vib_timed_turn_on(VIBRATE_TIME);
 }
 
 void target_uninit(void)
 {
         mmc_put_card_to_sleep(dev);
+
+	/* wait for the vibrator timer is expried */
+	wait_vib_timeout();
 }
 
 #define SSD_CE_INSTANCE         1
@@ -425,3 +436,21 @@
 {
 	return dev;
 }
+
+/* Configure PMIC and Drop PS_HOLD for shutdown */
+void shutdown_device()
+{
+	dprintf(CRITICAL, "Going down for shutdown.\n");
+
+	/* Configure PMIC for shutdown */
+	pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
+
+	/* Drop PS_HOLD for MSM */
+	writel(0x00, MPM2_MPM_PS_HOLD);
+
+	mdelay(5000);
+
+	dprintf(CRITICAL, "shutdown failed\n");
+
+	ASSERT(0);
+}
diff --git a/target/msm8610/rules.mk b/target/msm8610/rules.mk
index 909e673..7ffcfe1 100644
--- a/target/msm8610/rules.mk
+++ b/target/msm8610/rules.mk
@@ -25,6 +25,7 @@
 	dev/pmic/pm8x41 \
 	dev/panel/msm \
 	dev/gcdb/display \
+	dev/vib \
 	lib/libfdt
 
 DEFINES += \
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index 270a300..c89c483 100755
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -58,40 +58,76 @@
 	.full_current_scale = 0x19
 };
 
-static uint32_t dsi_pll_enable_seq(uint32_t ctl_base)
+static uint32_t dsi_pll_lock_status(uint32_t ctl_base)
 {
-	uint32_t rc = 0;
+	uint32_t counter, status;
 
+	udelay(100);
+	mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
+
+	status = readl(ctl_base + 0x02c0) & 0x01;
+	for (counter = 0; counter < 5 && !status; counter++) {
+		udelay(100);
+		status = readl(ctl_base + 0x02c0) & 0x01;
+	}
+
+	return status;
+}
+
+static uint32_t dsi_pll_enable_seq_b(uint32_t ctl_base)
+{
 	mdss_dsi_uniphy_pll_sw_reset(ctl_base);
 
 	writel(0x01, ctl_base + 0x0220); /* GLB CFG */
-	mdelay(1);
+	udelay(1);
 	writel(0x05, ctl_base + 0x0220); /* GLB CFG */
-	mdelay(1);
+	udelay(200);
 	writel(0x07, ctl_base + 0x0220); /* GLB CFG */
-	mdelay(1);
+	udelay(500);
 	writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
-	mdelay(1);
+	udelay(500);
 
-	mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
+	return dsi_pll_lock_status(ctl_base);
+}
 
-	while (!(readl(ctl_base + 0x02c0) & 0x01)) {
-		mdss_dsi_uniphy_pll_sw_reset(ctl_base);
-		writel(0x01, ctl_base + 0x0220); /* GLB CFG */
-		mdelay(1);
-		writel(0x05, ctl_base + 0x0220); /* GLB CFG */
-		mdelay(1);
-		writel(0x07, ctl_base + 0x0220); /* GLB CFG */
-		mdelay(1);
-		writel(0x05, ctl_base + 0x0220); /* GLB CFG */
-		mdelay(1);
-		writel(0x07, ctl_base + 0x0220); /* GLB CFG */
-		mdelay(1);
-		writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
-		mdelay(2);
-		mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
+static uint32_t dsi_pll_enable_seq_d(uint32_t ctl_base)
+{
+	mdss_dsi_uniphy_pll_sw_reset(ctl_base);
+
+	writel(0x01, ctl_base + 0x0220); /* GLB CFG */
+	udelay(1);
+	writel(0x05, ctl_base + 0x0220); /* GLB CFG */
+	udelay(200);
+	writel(0x07, ctl_base + 0x0220); /* GLB CFG */
+	udelay(250);
+	writel(0x05, ctl_base + 0x0220); /* GLB CFG */
+	udelay(200);
+	writel(0x07, ctl_base + 0x0220); /* GLB CFG */
+	udelay(500);
+	writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
+	udelay(500);
+
+	return dsi_pll_lock_status(ctl_base);
+}
+
+static void dsi_pll_enable_seq(uint32_t ctl_base)
+{
+	uint32_t counter, status;
+
+	for (counter = 0; counter < 3; counter++) {
+		status = dsi_pll_enable_seq_b(ctl_base);
+		if (status)
+			break;
+		status = dsi_pll_enable_seq_d(ctl_base);
+		if (status)
+			break;
+		status = dsi_pll_enable_seq_d(ctl_base);
+		if(status)
+			break;
 	}
-	return rc;
+
+	if (!status)
+		dprintf(CRITICAL, "Pll lock sequence failed\n");
 }
 
 static int msm8974_wled_backlight_ctrl(uint8_t enable)
@@ -185,11 +221,6 @@
 		mdp_clock_init();
 		mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data);
 		dsi_pll_enable_seq(MIPI_DSI0_BASE);
-		if (panel.panel_info.mipi.dual_dsi &&
-				!(panel.panel_info.mipi.broadcast)) {
-			mdss_dsi_auto_pll_config(MIPI_DSI1_BASE, pll_data);
-			dsi_pll_enable_seq(MIPI_DSI1_BASE);
-		}
 		mmss_clock_auto_pll_init(DSI0_PHY_PLL_OUT, dual_dsi,
 					pll_data->pclk_m,
 					pll_data->pclk_n,