Merge "platform: msm8974: Fix boot time stamp base address"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f700033..74c0fb9 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1892,11 +1892,7 @@
 		|| !strcmp(ptn->name, "userdata")
 		|| !strcmp(ptn->name, "persist")
 		|| !strcmp(ptn->name, "recoveryfs")) {
-		if (flash_ecc_bch_enabled())
-			/* Spare data bytes for 8 bit ECC increased by 4 */
-			extra = ((page_size >> 9) * 20);
-		else
-			extra = ((page_size >> 9) * 16);
+			extra = 1;
 	} else
 		sz = ROUND_TO_PAGE(sz, page_mask);
 
diff --git a/arch/arm/crt0.S b/arch/arm/crt0.S
index 7f1ad16..d58e234 100644
--- a/arch/arm/crt0.S
+++ b/arch/arm/crt0.S
@@ -50,8 +50,8 @@
 		/* new thumb behavior, low exception vectors, i/d cache disable, mmu disabled */
 	bic		r0, r0, #(1<<15| 1<<13 | 1<<12)
 	bic		r0, r0, #(1<<2 | 1<<0)
-		/* enable alignment faults */
-	orr		r0, r0, #(1<<1)
+		/* disable alignment faults */
+	bic		r0, r0, #(1<<1)
         /* Write SCTLR */
 	mcr		p15, 0, r0, c1, c0, 0
 #ifdef ENABLE_TRUSTZONE
diff --git a/dev/gcdb/display/include/panel_hx8379a_wvga_video.h b/dev/gcdb/display/include/panel_hx8379a_wvga_video.h
index 6bcfc92..acda031 100644
--- a/dev/gcdb/display/include/panel_hx8379a_wvga_video.h
+++ b/dev/gcdb/display/include/panel_hx8379a_wvga_video.h
@@ -98,7 +98,7 @@
 
 static char hx8379a_wvga_video_on_cmd4[] = {
 0x20, 0x00, 0x39, 0xC0,
-0xB4, 0x82, 0x08, 0x00,
+0xB4, 0x80, 0x08, 0x00,
 0x32, 0x10, 0x03, 0x32,
 0x13, 0x70, 0x32, 0x10,
 0x08, 0x37, 0x01, 0x28,
diff --git a/dev/gcdb/display/include/panel_ssd2080m_720p_video.h b/dev/gcdb/display/include/panel_ssd2080m_720p_video.h
index f8fc707..66c2b5a 100755
--- a/dev/gcdb/display/include/panel_ssd2080m_720p_video.h
+++ b/dev/gcdb/display/include/panel_ssd2080m_720p_video.h
@@ -54,7 +54,7 @@
 /* Panel resolution                                                          */
 /*---------------------------------------------------------------------------*/
 static struct panel_resolution ssd2080m_720p_video_panel_res = {
-  720, 1280, 80, 30, 14, 0, 12, 16, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  720, 1280, 80, 24, 14, 0, 12, 16, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
 /*---------------------------------------------------------------------------*/
@@ -453,7 +453,7 @@
 /*---------------------------------------------------------------------------*/
 
 static struct videopanel_info ssd2080m_720p_video_video_panel = {
-  1, 0, 0, 0, 1, 0, 2, 0, 0x9
+  1, 0, 0, 0, 1, 0, 2, 0, 0x8
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/include/dev/flash.h b/include/dev/flash.h
index 9fa10bc..6c2402d 100644
--- a/include/dev/flash.h
+++ b/include/dev/flash.h
@@ -68,7 +68,7 @@
 int flash_erase(struct ptentry *ptn);
 int flash_read_ext(struct ptentry *ptn, unsigned extra_per_page,
 		   unsigned offset, void *data, unsigned bytes);
-int flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data,
+int flash_write(struct ptentry *ptn, unsigned write_extra_bytes, const void *data,
 		unsigned bytes);
 
 static inline int flash_read(struct ptentry *ptn, unsigned offset, void *data,
diff --git a/include/endian.h b/include/endian.h
index 34bef6e..fe41a6c 100644
--- a/include/endian.h
+++ b/include/endian.h
@@ -49,6 +49,15 @@
 #endif
 
 // define a macro that unconditionally swaps
+#define SWAP_64(x) \
+		((((x) & 0xff00000000000000ull) >> 56) \
+		| (((x) & 0x00ff000000000000ull) >> 40) \
+		| (((x) & 0x0000ff0000000000ull) >> 24) \
+		| (((x) & 0x000000ff00000000ull) >> 8) \
+		| (((x) & 0x00000000ff000000ull) << 8) \
+		| (((x) & 0x0000000000ff0000ull) << 24) \
+		| (((x) & 0x000000000000ff00ull) << 40) \
+		| (((x) & 0x00000000000000ffull) << 56))
 #define SWAP_32(x) \
 	(((uint32_t)(x) << 24) | (((uint32_t)(x) & 0xff00) << 8) |(((uint32_t)(x) & 0x00ff0000) >> 8) | ((uint32_t)(x) >> 24))
 #define SWAP_16(x) \
@@ -56,19 +65,25 @@
 
 // standard swap macros
 #if BYTE_ORDER == BIG_ENDIAN
+#define LE64(val) SWAP_64(val)
 #define LE32(val) SWAP_32(val)
 #define LE16(val) SWAP_16(val)
+#define BE64(val) (val)
 #define BE32(val) (val)
 #define BE16(val) (val)
 #else
+#define LE64(val) (val)
 #define LE32(val) (val)
 #define LE16(val) (val)
+#define BE64(val) SWAP_64(val)
 #define BE32(val) SWAP_32(val)
 #define BE16(val) SWAP_16(val)
 #endif
 
+#define LE64SWAP(var) (var) = LE64(var);
 #define LE32SWAP(var) (var) = LE32(var);
 #define LE16SWAP(var) (var) = LE16(var);
+#define BE64SWAP(var) (var) = BE64(var);
 #define BE32SWAP(var) (var) = BE32(var);
 #define BE16SWAP(var) (var) = BE16(var);
 
diff --git a/platform/apq8084/include/platform/iomap.h b/platform/apq8084/include/platform/iomap.h
index ef26cbb..a5d0d41 100644
--- a/platform/apq8084/include/platform/iomap.h
+++ b/platform/apq8084/include/platform/iomap.h
@@ -119,6 +119,8 @@
 
 #define USB_HS_BCR                  (CLK_CTL_BASE + 0x480)
 
+#define UFS_BASE                    (0xFC590000 + 0x00004000)
+
 #define SPMI_BASE                   0xFC4C0000
 #define SPMI_GENI_BASE              (SPMI_BASE + 0xA000)
 #define SPMI_PIC_BASE               (SPMI_BASE + 0xB000)
diff --git a/platform/apq8084/include/platform/irqs.h b/platform/apq8084/include/platform/irqs.h
index 8b25b0c..33e1a12 100644
--- a/platform/apq8084/include/platform/irqs.h
+++ b/platform/apq8084/include/platform/irqs.h
@@ -45,6 +45,8 @@
 
 #define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP      (GIC_SPI_START + 8)
 
+#define UFS_IRQ                                (GIC_SPI_START + 28)
+
 #define USB1_HS_BAM_IRQ                        (GIC_SPI_START + 135)
 #define USB1_HS_IRQ                            (GIC_SPI_START + 134)
 #define USB2_IRQ                               (GIC_SPI_START + 141)
diff --git a/platform/msm_shared/dme.c b/platform/msm_shared/dme.c
new file mode 100644
index 0000000..da2f9ec
--- /dev/null
+++ b/platform/msm_shared/dme.c
@@ -0,0 +1,369 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 <string.h>
+#include <reg.h>
+#include <arch/defines.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <endian.h>
+#include <ufs.h>
+#include <dme.h>
+#include <uic.h>
+#include <utp.h>
+
+int dme_send_linkstartup_req(struct ufs_dev *dev)
+{
+	struct uic_cmd cmd;
+
+	cmd.uiccmd        = UICCMDR_DME_LINKSTARTUP;
+	cmd.num_args      = UICCMD_NO_ARGS;
+	cmd.timeout_msecs = DME_LINK_START_TIMEOUT;
+
+	if (uic_send_cmd(dev, &cmd) || cmd.gen_err_code == UICCMD_FAILURE)
+		goto dme_send_linkstartup_req_err;
+
+	return UFS_SUCCESS;
+
+dme_send_linkstartup_req_err:
+	dprintf(CRITICAL, "DME_LINKSTARTUP command failed.\n");
+	return -UFS_FAILURE;
+}
+
+int dme_get_req(struct ufs_dev *dev, struct dme_get_req_type *req)
+{
+	struct uic_cmd cmd;
+
+	cmd.uiccmd	      = UICCMDR_DME_GET;
+	cmd.num_args      = UICCMD_ONE_ARGS;
+	cmd.uiccmdarg1    = req->attribute << 16 | req->index;
+	cmd.timeout_msecs = INFINITE_TIME;
+
+	if (uic_send_cmd(dev, &cmd) || cmd.gen_err_code == UICCMD_FAILURE)
+		goto dme_get_req_err;
+
+	/* Return the result. */
+	*(req->mibval) = cmd.uiccmdarg3;
+
+	return UFS_SUCCESS;
+
+dme_get_req_err:
+	dprintf(CRITICAL, "DME_GET command failed.\n");
+	return -UFS_FAILURE;
+}
+
+static int dme_get_query_resp(struct ufs_dev *dev,
+					          struct upiu_req_build_type *req_upiu,
+					          addr_t buffer,
+					          size_t buf_len)
+{
+	struct upiu_trans_mgmt_query_hdr *resp_upiu;
+
+	resp_upiu = (struct upiu_trans_mgmt_query_hdr *) req_upiu->resp_ptr;
+
+	if (resp_upiu->opcode != req_upiu->opcode)
+		return -UFS_FAILURE;
+	if (resp_upiu->basic_hdr.response != UPIU_QUERY_RESP_SUCCESS)
+		return -UFS_FAILURE;
+
+	switch (resp_upiu->opcode)
+	{
+		case UPIU_QUERY_OP_READ_FLAG:
+		case UPIU_QUERY_OP_SET_FLAG:
+									  if (buf_len < sizeof(uint32_t))
+									  {
+										dprintf(CRITICAL, "Insufficient buffer space.\n");
+										return -UFS_FAILURE;
+									  }
+
+									  *((uint32_t *) buffer) = resp_upiu->flag_value;
+									  break;
+		case UPIU_QUERY_OP_TOGGLE_FLAG:
+		case UPIU_QUERY_OP_CLEAR_FLAG:
+		case UPIU_QUERY_OP_READ_DESCRIPTOR:
+									 break;
+		default: dprintf(CRITICAL, "UPIU query opcode not supported.\n");
+				 return -UFS_FAILURE;
+	}
+
+	return UFS_SUCCESS;
+}
+
+static int dme_send_query_upiu(struct ufs_dev *dev, struct utp_query_req_upiu_type *query)
+{
+	struct upiu_trans_mgmt_query_hdr resp_upiu;
+	struct upiu_req_build_type       req_upiu;
+	int                              ret;
+
+	memset(&req_upiu, 0, sizeof(req_upiu));
+
+	req_upiu.opcode        = query->opcode;
+	req_upiu.selector      = query->selector;
+	req_upiu.index         = query->index;
+	req_upiu.idn           = query->idn;
+	req_upiu.trans_type    = UPIU_TYPE_QUERY_REQ;
+	req_upiu.dd            = UTRD_NO_DATA_TRANSFER;
+	req_upiu.resp_ptr      = (struct upiu_basic_hdr *) &resp_upiu;
+	req_upiu.resp_len      = sizeof(resp_upiu);
+	req_upiu.resp_data_ptr = query->buf;
+	req_upiu.timeout_msecs = UTP_GENERIC_CMD_TIMEOUT;
+
+	if (query->opcode == UPIU_QUERY_OP_READ_DESCRIPTOR)
+	{
+		req_upiu.resp_data_len = query->buf_len;
+	}
+
+	ret = utp_enqueue_upiu(dev, &req_upiu);
+	if (ret)
+		goto utp_send_query_upiu_err;
+
+	ret = dme_get_query_resp(dev, &req_upiu, query->buf, query->buf_len);
+	if (ret)
+		goto utp_send_query_upiu_err;
+
+utp_send_query_upiu_err:
+	return ret;
+}
+
+int dme_set_fdeviceinit(struct ufs_dev *dev)
+{
+	STACKBUF_DMA_ALIGN(result, sizeof(uint32_t));
+	uint32_t try_again                        = DME_FDEVICEINIT_RETRIES;
+	struct utp_query_req_upiu_type read_query = {UPIU_QUERY_OP_READ_FLAG,
+												 UFS_IDX_fDeviceInit,
+												 0,
+												 0,
+												 (addr_t) result,
+												 sizeof(uint32_t)};
+	struct utp_query_req_upiu_type set_query  = {UPIU_QUERY_OP_SET_FLAG,
+												 UFS_IDX_fDeviceInit,
+												 0,
+												 0,
+												 (addr_t) result,
+												 sizeof(uint32_t)};
+
+
+	if (dme_send_query_upiu(dev, &read_query))
+		return -UFS_FAILURE;
+
+	arch_invalidate_cache_range((addr_t) result, sizeof(uint32_t));
+
+	if (*result == 1)
+		goto utp_set_fdeviceinit_done;
+
+	do
+	{
+		try_again--;
+
+		if (dme_send_query_upiu(dev, &set_query))
+			return -UFS_FAILURE;
+
+		if (dme_send_query_upiu(dev, &read_query))
+			return -UFS_FAILURE;
+
+		if (*result == 1)
+			break;
+	} while (try_again);
+
+utp_set_fdeviceinit_done:
+	return UFS_SUCCESS;
+}
+
+int dme_read_string_desc(struct ufs_dev *dev, uint8_t index, struct ufs_string_desc *desc)
+{
+	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+											UFS_DESC_IDN_STRING,
+											index,
+											0,
+											(addr_t) desc,
+											sizeof(struct ufs_string_desc)};
+
+	if (dme_send_query_upiu(dev, &query))
+		return -UFS_FAILURE;
+
+	if (desc->desc_len != 0)
+		return UFS_SUCCESS;
+
+	return -UFS_FAILURE;
+}
+
+int dme_read_device_desc(struct ufs_dev *dev)
+{
+	STACKBUF_DMA_ALIGN(dev_desc, sizeof(struct ufs_dev_desc));
+	STACKBUF_DMA_ALIGN(desc, sizeof(struct ufs_string_desc));
+	struct ufs_dev_desc            *device_desc = dev_desc;
+	struct ufs_string_desc         *str_desc    = desc;
+	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+											UFS_DESC_IDN_DEVICE,
+											0,
+											0,
+											(addr_t) dev_desc,
+											sizeof(struct ufs_dev_desc)};
+
+	if (dme_send_query_upiu(dev, &query))
+		return -UFS_FAILURE;
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) device_desc, sizeof(struct ufs_dev_desc));
+
+	/* Store all relevant data */
+	dev->num_lus = device_desc->num_lu;
+
+	/* Get serial number for the device based on the string index. */
+	if (dme_read_string_desc(dev, device_desc->serial_num, desc))
+		return -UFS_FAILURE;
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) str_desc, sizeof(struct ufs_string_desc));
+
+	dev->serial_num = 0;
+	
+	return UFS_SUCCESS;
+}
+
+int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index, uint64_t *capacity)
+{
+	STACKBUF_DMA_ALIGN(unit_desc, sizeof(struct ufs_unit_desc));
+	struct ufs_unit_desc           *desc = unit_desc;
+	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+											UFS_DESC_IDN_UNIT,
+											index,
+											0,
+											(addr_t) unit_desc,
+											sizeof(struct ufs_unit_desc)};
+
+	if (dme_send_query_upiu(dev, &query))
+		return -UFS_FAILURE;
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_unit_desc));
+
+	*capacity = BE64(desc->logical_blk_cnt) * dev->block_size;
+
+	return UFS_SUCCESS;
+}
+
+int dme_read_config_desc(struct ufs_dev *dev)
+{
+	STACKBUF_DMA_ALIGN(desc, sizeof(struct ufs_config_desc));
+	struct ufs_config_desc         *config_desc = desc;
+	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+											UFS_DESC_IDN_CONFIGURATION,
+											0,
+											0,
+											(addr_t) config_desc,
+											sizeof(struct ufs_config_desc)};
+
+	if (dme_send_query_upiu(dev, &query))
+		return -UFS_FAILURE;
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) config_desc, sizeof(struct ufs_config_desc));
+
+	return UFS_SUCCESS;
+}
+
+int dme_send_nop_query(struct ufs_dev *dev)
+{
+	struct upiu_req_build_type     req_upiu;
+	struct upiu_basic_hdr          resp_upiu;
+	int                            ret;
+	unsigned                       try_again;
+
+	ret       = UFS_SUCCESS;
+	try_again = DME_NOP_NUM_RETRIES;
+
+	memset(&req_upiu, 0 , sizeof(struct upiu_req_build_type));
+
+	req_upiu.trans_type        = UPIU_TYPE_NOP_OUT;
+	req_upiu.flags             = 0;
+	req_upiu.query_mgmt_func   = 0;
+	req_upiu.cmd_type          = UTRD_DEV_MGMT_FUNC;
+	req_upiu.dd                = UTRD_NO_DATA_TRANSFER;
+	req_upiu.resp_ptr          = &resp_upiu;
+	req_upiu.resp_len          = sizeof(struct upiu_basic_hdr);
+	req_upiu.timeout_msecs     = DME_NOP_QUERY_TIMEOUT;
+
+	while (try_again)
+	{
+		try_again--;
+
+		ret = utp_enqueue_upiu(dev, &req_upiu);
+
+		if (ret == -UFS_RETRY)
+		{
+			continue;
+		}
+		else if (ret == -UFS_FAILURE)
+		{
+			dprintf(CRITICAL, "sending nop out failed.\n");
+			goto upiu_send_nop_out_err;
+		}
+
+		/* Check response UPIU */
+		if (resp_upiu.trans_type != UPIU_TYPE_NOP_IN)
+		{
+			dprintf(CRITICAL, "Command failed. command = %x. Invalid response.\n", req_upiu.trans_type);
+			ret = -UFS_FAILURE;
+			goto upiu_send_nop_out_err;
+		}
+		else
+			break;
+	}
+
+upiu_send_nop_out_err:
+	return ret;
+}
+
+int utp_build_query_req_upiu(struct upiu_trans_mgmt_query_hdr *req_upiu,
+							 struct upiu_req_build_type *upiu_data)
+{
+	req_upiu->opcode    = upiu_data->opcode;
+	req_upiu->idn       = upiu_data->idn;
+	req_upiu->index     = upiu_data->index;
+	req_upiu->selector  = upiu_data->selector;
+	req_upiu->resp_len  = BE16(upiu_data->resp_data_len);
+
+	switch (upiu_data->opcode)
+	{
+		case UPIU_QUERY_OP_READ_FLAG:
+		case UPIU_QUERY_OP_READ_DESCRIPTOR:
+											req_upiu->basic_hdr.query_task_mgmt_func = UPIU_QUERY_FUNC_STD_READ_REQ;
+											break;
+		case UPIU_QUERY_OP_TOGGLE_FLAG:
+		case UPIU_QUERY_OP_CLEAR_FLAG:
+		case UPIU_QUERY_OP_SET_FLAG:
+									 req_upiu->basic_hdr.query_task_mgmt_func = UPIU_QUERY_FUNC_STD_WRITE_REQ;
+									 break;
+		default: dprintf(CRITICAL, "UPIU query opcode not supported.\n");
+				 return -UFS_FAILURE;
+	}
+
+	return UFS_SUCCESS;
+}
diff --git a/platform/msm_shared/include/dme.h b/platform/msm_shared/include/dme.h
new file mode 100644
index 0000000..c93e23a
--- /dev/null
+++ b/platform/msm_shared/include/dme.h
@@ -0,0 +1,247 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 _DME_H_
+#define _DME_H_
+
+#include <sys/types.h>
+#include <upiu.h>
+
+/* Bit field of UFSHCI_UICCMDR register */
+#define UICCMDR_DME_GET                                  0x01
+#define UICCMDR_DME_SET                                  0x02
+#define UICCMDR_DME_PEER_GET                             0x03
+#define UICCMDR_DME_PEER_SET                             0x04
+#define UICCMDR_DME_POWERON                              0x10
+#define UICCMDR_DME_POWEROFF                             0x11
+#define UICCMDR_DME_ENABLE                               0x12
+#define UICCMDR_DME_RESET                                0x14
+#define UICCMDR_DME_ENDPOINTRESET                        0x15
+#define UICCMDR_DME_LINKSTARTUP                          0x16
+#define UICCMDR_DME_HIBERNATE_ENTER                      0x17
+#define UICCMDR_DME_HIBERNATE_EXIT                       0x18
+#define UICCMDR_DME_TEST_MODE                            0x1a
+
+/* Retry value for commands. */
+#define DME_NOP_NUM_RETRIES                              20
+#define DME_FDEVICEINIT_RETRIES                          20
+
+/* Timeout value for commands. */
+#define DME_NOP_QUERY_TIMEOUT                            10
+#define DME_LINK_START_TIMEOUT                           1
+
+/* UFS descriptor type ident value */
+enum utp_ufs_desc_type
+{
+	UFS_DESC_IDN_DEVICE         = 0x00,
+	UFS_DESC_IDN_CONFIGURATION  = 0x01,
+	UFS_DESC_IDN_UNIT           = 0x02,
+	UFS_DESC_IDN_INTERCONNECT   = 0x04,
+	UFS_DESC_IDN_STRING         = 0x05,
+	UFS_DESC_IDN_GEOMETRY       = 0x07,
+	UFS_DESC_IDN_POWER          = 0x08,
+};
+
+// Attributes definitions
+#define UFS_IDX_bBootLunEn          0x00
+#define UFS_IDX_bCurrentPowerMode   0x01
+#define UFS_IDX_bActiveICCLevel     0x03
+#define UFS_IDX_bRefClkFreq         0x0a
+#define UFS_IDX_bConfigDescrLock    0x0b
+
+enum utp_query_req_upiu_func_type
+{
+	UPIU_QUERY_FUNC_STD_READ_REQ  = 0x01,
+	UPIU_QUERY_FUNC_STD_WRITE_REQ = 0x81,
+};
+
+/* Flags definitions */
+#define UFS_IDX_fDeviceInit         0x01
+#define UFS_IDX_fPowerOnWPEn        0x03
+
+enum utp_query_response_upiu_type
+{
+	UPIU_QUERY_RESP_SUCCESS               = 0x00,
+	UPIU_QUERY_RESP_PARAM_NOT_READABLE    = 0xF6,
+	UPIU_QUERY_RESP_PARAM_NOT_WRITABLE    = 0xF7,
+	UPIU_QUERY_RESP_PARAM_ALREADY_WRITTEN = 0xF8,
+	UPIU_QUERY_RESP_INVALID_LEN           = 0xF9,
+	UPIU_QUERY_RESP_INVALID_VALUE         = 0xFA,
+	UPIU_QUERY_RESP_INVALID_SELECTOR      = 0xFB,
+	UPIU_QUERY_RESP_INVALID_IDN           = 0xFC,
+	UPIU_QUERY_RESP_INVALID_OPCODE        = 0xFD,
+	UPIU_QUERY_RESP_GEN_FAILURE           = 0xFE,
+};
+
+struct dme_get_req_type
+{
+	uint16_t attribute;
+	uint16_t index;
+	uint32_t *mibval;
+};
+
+#define DEV_DESC_LEN                   0x1F
+
+struct utp_query_req_upiu_type
+{
+	enum upiu_query_opcode_type opcode;
+	uint8_t idn;
+	uint8_t index;
+	uint8_t selector;
+	addr_t  buf;
+	size_t  buf_len;
+};
+
+struct ufs_dev_desc
+{
+	uint8_t  desc_len;
+	uint8_t  desc_type;
+	uint8_t  dev_type;
+	uint8_t  dev_class;
+	uint8_t  dev_sub_class;
+	uint8_t  protocol;
+	uint8_t  num_lu;
+	uint8_t  num_wlun;
+	uint8_t  boot_en;
+	uint8_t  desc_access_en;
+	uint8_t  init_pwr_mode;
+	uint8_t  high_pior_lun;
+	uint8_t  sec_removal_type;
+	uint8_t  sec_lun;
+	uint8_t  resv_0;
+	uint8_t  active_icc_level;
+	uint16_t spec_ver;
+	uint16_t manufacture_date;
+	uint8_t  manufacture_name;
+	uint8_t  product_name;
+	uint8_t  serial_num;
+	uint8_t  oem_id;
+	uint16_t manufacture_id;
+	uint8_t  ud0_base_offset;
+	uint8_t  ud_config_p_len;
+	uint8_t  dev_rtt_cap;
+}__PACKED;
+
+struct ufs_unit_desc
+{
+	uint8_t   desc_len;
+	uint8_t   desc_type;
+	uint8_t   unit_index;
+	uint8_t   lu_enable;
+	uint8_t   boot_lun_id;
+	uint8_t   lu_wp;
+	uint8_t   lu_queue_depth;
+	uint8_t   resv;
+	uint8_t   mem_type;
+	uint8_t   data_reliability;
+	uint8_t   logical_blk_size;
+	uint64_t  logical_blk_cnt;
+	uint32_t  erase_blk_size;
+	uint8_t   provisioning_type;
+	uint8_t   phy_mem_resource_cnt[8];
+	uint16_t  ctx_capabilities;
+	uint8_t   large_unit_size_m1;
+}__PACKED;
+
+struct ufs_geometry_desc
+{
+	uint8_t  desc_len;
+	uint8_t  desc_type;
+	uint8_t  media_tech;
+	uint8_t  resv_0;
+	uint8_t  raw_dev_capacity[8];
+	uint8_t  resv_1;
+	uint32_t segment_size;
+	uint8_t  alloc_unit_size;
+	uint8_t  min_addr_blk_size;
+	uint8_t  optimal_read_blk_size;
+	uint8_t  optimal_write_blk_size;
+	uint8_t  max_inbuf_size;
+	uint8_t  maxoutbuf_size;
+	uint8_t  rpmb_rdwr_size;
+	uint8_t  resv_2;
+	uint8_t  data_ordering;
+	uint8_t  resv_3[5];
+	uint8_t  max_ctx_id_num;
+	uint8_t  sys_data_tag_unit_size;
+	uint8_t  sys_data_tag_res_size;
+	uint8_t  supp_sec_rt_types;
+	uint16_t supp_mem_types;
+}__PACKED;
+
+struct ufs_dev_desc_config_params
+{
+	uint8_t  num_lu;
+	uint8_t  boot_enable;
+	uint8_t  desc_access_en;
+	uint8_t  init_pwr_mode;
+	uint8_t  high_pior_lun;
+	uint8_t  sec_removal_type;
+	uint8_t  active_icc_level;
+	uint16_t dev_rtt_cap;
+	uint8_t  resv[5];
+}__PACKED;
+
+struct ufs_unit_desc_config_params
+{
+	uint8_t lu_enable;
+	uint8_t boot_lun_id;
+	uint8_t lu_wp;
+	uint8_t mem_type;
+	uint32_t num_alloc_units;
+	uint8_t data_reliability;
+	uint8_t logical_blk_size;
+	uint8_t provisioning_type;
+	uint16_t ctx_capabilities;
+	uint8_t resv[3];
+}__PACKED;
+
+struct ufs_config_desc
+{
+	uint8_t                            desc_len;
+	uint8_t                            desc_type;
+	struct ufs_dev_desc_config_params  config_params;
+	struct ufs_unit_desc_config_params unit_params[8];
+}__PACKED;
+
+struct ufs_string_desc
+{
+	uint8_t desc_len;
+	uint8_t desc_type;
+	uint8_t serial_num[128];
+}__PACKED;
+
+int dme_send_linkstartup_req(struct ufs_dev *dev);
+int dme_get_req(struct ufs_dev *dev, struct dme_get_req_type *req);
+int utp_build_query_req_upiu(struct upiu_trans_mgmt_query_hdr *req_upiu,
+								  struct upiu_req_build_type *upiu_data);
+int dme_send_nop_query(struct ufs_dev *dev);
+int dme_set_fdeviceinit(struct ufs_dev *dev);
+int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index, uint64_t *capacity);
+
+#endif
diff --git a/platform/msm_shared/include/ucs.h b/platform/msm_shared/include/ucs.h
new file mode 100644
index 0000000..9f02a03
--- /dev/null
+++ b/platform/msm_shared/include/ucs.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 _UCS_H
+#define _UCS_H
+
+#define SCSI_MAX_DATA_TRANS_BLK_LEN    0x01
+#define UFS_DEFAULT_SECTORE_SIZE       4096
+
+#define SCSI_STATUS_GOOD               0x00
+#define SCSI_STATUS_CHK_COND           0x02
+#define SCSI_STATUS_BUSY               0x08
+#define SCSI_STATUS_TASK_SET_FULL      0x08
+
+#define SCSI_SENSE_BUF_LEN             0x20
+#define SCSI_INQUIRY_LEN               36
+#define SCSI_CDB_PARAM_LEN             16
+
+/* FLAGS for indication of read or write */
+enum scsi_upiu_flags
+{
+	UPIU_FLAGS_READ         = 0x40,
+	UPIU_FLAGS_WRITE        = 0x20,
+	UPIU_FLAGS_ATTR_SIMPLE  = 0x00,
+	UPIU_FLAGS_ATTR_ORDERED = 0x01,
+	UPIU_FLAGS_ATTR_HOQ     = 0x02,
+};
+
+#define SCSI_READ_WRITE_10_CDB1(rd_protect, dpo, fua, fua_nv) ((rd_protect) << 5 | (dpo) << 4 | (fua) << 3 | (fua_nv) << 1)
+
+/* SCSI commands */
+enum utp_scsi_cmd_type
+{
+	SCSI_CMD_TEST_UNIT_RDY      = 0x00,
+	SCSI_CMD_SENSE_REQ          = 0x03,
+	SCSI_CMD_INQUIRY            = 0x12,
+	SCSI_CMD_READ10             = 0x28,
+	SCSI_CMD_READ_CAP10         = 0x25,     // Read Capacity
+	SCSI_CMD_SYNC_CACHE10       = 0x35,
+	SCSI_CMD_UNMAP              = 0x42,
+	SCSI_CMD_WRITE10            = 0x2A,
+	SCSI_CMD_SECPROT_IN         = 0xA2,     // Security Protocal in
+	SCSI_CMD_SECPROT_OUT        = 0xB5,     // Security Protocal out
+	SCSI_CMD_REPORT_LUNS        = 0xA0,
+};
+
+struct scsi_req_build_type
+{
+	addr_t               cdb;
+	uint8_t              lun;
+	addr_t               data_buffer_addr;
+	uint32_t             data_len;
+	enum scsi_upiu_flags flags;
+	enum upiu_dd_type    dd;
+};
+
+struct scsi_rdwr_req
+{
+	uint8_t  lun;
+	uint32_t start_lba;
+	uint32_t num_blocks;
+	uint32_t data_buffer_base;
+};
+
+struct scsi_rdwr_cdb
+{
+	uint8_t  opcode;
+	uint8_t  cdb1;
+	uint32_t lba;
+	uint8_t  grp_num;
+	uint16_t trans_len;
+	uint8_t  control;
+	uint8_t  resv[6];
+}__PACKED;
+
+struct scsi_sense_cdb
+{
+	uint8_t  opcode;
+	uint8_t  desc;
+	uint16_t resv_0;
+	uint8_t  alloc_len;
+	uint8_t  control;
+	uint8_t  resv_1[10];
+}__PACKED;
+
+struct scsi_failure_sense_data
+{
+	uint8_t  valid_resp_code;
+	uint8_t  obsolete;
+	uint16_t file_mark_eom_ili_resv_sense_key;
+	uint8_t  sense_info[4];
+	uint8_t  additional_sense_len;
+	uint32_t csi;
+	uint8_t  asc;
+	uint8_t  ascq;
+	uint8_t  fruc;
+	uint8_t  sense_key_specific;
+}__PACKED;
+
+int ucs_scsi_send_inquiry(struct ufs_dev *dev);
+int ucs_do_scsi_read(struct ufs_dev *dev, struct scsi_rdwr_req *req);
+int ucs_do_scsi_write(struct ufs_dev *dev, struct scsi_rdwr_req *req);
+
+#endif
diff --git a/platform/msm_shared/include/ufs.h b/platform/msm_shared/include/ufs.h
new file mode 100644
index 0000000..e5578bd
--- /dev/null
+++ b/platform/msm_shared/include/ufs.h
@@ -0,0 +1,96 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 _UFS_H_
+#define _UFS_H_
+
+#include <sys/types.h>
+#include <kernel/mutex.h>
+#include <kernel/event.h>
+#include <list.h>
+
+enum ufs_err
+{
+	UFS_SUCCESS,
+	UFS_FAILURE,
+	UFS_RETRY,
+};
+
+struct ufs_req_node
+{
+	uint32_t                  task_id;
+	uint32_t                  door_bell_bit;
+	event_t                   *event;
+	struct list_node          list_node;
+};
+
+
+struct ufs_utp_req_meta_data
+{
+	mutex_t             bitmap_mutex;
+	struct ufs_req_node list_head;
+	uint32_t            bitmap;
+	uint32_t            task_id;
+	uint64_t            list_base_addr;
+};
+
+struct ufs_uic_meta_data
+{
+	mutex_t  uic_mutex;
+	event_t  uic_event;
+};
+
+struct ufs_dev
+{
+	uint8_t                      instance;
+	uint32_t                     base;
+	uint8_t                      num_lus;
+	uint32_t                      serial_num;
+	uint32_t                     block_size;
+
+	/* UTRD maintainance data structures.*/
+	struct ufs_utp_req_meta_data utrd_data;
+	struct ufs_utp_req_meta_data utmrd_data;
+
+	/* UIC maintainance data structures.*/
+	struct ufs_uic_meta_data     uic_data;
+};
+
+/* Define all the basic WLUN type  */
+#define UFS_WLUN_REPORT          0x81
+#define UFS_UFS_DEVICE           0xD0
+#define UFS_WLUN_BOOT            0xB0
+#define UFS_WLUN_RPMB            0xC4
+
+int ufs_init(struct ufs_dev *dev);
+int ufs_read(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks);
+int ufs_write(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks);
+uint64_t ufs_get_dev_capacity(struct ufs_dev* dev);
+uint32_t ufs_get_serial_num(struct ufs_dev* dev);
+
+#endif
diff --git a/platform/msm_shared/include/ufs_hci.h b/platform/msm_shared/include/ufs_hci.h
new file mode 100644
index 0000000..b1b76f6
--- /dev/null
+++ b/platform/msm_shared/include/ufs_hci.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2013, 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

+ * 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 The Linux Foundation 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 _UFS_HCI_H

+#define _UFS_HCI_H_

+

+#include <kernel/mutex.h>

+#include <kernel/event.h>

+#include <list.h>

+#include <ufs.h>

+

+#define UFS_HCE_TIMEOUT                 100000

+

+struct ufs_req_irq_type

+{

+	struct list_node *list;

+	uint32_t irq_handled;

+	uint32_t door_bell_reg;

+};

+

+int ufs_reg_target_val_timeout_loop(uint32_t reg_addr, uint32_t target_val, uint32_t timeout);

+enum handler_return ufs_irq_handler(void* data);

+void ufs_irq_enable(struct ufs_dev *dev, uint32_t irq);

+int ufs_enable_hci(struct ufs_dev *dev);

+uint64_t ufs_alloc_trans_req_list();

+uint64_t ufs_alloc_task_mgmt_req_list();

+

+#endif

diff --git a/platform/msm_shared/include/ufs_hw.h b/platform/msm_shared/include/ufs_hw.h
new file mode 100644
index 0000000..cf4da12
--- /dev/null
+++ b/platform/msm_shared/include/ufs_hw.h
@@ -0,0 +1,107 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 _UFS_HW_H_
+#define _UFS_HW_H_
+
+#include <bits.h>
+
+#define UFS_CAP(_base)                             (_base + 0x00000000)
+#define UFS_VER(_base)                             (_base + 0x00000008)
+#define UFS_HCDDID(_base)                          (_base + 0x00000010)
+#define UFS_HCPMID(_base)                          (_base + 0x00000014)
+#define UFS_IS(_base)                              (_base + 0x00000020)
+#define UFS_IE(_base)                              (_base + 0x00000024)
+#define UFS_HCS(_base)                             (_base + 0x00000030)
+#define UFS_HCE(_base)                             (_base + 0x00000034)
+#define UFS_UECPA(_base)                           (_base + 0x00000038)
+#define UFS_UECDL(_base)                           (_base + 0x0000003C)
+#define UFS_UTRIACR(_base)                         (_base + 0x0000004C)
+#define UFS_UTRLBA(_base)                          (_base + 0x00000050)
+#define UFS_UTRLBAU(_base)                         (_base + 0x00000054)
+#define UFS_UTRLDBR(_base)                         (_base + 0x00000058)
+#define UFS_UTRLCLR(_base)                         (_base + 0x0000005C)
+#define UFS_UTRLRSR(_base)                         (_base + 0x00000060)
+#define UFS_UTMRLBA(_base)                         (_base + 0x00000070)
+#define UFS_UTMRLBAU(_base)                        (_base + 0x00000074)
+#define UFS_UTMRLRSR(_base)                        (_base + 0x00000080)
+#define UFS_UICCMD(_base)                          (_base + 0x00000090)
+#define UFS_UICCMDARG1(_base)                      (_base + 0x00000094)
+#define UFS_UICCMDARG2(_base)                      (_base + 0x00000098)
+#define UFS_UICCMDARG3(_base)                      (_base + 0x0000009C)
+#define UFS_SYS1CLK_1US(_base)                     (_base + 0x000000C0)
+#define UFS_TX_SYMBOL_CLK_NS_US(_base)             (_base + 0x000000C4)
+#define UFS_REG_PA_LINK_STARTUP_TIMER(_base)       (_base + 0x000000D8)
+#define UFS_CFG1(_base)                            (_base + 0x000000DC)
+
+#define UFS_CFG1_PHY_SOFT_RESET             BIT(0)
+
+/* Bit field of UFSHCI_HCS register */
+#define UFS_HCS_DP                          BIT(0)
+#define UFS_HCS_UTRLRDY                     BIT(1)
+#define UFS_HCS_UTMRLRDY                    BIT(2)
+#define UFS_HCS_UCRDY                       BIT(3)
+
+/* Bit field of UFSHCI_IE register */
+#define UFS_IE_UTRCE                        BIT(0)
+#define UFS_IE_UDEPRIU                      BIT(1)
+#define UFS_IE_UEE                          BIT(2)
+#define UFS_IE_UTMSE                        BIT(3)
+#define UFS_IE_UPMSE                        BIT(4)
+#define UFS_IE_UHXSE                        BIT(5)
+#define UFS_IE_UHESE                        BIT(6)
+#define UFS_IE_ULLSE                        BIT(7)
+#define UFS_IE_ULSSE                        BIT(8)
+#define UFS_IE_UTMRCE                       BIT(9)
+#define UFS_IE_UCCE                         BIT(10)
+#define UFS_IE_DFEE                         BIT(11)
+#define UFS_IE_UTPEE                        BIT(12)
+#define UFS_IE_HCFEE                        BIT(16)
+#define UFS_IE_SBFEE                        BIT(17)
+
+/* Bit field of UFSHCI_IS register */
+#define UFS_IS_UTRCS                        BIT(0)
+#define UFS_IS_UDEPRI                       BIT(1)
+#define UFS_IS_UE                           BIT(2)
+#define UFS_IS_UTMS                         BIT(3)
+#define UFS_IS_UPMS                         BIT(4)
+#define UFS_IS_UHXS                         BIT(5)
+#define UFS_IS_UHES                         BIT(6)
+#define UFS_IS_ULLS                         BIT(7)
+#define UFS_IS_ULSS                         BIT(8)
+#define UFS_IS_UTMRCS                       BIT(9)
+#define UFS_IS_UCCS                         BIT(10)
+#define UFS_IS_DFES                         BIT(11)
+#define UFS_IS_UTPES                        BIT(12)
+#define UFS_IS_HCFES                        BIT(16)
+#define UFS_IS_SBFES                        BIT(17)
+
+/* Bit field for UFS_HCE register. */
+#define UFS_HCE_ENABLE                      BIT(0)
+
+#endif
diff --git a/platform/msm_shared/include/uic.h b/platform/msm_shared/include/uic.h
new file mode 100644
index 0000000..bc85241
--- /dev/null
+++ b/platform/msm_shared/include/uic.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 _UIC_H_
+#define _UIC_H_
+
+#include <sys/types.h>
+
+#define HCI_UIC_TIMEOUT                                  100000
+#define HCI_ENABLE_TIMEOUT                               100000
+
+enum uic_error_codes
+{
+	UIC_ERR_UNKNOWN,
+	UIC_ERR_TIMEOUT,
+};
+
+enum uic_gen_err_code
+{
+	UICCMD_SUCCESS,
+	UICCMD_FAILURE,
+};
+
+enum uic_num_cmd_args
+{
+	UICCMD_NO_ARGS    = 0,
+	UICCMD_ONE_ARGS   = 1,
+	UICCMD_TWO_ARGS   = 2,
+	UICCMD_THREE_ARGS = 4,
+};
+
+struct uic_cmd
+{
+	uint32_t uiccmd;
+	uint32_t num_args;
+	uint32_t uiccmdarg1;
+	uint32_t uiccmdarg2;
+	uint32_t uiccmdarg3;
+	uint32_t gen_err_code;
+	uint32_t timeout_msecs;
+};
+
+/* UFS init settings. */
+#define UFS_SYS1CLK_1US_VAL                              100
+#define UFS_TX_SYMBOL_CLK_1US_VAL                        1
+#define UFS_CLK_NS_REG_VAL                               10
+#define UFS_PA_LINK_STARTUP_TIMER_VAL                    20000000
+#define UFS_LINK_STARTUP_RETRY                           10
+
+#define SHFT_CLK_NS_REG                                  (10)
+
+int uic_init(struct ufs_dev *dev);
+int uic_send_cmd(struct ufs_dev *dev, struct uic_cmd *cmd);
+int uic_reset(struct ufs_dev *dev);
+
+
+#endif
diff --git a/platform/msm_shared/include/upiu.h b/platform/msm_shared/include/upiu.h
new file mode 100644
index 0000000..1c9968d
--- /dev/null
+++ b/platform/msm_shared/include/upiu.h
@@ -0,0 +1,164 @@
+/* Copyright (c) 2013, 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

+ * 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 The Linux Foundation 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 _UPIU_H

+#define _UPIU_H

+

+struct upiu_basic_hdr

+{

+	uint8_t  trans_type;

+	uint8_t  flags;

+	uint8_t  lun;

+	uint8_t  task_tag;

+	uint8_t  cmd_set_type;

+	uint8_t  query_task_mgmt_func;

+	uint8_t  response;

+	uint8_t  status;

+	uint8_t  total_ehs_len;

+	uint8_t  device_info;

+	uint16_t data_seg_len;

+} __PACKED;

+

+struct upiu_trans_mgmt_query_hdr

+{

+	struct upiu_basic_hdr basic_hdr;

+	uint8_t                   opcode;

+	uint8_t                   idn;

+	uint8_t                   index;

+	uint8_t                   selector;

+	uint8_t                   resv_0[2];

+	uint16_t                  resp_len;

+	uint8_t                   resv_1[3];

+	uint8_t                   flag_value;

+	uint8_t                   resv_2[4];

+}__PACKED;

+

+struct upiu_cmd_hdr

+{

+	struct upiu_basic_hdr basic_hdr;

+	uint32_t			      data_expected_len;	// Requested length

+	uint8_t				      param[16];			// Payload, operation specefic field

+}__PACKED;

+

+struct upiu_cmd_resp_hdr

+{

+	struct upiu_basic_hdr basic_hdr;

+	uint32_t			      residual_trans_count;

+	uint8_t				      resv_0[16];

+}__PACKED;

+

+struct upiu_gen_hdr

+{

+	struct upiu_basic_hdr basic_hdr;

+	uint8_t			          trans_specific_fields[20];

+}__PACKED;

+

+/* UPIU transaction codes. */

+enum upiu_trans_type

+{

+	UPIU_TYPE_NOP_OUT              = 0x00,

+	UPIU_TYPE_COMMAND              = 0x01,

+	UPIU_TYPE_TASK_MGMT            = 0x04,

+	UPIU_TYPE_QUERY_REQ            = 0x16,

+	UPIU_TYPE_NOP_IN               = 0x20,

+	UPIU_TYPE_RESPONSE             = 0x21,

+	UPIU_TYPE_TASK_MAN_RESP        = 0x24,

+	UPIU_TYPE_QUERY_RESP           = 0x36,

+	UPIU_TYPE_REJECT               = 0x3f,

+};

+

+/* UPIU respones */

+enum upiu_response

+{

+	UPIU_RESPONSE_TARGET_SUCCESS   = 0x00,

+	UPIU_RESPONSE_TARGET_FAILURE   = 0x01,

+};

+

+enum upiu_cmd_set_type

+{

+	UPIU_SCSI_CMD_SET           = 0,

+	UPIU_UFS_SPECIFIC_CMD_SET   = 1,

+};

+

+enum upiu_query_opcode_type

+{

+	UPIU_QUERY_OP_NOP              = 0x0,

+	UPIU_QUERY_OP_READ_DESCRIPTOR  = 0x1,

+	UPIU_QUERY_OP_WRITE_DESCRIPTOR = 0x2,

+	UPIU_QUERY_OP_READ_ATTRIBUTE   = 0x3,

+	UPIU_QUERY_OP_WRITE_ATTRIBUTE  = 0x4,

+	UPIU_QUERY_OP_READ_FLAG        = 0x5,

+	UPIU_QUERY_OP_SET_FLAG         = 0x6,

+	UPIU_QUERY_OP_CLEAR_FLAG       = 0x7,

+	UPIU_QUERY_OP_TOGGLE_FLAG      = 0x8,

+};

+

+enum upiu_cmd_type

+{

+	UTRD_SCSCI_CMD        = 0,

+	UTRD_NATIVE_UFS_CMD   = 1,

+	UTRD_DEV_MGMT_FUNC    = 2,

+};

+

+enum upiu_dd_type

+{

+	UTRD_NO_DATA_TRANSFER  = 0,

+	UTRD_SYSTEM_TO_TARGET  = 1,

+	UTRD_TARGET_TO_SYSTEM  = 2,

+};

+

+struct upiu_req_build_type

+{

+	enum upiu_trans_type        trans_type;

+	uint8_t                         flags;

+	uint8_t                         lun;

+	enum upiu_cmd_set_type      cmd_set_type;

+	uint8_t                         query_mgmt_func;

+	uint8_t                         ehs_len;

+	uint16_t                        data_seg_len;

+	addr_t                          data_buffer_addr;

+	uint32_t                        data_buffer_len;

+	addr_t                          cdb;

+	uint64_t                        expected_data_len;

+	enum upiu_query_opcode_type opcode;

+	uint8_t                         idn;

+	uint8_t                         index;

+	uint8_t                         selector;

+	struct upiu_basic_hdr       *resp_ptr;

+	uint64_t                        resp_len;

+	uint16_t                        resp_data_len;

+	addr_t                        resp_data_ptr;

+

+	/* UTRD properties. */

+	enum upiu_cmd_type          cmd_type;

+	enum upiu_dd_type           dd;

+	uint64_t                        timeout_msecs;

+};

+

+

+#endif

diff --git a/platform/msm_shared/include/utp.h b/platform/msm_shared/include/utp.h
new file mode 100644
index 0000000..4d70f16
--- /dev/null
+++ b/platform/msm_shared/include/utp.h
@@ -0,0 +1,149 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 _UTP_H_
+#define _UTP_H_
+
+#include <ufs_hci.h>
+#include <upiu.h>
+#include <ucs.h>
+#include <dme.h>
+
+/* UPIU general header length without the extra segments. */
+#define UPIU_HDR_LEN                                       0x20
+
+#define UTP_MAX_PRD_DATA_BYTE_CNT                          0x40000
+#define UTP_MAX_PRD_DATA_BYTE_CNT_BYTE_SHIFT               18
+#define UTP_MAX_PRD_TABLE_ENTRIES                          1024
+
+#define UTP_CMD_DESC_BASE_ALIGNMENT_SIZE                   128
+#define UTP_REQ_BUILD_CMD_DD_IRQ_FIELD(cmd, dd, irq)       ((cmd << 4) | (dd << 1) | irq)
+
+#define UTP_MUTEX_ACQUIRE_TIMEOUT                          0x100000
+
+#define UTP_GENERIC_CMD_TIMEOUT                            10000
+
+struct utp_prdt_entry
+{
+	uint32_t data_base_addr;
+	uint32_t data_upper_addr;
+	uint8_t  resv_0[4];
+	uint32_t data_byte_cnt;
+}__PACKED;
+
+struct utp_trans_req_desc
+{
+	uint8_t  resv_0[3];
+	uint8_t  cmd_type_dd_irq;
+	uint8_t  resv_1[4];
+	uint8_t  overall_cmd_status;
+	uint8_t  resv_2[7];
+	uint8_t  cmd_desc_base_addr[4];
+	uint8_t  cmd_desc_base_addr_upper[4];
+	uint16_t resp_upiu_len;
+	uint16_t resp_upiu_offset;
+	uint16_t prdt_len;
+	uint16_t prdt_offset;
+}__PACKED;
+
+enum utp_utrd_irq_type
+{
+	UTRD_REGULAR_CMD  = 0,
+	UTRD_IRQ_CMD      = 1,
+};
+
+enum utp_utrd_overall_status_type
+{
+	UTRD_OCS_SUCCESS                     = 0x0,
+	UTRD_OCS_INVALID_COM_TABLE_ATTR      = 0x1,
+	UTRD_OCS_INVALID_PRDT_ATTR           = 0x2,
+	UTRD_OCS_MISMATCH_DATA_BUFFER_SIZE   = 0x3,
+	UTRD_OCS_MISMATCH_RESPONSE_UPIU_SIZE = 0x4,
+	UTRD_OCS_COMMUNICATION_FAILURE       = 0x5,
+	UTRD_OCS_ABORTED                     = 0x6,
+	UTRD_OCS_INVALID_OCS_VALUE           = 0xf,
+};
+
+struct utp_utrd_req_build_type
+{
+	struct upiu_basic_hdr         *req_upiu;
+	uint32_t                          req_upiu_len;
+	uint32_t                          resp_upiu_len;
+	enum upiu_cmd_type            cmd_type;
+	enum upiu_dd_type             dd;
+	enum utp_utrd_irq_type            irq;
+	enum utp_utrd_overall_status_type ocs;
+	uint32_t                          prdt_offset;
+	uint32_t                          prdt_len;
+	uint32_t                          timeout;
+};
+
+struct utp_task_mgmt_req_desc
+{
+	uint8_t  resv_0[3];
+	uint8_t  irq;
+	uint8_t  resv_1[4];
+	uint8_t  overall_cmd_status;
+	uint8_t  resv_2[7];
+}__PACKED;
+
+enum utp_utmrd_irq_type
+{
+	NO_IRQ     = 0,
+	ENABLE_IRQ = 1,
+};
+
+enum utp_utmrd_overall_status_type
+{
+	UTMRD_OCS_SUCCESS                     = 0x0,
+	UTMRD_OCS_TASK_MGMT_FUNC_ATTR         = 0x1,
+	UTMRD_OCS_MISMATCH_TASK_MGMT_REQ_SIZE = 0x2,
+	UTMRD_OCS_MISMATCH_TASK_MGMT_RES_SIZE = 0x3,
+	UTMRD_OCS_PEER_COMM_FAILURE           = 0x4,
+	UTMRD_OCS_ABORTED                     = 0x5,
+	UTMRD_OCS_FATAL_ERR                   = 0x6,
+};
+
+struct utrd_cmd_desc
+{
+	struct upiu_gen_hdr *req_upiu;
+	uint32_t                resp_upiu_len;
+	uint32_t                num_prdt;
+};
+
+struct utp_bitmap_access_type
+{
+	uint32_t *bitmap;
+	uint32_t door_bell_bit;
+	mutex_t *mutx;
+};
+
+int utp_enqueue_upiu(struct ufs_dev *dev, struct upiu_req_build_type *upiu_data);
+void utp_process_req_completion(struct ufs_req_irq_type *irq);
+
+#endif
diff --git a/platform/msm_shared/mipi_dsi_phy.c b/platform/msm_shared/mipi_dsi_phy.c
index e3a4527..90e541a 100644
--- a/platform/msm_shared/mipi_dsi_phy.c
+++ b/platform/msm_shared/mipi_dsi_phy.c
@@ -213,154 +213,6 @@
 	udelay(1);
 }
 
-int mdss_dsi_uniphy_pll_config(uint32_t ctl_base)
-{
-	mdss_dsi_phy_sw_reset(ctl_base);
-
-	/* Configuring the Pll Vco clk to 424 Mhz */
-
-	/* Loop filter resistance value */
-	writel(0x08, ctl_base + 0x022c);
-	/* Loop filter capacitance values : c1 and c2 */
-	writel(0x70, ctl_base + 0x0230);
-	writel(0x15, ctl_base + 0x0234);
-
-	writel(0x02, ctl_base + 0x0208); /* ChgPump */
-	writel(0x00, ctl_base + 0x0204); /* postDiv1 */
-	writel(0x03, ctl_base + 0x0224); /* postDiv2 */
-	writel(0x05, ctl_base + 0x0228); /* postDiv3 */
-
-	writel(0x2b, ctl_base + 0x0278); /* Cal CFG3 */
-	writel(0x66, ctl_base + 0x027c); /* Cal CFG4 */
-	writel(0x05, ctl_base + 0x0264); /* LKDetect CFG2 */
-
-	writel(0x0a, ctl_base + 0x023c); /* SDM CFG1 */
-	writel(0xab, ctl_base + 0x0240); /* SDM CFG2 */
-	writel(0x0a, ctl_base + 0x0244); /* SDM CFG3 */
-	writel(0x00, ctl_base + 0x0248); /* SDM CFG4 */
-
-	udelay(10);
-
-	writel(0x01, ctl_base + 0x0200); /* REFCLK CFG */
-	writel(0x00, ctl_base + 0x0214); /* PWRGEN CFG */
-	writel(0x71, ctl_base + 0x020c); /* VCOLPF CFG */
-	writel(0x02, ctl_base + 0x0210); /* VREG CFG */
-	writel(0x00, ctl_base + 0x0238); /* SDM CFG0 */
-
-	writel(0x5f, ctl_base + 0x028c); /* CAL CFG8 */
-	writel(0xa8, ctl_base + 0x0294); /* CAL CFG10 */
-	writel(0x01, ctl_base + 0x0298); /* CAL CFG11 */
-	writel(0x0a, ctl_base + 0x026c); /* CAL CFG0 */
-	writel(0x30, ctl_base + 0x0284); /* CAL CFG6 */
-	writel(0x00, ctl_base + 0x0288); /* CAL CFG7 */
-	writel(0x00, ctl_base + 0x0290); /* CAL CFG9 */
-	writel(0x20, ctl_base + 0x029c); /* EFUSE CFG */
-
-	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(0x0f, ctl_base + 0x0220); /* GLB CFG */
-	mdelay(1);
-
-	mdss_dsi_uniphy_pll_lock_detect_setting(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);
-	}
-
-}
-
-int mdss_sharp_dsi_uniphy_pll_config(uint32_t ctl_base)
-{
-	mdss_dsi_phy_sw_reset(ctl_base);
-
-	/* Configuring the Pll Vco clk to 500 Mhz */
-
-	/* Loop filter resistance value */
-	writel(0x08, ctl_base + 0x022c);
-	/* Loop filter capacitance values : c1 and c2 */
-	writel(0x70, ctl_base + 0x0230);
-	writel(0x15, ctl_base + 0x0234);
-
-	writel(0x02, ctl_base + 0x0208); /* ChgPump */
-	writel(0x00, ctl_base + 0x0204); /* postDiv1 */
-	writel(0x03, ctl_base + 0x0224); /* postDiv2 */
-	writel(0x0b, ctl_base + 0x0228); /* postDiv3 */
-
-	writel(0x2b, ctl_base + 0x0278); /* Cal CFG3 */
-	writel(0x66, ctl_base + 0x027c); /* Cal CFG4 */
-	writel(0x05, ctl_base + 0x0264); /* LKDetect CFG2 */
-
-	writel(0x0c, ctl_base + 0x023c); /* SDM CFG1 */
-	writel(0x55, ctl_base + 0x0240); /* SDM CFG2 */
-	writel(0x05, ctl_base + 0x0244); /* SDM CFG3 */
-	writel(0x00, ctl_base + 0x0248); /* SDM CFG4 */
-
-	udelay(10);
-
-	writel(0x01, ctl_base + 0x0200); /* REFCLK CFG */
-	writel(0x00, ctl_base + 0x0214); /* PWRGEN CFG */
-	writel(0x01, ctl_base + 0x020c); /* VCOLPF CFG */
-	writel(0x02, ctl_base + 0x0210); /* VREG CFG */
-	writel(0x00, ctl_base + 0x0238); /* SDM CFG0 */
-
-	writel(0x60, ctl_base + 0x028c); /* CAL CFG8 */
-	writel(0xf4, ctl_base + 0x0294); /* CAL CFG10 */
-	writel(0x01, ctl_base + 0x0298); /* CAL CFG11 */
-	writel(0x0a, ctl_base + 0x026c); /* CAL CFG0 */
-	writel(0x30, ctl_base + 0x0284); /* CAL CFG6 */
-	writel(0x00, ctl_base + 0x0288); /* CAL CFG7 */
-	writel(0x00, ctl_base + 0x0290); /* CAL CFG9 */
-	writel(0x20, ctl_base + 0x029c); /* EFUSE CFG */
-
-	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(0x0f, ctl_base + 0x0220); /* GLB CFG */
-	mdelay(1);
-
-	mdss_dsi_uniphy_pll_lock_detect_setting(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);
-	}
-
-}
-
 int mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd)
 {
 	/* DSI0 and DSI1 have a common regulator */
diff --git a/platform/msm_shared/nand.c b/platform/msm_shared/nand.c
index 4030c34..d8df0eb 100644
--- a/platform/msm_shared/nand.c
+++ b/platform/msm_shared/nand.c
@@ -3460,17 +3460,22 @@
 }
 
 int
-flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data,
+flash_write(struct ptentry *ptn, unsigned write_extra_bytes, const void *data,
 	    unsigned bytes)
 {
 	unsigned page = ptn->start * num_pages_per_blk;
 	unsigned lastpage = (ptn->start + ptn->length) * num_pages_per_blk;
 	unsigned *spare = (unsigned *)flash_spare;
 	const unsigned char *image = data;
-	unsigned wsize = flash_pagesize + extra_per_page;
+	unsigned wsize;
 	unsigned n;
 	int r;
 
+	if(write_extra_bytes)
+		wsize = flash_pagesize + flash_info.spare_size;
+	else
+		wsize = flash_pagesize;
+
 	if ((flash_info.type == FLASH_ONENAND_DEVICE)
 	    && (ptn->type == TYPE_MODEM_PARTITION)) {
 		dprintf(CRITICAL, "flash_write_image: feature not supported\n");
@@ -3504,7 +3509,7 @@
 			}
 		}
 
-		if (extra_per_page) {
+		if (write_extra_bytes) {
 			r = _flash_write_page(flash_cmdlist, flash_ptrlist,
 					      page, image,
 					      image + flash_pagesize);
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index df8480d..ca3b123 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -63,6 +63,7 @@
 static struct flash_id supported_flash[] = {
 	/* Flash ID    ID Mask      Density(MB)    Wid Pgsz    Blksz              oobsz   8-bit ECCf */
 	{0x1590AC2C,   0xFFFFFFFF,  0x20000000,    0,  2048,   0x00020000,        0x40,   0},
+	{0x1590AA2C,   0xFFFFFFFF,  0x10000000,    0,  2048,   0x00020000,        0xE0,   1},
 	{0x2690AC2C,   0xFFFFFFFF,  0x20000000,    0,  4096,   0x00040000,        0xE0,   1},
 	{0x1590ACAD,   0xFFFFFFFF,  0x20000000,    0,  2048,   0x00020000,        0x80,   0},
 	/* Note: Width flag is 0 for 8 bit Flash and 1 for 16 bit flash   */
@@ -1611,7 +1612,7 @@
 
 int
 flash_write(struct ptentry *ptn,
-			unsigned extra_per_page,
+			unsigned write_extra_bytes,
 			const void *data,
 			unsigned bytes)
 {
@@ -1619,9 +1620,14 @@
 	uint32_t lastpage = (ptn->start + ptn->length) * flash.num_pages_per_blk;
 	uint32_t *spare = (unsigned *)flash_spare_bytes;
 	const unsigned char *image = data;
-	uint32_t wsize = flash.page_size + extra_per_page;
+	uint32_t wsize;
 	int r;
 
+	if(write_extra_bytes)
+		wsize = flash.page_size + flash.spare_size;
+	else
+		wsize = flash.page_size;
+
 	memset(spare, 0xff, (flash.spare_size / flash.cws_per_page));
 
 	while (bytes > 0)
@@ -1656,9 +1662,9 @@
 
 		memcpy(rdwr_buf, image, flash.page_size);
 
-		if (extra_per_page)
+		if (write_extra_bytes)
 		{
-			memcpy(rdwr_buf + flash.page_size, image + flash.page_size, extra_per_page);
+			memcpy(rdwr_buf + flash.page_size, image + flash.page_size, flash.spare_size);
 			r = qpic_nand_write_page(page,
 									 NAND_CFG,
 									 rdwr_buf,
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 00be808..e20a32d 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -189,7 +189,13 @@
             $(LOCAL_DIR)/qpic_nand.o \
             $(LOCAL_DIR)/dev_tree.o \
             $(LOCAL_DIR)/gpio.o \
-            $(LOCAL_DIR)/scm.o
+            $(LOCAL_DIR)/scm.o \
+			$(LOCAL_DIR)/ufs.o \
+			$(LOCAL_DIR)/utp.o \
+			$(LOCAL_DIR)/uic.o \
+			$(LOCAL_DIR)/ucs.o \
+			$(LOCAL_DIR)/ufs_hci.o \
+			$(LOCAL_DIR)/dme.o
 endif
 
 ifeq ($(PLATFORM),msm7x27a)
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
new file mode 100644
index 0000000..783737f
--- /dev/null
+++ b/platform/msm_shared/ucs.c
@@ -0,0 +1,282 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 <stdlib.h>
+#include <endian.h>
+#include <string.h>
+#include <utp.h>
+
+static int ucs_do_request_sense(struct ufs_dev *dev);
+
+int ucs_do_scsi_cmd(struct ufs_dev *dev, struct scsi_req_build_type *req)
+{
+	struct upiu_req_build_type req_upiu;
+	struct upiu_basic_hdr      resp_upiu;
+	int                        ret;
+
+	memset(&req_upiu, 0 , sizeof(struct upiu_req_build_type));
+
+	req_upiu.cmd_set_type	   = UPIU_SCSI_CMD_SET;
+	req_upiu.trans_type	       = UPIU_TYPE_COMMAND;
+	req_upiu.data_buffer_addr  = req->data_buffer_addr;
+	req_upiu.expected_data_len = req->data_len;
+	req_upiu.data_seg_len	   = 0;
+	req_upiu.ehs_len		   = 0;
+	req_upiu.flags			   = req->flags;
+	req_upiu.lun			   = req->lun;
+	req_upiu.query_mgmt_func   = 0;
+	req_upiu.cdb			   = req->cdb;
+	req_upiu.cmd_type		   = UTRD_SCSCI_CMD;
+	req_upiu.dd			       = req->dd;
+	req_upiu.resp_ptr		   = &resp_upiu;
+	req_upiu.resp_len		   = sizeof(resp_upiu);
+	req_upiu.timeout_msecs	   = UTP_GENERIC_CMD_TIMEOUT;
+
+	if (utp_enqueue_upiu(dev, &req_upiu))
+	{
+		dprintf(CRITICAL, "Data read failed\n");
+		return -UFS_FAILURE;
+	}
+
+	if (resp_upiu.status != SCSI_STATUS_GOOD)
+	{
+		if (resp_upiu.status == SCSI_STATUS_CHK_COND && (*((uint8_t *)(req->cdb)) != SCSI_CMD_SENSE_REQ))
+		{
+			ret = ucs_do_request_sense(dev);
+			if (ret)
+				dprintf(CRITICAL, "SCSI request sense failed.\n");
+		}
+
+		dprintf(CRITICAL, "SCSI read failed. status = %x\n", resp_upiu.status);
+		return -UFS_FAILURE;
+	}
+
+	return UFS_SUCCESS;
+}
+
+int ucs_do_scsi_read(struct ufs_dev *dev, struct scsi_rdwr_req *req)
+{
+	STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_rdwr_cdb));
+	struct scsi_req_build_type     req_upiu;
+	struct scsi_rdwr_cdb           *cdb_param;
+	uint32_t                       blks_remaining;
+	uint16_t                       blks_to_transfer;
+	uint64_t                       bytes_to_transfer;
+	uint32_t                       start_blk;
+	uint32_t                       buf;
+
+	blks_remaining = req->num_blocks;
+	buf            = req->data_buffer_base;
+	start_blk      = req->start_lba;
+
+	cdb_param = (struct scsi_rdwr_cdb*) cdb;
+	while (blks_remaining)
+	{
+		if (blks_remaining <= SCSI_MAX_DATA_TRANS_BLK_LEN)
+		{
+			blks_to_transfer = blks_remaining;
+			blks_remaining   = 0;
+		}
+		else
+		{
+			blks_to_transfer = SCSI_MAX_DATA_TRANS_BLK_LEN;
+			blks_remaining  -= SCSI_MAX_DATA_TRANS_BLK_LEN;
+		}
+
+		bytes_to_transfer = blks_to_transfer * UFS_DEFAULT_SECTORE_SIZE;
+
+		memset(cdb_param, 0, sizeof(struct scsi_rdwr_cdb));
+		cdb_param->opcode    = SCSI_CMD_READ10;
+		cdb_param->cdb1      = SCSI_READ_WRITE_10_CDB1(0, 0, 1, 0);
+		cdb_param->lba       = BE32(start_blk);
+		cdb_param->trans_len = BE16(blks_to_transfer);
+
+
+		dsb();
+		arch_clean_invalidate_cache_range((addr_t) cdb_param, sizeof(struct scsi_rdwr_cdb));
+
+		memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+		req_upiu.cdb               = (addr_t) cdb_param;
+		req_upiu.data_buffer_addr  = buf;
+		req_upiu.data_len = bytes_to_transfer;
+		req_upiu.flags             = UPIU_FLAGS_READ;
+		req_upiu.lun               = req->lun;
+		req_upiu.dd                = UTRD_TARGET_TO_SYSTEM;
+
+		if (ucs_do_scsi_cmd(dev, &req_upiu))
+		{
+			dprintf(CRITICAL, "Data read failed\n");
+			return -UFS_FAILURE;
+		}
+
+		buf       += bytes_to_transfer;
+		start_blk += SCSI_MAX_DATA_TRANS_BLK_LEN;
+	}
+
+	return UFS_SUCCESS;
+}
+
+int ucs_do_scsi_write(struct ufs_dev *dev, struct scsi_rdwr_req *req)
+{
+	struct scsi_req_build_type     req_upiu;
+	STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_rdwr_cdb));
+	struct scsi_rdwr_cdb           *cdb_param;
+	uint32_t                       blks_remaining;
+	uint16_t                       blks_to_transfer;
+	uint64_t                       bytes_to_transfer;
+	uint32_t                       start_blk;
+	uint32_t                       buf;
+
+	blks_remaining = req->num_blocks;
+	buf = req->data_buffer_base;
+	start_blk = req->start_lba;
+
+	cdb_param = (struct scsi_rdwr_cdb*) cdb;
+	while (blks_remaining)
+	{
+		if (blks_remaining <= SCSI_MAX_DATA_TRANS_BLK_LEN)
+		{
+			blks_to_transfer = blks_remaining;
+			blks_remaining   = 0;
+		}
+		else
+		{
+			blks_to_transfer = SCSI_MAX_DATA_TRANS_BLK_LEN;
+			blks_remaining  -= SCSI_MAX_DATA_TRANS_BLK_LEN;
+		}
+
+		bytes_to_transfer = blks_to_transfer * UFS_DEFAULT_SECTORE_SIZE;
+
+		memset(cdb_param, 0, sizeof(struct scsi_rdwr_cdb));
+		cdb_param->opcode    = SCSI_CMD_WRITE10;
+		cdb_param->cdb1      = SCSI_READ_WRITE_10_CDB1(0, 0, 1, 0);
+		cdb_param->lba       = BE32(start_blk);
+		cdb_param->trans_len = BE16(blks_to_transfer);
+
+		/* Flush cdb to memory. */
+		dsb();
+		arch_clean_invalidate_cache_range((addr_t) cdb_param, sizeof(struct scsi_rdwr_cdb));
+
+		memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+		req_upiu.cdb               = (addr_t) cdb_param;
+		req_upiu.data_buffer_addr  = buf;
+		req_upiu.data_len          = bytes_to_transfer;
+		req_upiu.flags             = UPIU_FLAGS_WRITE;
+		req_upiu.lun               = req->lun;
+		req_upiu.dd                = UTRD_SYSTEM_TO_TARGET;
+
+		if (ucs_do_scsi_cmd(dev, &req_upiu))
+		{
+			dprintf(CRITICAL, "Data read failed\n");
+			return -UFS_FAILURE;
+		}
+
+		buf       += bytes_to_transfer;
+		start_blk += SCSI_MAX_DATA_TRANS_BLK_LEN;
+	}
+
+	return UFS_SUCCESS;
+}
+
+int ucs_scsi_send_inquiry(struct ufs_dev *dev)
+{
+	STACKBUF_DMA_ALIGN(cdb_param, SCSI_CDB_PARAM_LEN);
+	STACKBUF_DMA_ALIGN(param, SCSI_INQUIRY_LEN);
+	struct scsi_req_build_type req_upiu;
+
+	memset(cdb_param, 0, SCSI_CDB_PARAM_LEN);
+	cdb_param[0] = SCSI_CMD_INQUIRY;
+	cdb_param[3] = sizeof(param)>> 8;
+	cdb_param[4] = sizeof(param);
+
+	/* Flush cdb to memory. */
+	dsb();
+	arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+
+	memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+	req_upiu.cdb			   = (addr_t) cdb_param;
+	req_upiu.data_buffer_addr  = (addr_t) param;
+	req_upiu.data_len          = SCSI_INQUIRY_LEN;
+	req_upiu.flags			   = UPIU_FLAGS_READ;
+	req_upiu.lun			   = 0;
+	req_upiu.dd			       = UTRD_TARGET_TO_SYSTEM;
+
+	if (ucs_do_scsi_cmd(dev, &req_upiu))
+	{
+		dprintf(CRITICAL, "Failed to send SCSI inquiry\n");
+		return -UFS_FAILURE;
+	}
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) param, SCSI_INQUIRY_LEN);
+
+	return UFS_SUCCESS;
+}
+
+static int ucs_do_request_sense(struct ufs_dev *dev)
+{
+	STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sense_cdb));
+	struct scsi_req_build_type req_upiu;
+	struct scsi_sense_cdb      *cdb_param;
+	uint8_t                    buf[SCSI_SENSE_BUF_LEN];
+
+	cdb_param = cdb;
+
+	memset(cdb, 0, sizeof(struct scsi_sense_cdb));
+
+	cdb_param->opcode    = SCSI_CMD_SENSE_REQ;
+	cdb_param->alloc_len = SCSI_SENSE_BUF_LEN;
+
+	/* Flush cdb to memory. */
+	dsb();
+	arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+
+	memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+	req_upiu.cdb			   = (addr_t) cdb_param;
+	req_upiu.data_buffer_addr  = (addr_t) buf;
+	req_upiu.data_len          = SCSI_SENSE_BUF_LEN;
+	req_upiu.flags			   = UPIU_FLAGS_READ;
+	req_upiu.lun			   = 0;
+	req_upiu.dd			       = UTRD_TARGET_TO_SYSTEM;
+
+	if (ucs_do_scsi_cmd(dev, &req_upiu))
+	{
+		dprintf(CRITICAL, "Data read failed\n");
+		return -UFS_FAILURE;
+	}
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) buf, SCSI_INQUIRY_LEN);
+
+	return UFS_SUCCESS;
+}
diff --git a/platform/msm_shared/ufs.c b/platform/msm_shared/ufs.c
new file mode 100644
index 0000000..b0470cd
--- /dev/null
+++ b/platform/msm_shared/ufs.c
@@ -0,0 +1,207 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 <ufs_hw.h>
+#include <utp.h>
+#include <upiu.h>
+#include <uic.h>
+#include <ucs.h>
+#include <dme.h>
+#include <string.h>
+#include <platform/iomap.h>
+#include <kernel/mutex.h>
+
+static int ufs_dev_init(struct ufs_dev *dev)
+{
+	/* Init the mutexes. */
+	mutex_init(&(dev->uic_data.uic_mutex));
+	mutex_init(&(dev->utrd_data.bitmap_mutex));
+	mutex_init(&(dev->utmrd_data.bitmap_mutex));
+
+	/* Initialize wait lists. */
+	list_initialize(&(dev->utrd_data.list_head.list_node));
+	list_initialize(&(dev->utmrd_data.list_head.list_node));
+
+	/* Initialize the bitmaps. */
+	dev->utrd_data.bitmap  = 0;
+	dev->utmrd_data.bitmap = 0;
+
+	/* Initialize task ids. */
+	dev->utrd_data.task_id  = 0;
+	dev->utmrd_data.task_id = 0;
+
+	/* Allocate memory for lists. */
+	dev->utrd_data.list_base_addr  = ufs_alloc_trans_req_list();
+	dev->utmrd_data.list_base_addr = ufs_alloc_task_mgmt_req_list();
+
+	if (!dev->utrd_data.list_base_addr || !dev->utmrd_data.list_base_addr)
+		return -UFS_FAILURE;
+
+	return UFS_SUCCESS;
+}
+
+static void ufs_setup_req_lists(struct ufs_dev *dev)
+{
+	uint32_t val;
+
+	writel(dev->utmrd_data.list_base_addr, UFS_UTMRLBA(dev->base));
+	writel(dev->utmrd_data.list_base_addr << 32, UFS_UTMRLBAU(dev->base));
+
+	writel(dev->utrd_data.list_base_addr, UFS_UTRLBA(dev->base));
+	writel(dev->utrd_data.list_base_addr << 32, UFS_UTRLBAU(dev->base));
+
+	writel(1, UFS_UTMRLRSR(dev->base));
+	writel(1, UFS_UTRLRSR(dev->base));
+
+	/* Enable the required irqs. */
+	val = UFS_IE_UTRCE | UFS_IE_UEE | UFS_IE_UTMRCE | UFS_IE_UCCE ;
+	ufs_irq_enable(dev, val);
+}
+
+int ufs_read(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks)
+{
+	struct scsi_rdwr_req req;
+	int                  ret;
+
+	req.data_buffer_base = buffer;
+	req.lun              = 0;
+	req.num_blocks       = num_blocks;
+	req.start_lba        = start_lba / dev->block_size;
+
+	ret = ucs_do_scsi_read(dev, &req);
+	if (ret)
+	{
+		dprintf(CRITICAL, "UFS read failed.\n");
+	}
+
+	return ret;
+}
+
+int ufs_write(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks)
+{
+	struct scsi_rdwr_req req;
+	int                  ret;
+
+	req.data_buffer_base = buffer;
+	req.lun              = 0;
+	req.num_blocks       = num_blocks;
+	req.start_lba        = start_lba / dev->block_size;
+
+	ret = ucs_do_scsi_write(dev, &req);
+	if (ret)
+	{
+		dprintf(CRITICAL, "UFS write failed.\n");
+	}
+
+	return ret;
+}
+uint64_t ufs_get_dev_capacity(struct ufs_dev* dev)
+{
+	uint64_t capacity;
+	int ret = 0;
+
+	ret = dme_read_unit_desc(dev, 0, &capacity);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to read unit descriptor\n");
+	}
+
+	return capacity;
+}
+
+uint32_t ufs_get_serial_num(struct ufs_dev* dev)
+{
+	int ret;
+
+	ret = dme_read_device_desc(dev);
+	if (ret)
+	{
+		dprintf(CRITICAL, "UFS get serial number failed.\n");
+	}
+
+	return dev->serial_num;
+}
+
+uint32_t ufs_get_page_size(struct ufs_dev* dev)
+{
+	return dev->block_size;
+}
+
+int ufs_init(struct ufs_dev *dev)
+{
+	uint32_t ret = UFS_SUCCESS;
+	uint64_t cap;
+
+	dev->block_size = 4096;
+
+	/* Init dev struct. */
+	ret = ufs_dev_init(dev);
+	if (ret != UFS_SUCCESS)
+	{
+		dprintf(CRITICAL, "UFS init failed\n");
+		goto ufs_init_err;
+	}
+
+	/* Perform Data link init. */
+	ret = uic_init(dev);
+	if (ret != UFS_SUCCESS)
+	{
+		dprintf(CRITICAL, "UFS init failed\n");
+		goto ufs_init_err;
+	}
+
+	/* Setup request lists. */
+	ufs_setup_req_lists(dev);
+
+	/* Send NOP to check if device UTP layer is ready. */
+	ret = dme_send_nop_query(dev);
+	if (ret != UFS_SUCCESS)
+	{
+		dprintf(CRITICAL, "UFS init failed\n");
+		goto ufs_init_err;
+	}
+
+	ret = dme_set_fdeviceinit(dev);
+    if (ret != UFS_SUCCESS)
+    {
+        dprintf(CRITICAL, "UFS init failed\n");
+        goto ufs_init_err;
+    }
+
+	ret = ucs_scsi_send_inquiry(dev);
+    if (ret != UFS_SUCCESS)
+    {
+        dprintf(CRITICAL, "UFS init failed\n");
+        goto ufs_init_err;
+    }
+
+ufs_init_err:
+	return ret;
+}
diff --git a/platform/msm_shared/ufs_hci.c b/platform/msm_shared/ufs_hci.c
new file mode 100644
index 0000000..479c0ff
--- /dev/null
+++ b/platform/msm_shared/ufs_hci.c
@@ -0,0 +1,174 @@
+/* Copyright (c) 2013, 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
+ * 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 The Linux Foundation 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 <arch/ops.h>
+#include <sys/types.h>
+#include <reg.h>
+#include <platform/interrupts.h>
+#include <platform/iomap.h>
+#include <platform/irqs.h>
+#include <ufs_hw.h>
+#include <utp.h>
+
+uint64_t ufs_alloc_trans_req_list()
+{
+	void *ptr;
+
+	ptr = memalign(lcm(CACHE_LINE, 1024), 32 * sizeof(struct utp_trans_req_desc));
+
+	if (!ptr)
+	{
+		dprintf(CRITICAL, "Failed to allocate utrd list.\n");
+	}
+
+	return (addr_t) ptr;
+}
+
+uint64_t ufs_alloc_task_mgmt_req_list()
+{
+	addr_t ptr = (addr_t) memalign(1024, 1024);
+
+	if (!ptr)
+	{
+		dprintf(CRITICAL, "Failed to allocate memory for Task mamagement request list.\n");
+	}
+
+	return ptr;
+}
+
+int ufs_enable_hci(struct ufs_dev *dev)
+{
+	int ret;
+
+	/* Enable host controller */
+	writel(UFS_HCE_ENABLE, UFS_HCE(dev->base));
+
+	/* Wait until host controller is enabled. */
+	ret = ufs_reg_target_val_timeout_loop(UFS_HCE(dev->base), 1, UFS_HCE_TIMEOUT);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to enable UFS host controller.\n");
+	}
+
+	return ret;
+}
+
+void ufs_irq_enable(struct ufs_dev *dev, uint32_t irq)
+{
+	/* Clear all irqs. */
+	writel(0xFFFFFFFF, UFS_IS(dev->base));
+
+	writel(irq, UFS_IE(dev->base));
+	register_int_handler(UFS_IRQ, ufs_irq_handler, dev);
+	unmask_interrupt(UFS_IRQ);
+}
+
+enum handler_return ufs_irq_handler(void* data)
+{
+	uint32_t       val;
+	struct ufs_dev *dev = (struct ufs_dev *) data;
+	struct ufs_req_irq_type irq;
+
+	val = readl(UFS_IS(dev->base));
+
+	if (val & UFS_IS_SBFES || val & UFS_IS_HCFES || val & UFS_IS_UTPES || val & UFS_IS_DFES || val & UFS_IS_UE)
+	{
+		/* Controller might be in a bad state, unrecoverable error. */
+		dprintf(CRITICAL, "UFS error\n");
+		ASSERT(0);
+	}
+
+	while (val)
+	{
+		irq.irq_handled = 0;
+
+		if (val & UFS_IS_UCCS)
+		{
+			/* UIC command */
+			event_signal(&(dev->uic_data.uic_event), false);
+			/* Clear irq. */
+			writel(UFS_IS_UCCS, UFS_IS(dev->base));
+			val        &= ~UFS_IS_UCCS;
+			irq.irq_handled = UFS_IS_UCCS;
+			continue;
+		}
+		else if (val & UFS_IS_UTRCS)
+		{
+			/* UTRD completion. */
+			irq.list           = &(dev->utrd_data.list_head.list_node);
+			irq.irq_handled    = UFS_IS_UTRCS;
+			irq.door_bell_reg  = UFS_UTRLDBR(dev->base);
+
+			/* Clear irq. */
+			writel(irq.irq_handled, UFS_IS(dev->base));
+			val	   &= ~irq.irq_handled;
+
+			utp_process_req_completion(&irq);
+		}
+		else if (val & UFS_IS_UTMRCS)
+		{
+			/* UTMRD completion. */
+			irq.list = &(dev->utmrd_data.list_head.list_node);
+			irq.irq_handled = UFS_IS_UTMRCS;
+			/* TODO: Fill in door bell reg for management requests. */
+
+			/* Clear irq. */
+			writel(irq.irq_handled, UFS_IS(dev->base));
+			val	   &= ~irq.irq_handled;
+
+			utp_process_req_completion(&irq);
+		}
+		else
+		{
+			dprintf(CRITICAL, "Unknown irq.\n");
+			ASSERT(0);
+		}
+	}
+
+	return INT_NO_RESCHEDULE;
+}
+
+int ufs_reg_target_val_timeout_loop(uint32_t reg_addr, uint32_t target_val, uint32_t timeout)
+{
+	uint32_t try_again;
+	uint32_t val;
+
+	try_again = timeout;
+
+	do
+	{
+		try_again--;
+		val = readl(reg_addr);
+		} while (!(val & target_val) && try_again);
+
+	if (!(val & target_val))
+		return -UFS_FAILURE;
+	else
+		return UFS_SUCCESS;
+}
diff --git a/platform/msm_shared/uic.c b/platform/msm_shared/uic.c
new file mode 100644
index 0000000..3ba35b5
--- /dev/null
+++ b/platform/msm_shared/uic.c
Binary files differ
diff --git a/platform/msm_shared/utp.c b/platform/msm_shared/utp.c
new file mode 100644
index 0000000..c7d30ff
--- /dev/null
+++ b/platform/msm_shared/utp.c
Binary files differ
diff --git a/target/msm8226/include/target/display.h b/target/msm8226/include/target/display.h
index 1121591..62f0eac 100755
--- a/target/msm8226/include/target/display.h
+++ b/target/msm8226/include/target/display.h
@@ -98,7 +98,7 @@
 
 #define msm8226_DSI_FEATURE_ENABLE 0
 
-#define MIPI_FB_ADDR  0x0F100000
+#define MIPI_FB_ADDR  0x03200000
 
 #define MIPI_HSYNC_PULSE_WIDTH       12
 #define MIPI_HSYNC_BACK_PORCH_DCLK   32
@@ -109,5 +109,4 @@
 #define MIPI_VSYNC_FRONT_PORCH_LINES 9
 
 extern int mdss_dsi_phy_init(struct mipi_dsi_panel_config *, uint32_t ctl_base);
-extern int mdss_dsi_uniphy_pll_config(uint32_t ctl_base);
 #endif
diff --git a/target/msm8974/include/target/display.h b/target/msm8974/include/target/display.h
index ae2b01e..8897239 100644
--- a/target/msm8974/include/target/display.h
+++ b/target/msm8974/include/target/display.h
@@ -89,8 +89,8 @@
 /* Other Configuration                                                       */
 /*---------------------------------------------------------------------------*/
 
-#define MIPI_FB_ADDR  0x0D200000
-#define EDP_FB_ADDR   0x7EF00000
+#define MIPI_FB_ADDR  0x03200000
+#define EDP_FB_ADDR   MIPI_FB_ADDR
 
 #define MIPI_HSYNC_PULSE_WIDTH       12
 #define MIPI_HSYNC_BACK_PORCH_DCLK   32
@@ -101,6 +101,5 @@
 #define MIPI_VSYNC_FRONT_PORCH_LINES 9
 
 extern int mdss_dsi_phy_init(struct mipi_dsi_panel_config *, uint32_t ctl_base);
-extern int mdss_dsi_uniphy_pll_config(uint32_t ctl_base);
 
 #endif
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index 7b35aa0..e02ea22 100644
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -126,11 +126,11 @@
 	if (enable) {
 		mdp_gdsc_ctrl(enable);
 		mdp_clock_init();
-		mdss_dsi_uniphy_pll_config(MIPI_DSI0_BASE);
+		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_uniphy_pll_config(MIPI_DSI1_BASE);
+			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,