Merge "target: msm8226: select JDI 1080p panel for 8926 v2 devices"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 7cd33ad..a578cc3 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -111,7 +111,6 @@
 #endif
 static const char *usb_sn_cmdline = " androidboot.serialno=";
 static const char *androidboot_mode = " androidboot.mode=";
-static const char *display_cmdline = " mdss_mdp.panel=";
 static const char *loglevel         = " quiet";
 static const char *battchg_pause = " androidboot.mode=charger";
 static const char *auth_kernel = " androidboot.authorized_kernel=true";
@@ -330,7 +329,6 @@
 	if (target_display_panel_node(display_panel_buf, MAX_PANEL_BUF_SIZE) &&
 	    strlen(display_panel_buf))
 	{
-		cmdline_len += strlen(display_cmdline);
 		cmdline_len += strlen(display_panel_buf);
 	}
 
@@ -457,9 +455,6 @@
 		}
 
 		if (strlen(display_panel_buf)) {
-			src = display_cmdline;
-			if (have_cmdline) --dst;
-			while ((*dst++ = *src++));
 			src = display_panel_buf;
 			if (have_cmdline) --dst;
 			while ((*dst++ = *src++));
@@ -1276,6 +1271,7 @@
 	unsigned long long size;
 	int index = INVALID_PTN;
 	uint32_t blocksize;
+	uint8_t lun = 0;
 
 	index = partition_get_index("aboot");
 	ptn = partition_get_offset(index);
@@ -1284,6 +1280,9 @@
 		return;
 	}
 
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
 	size = partition_get_size(index);
 
 	memcpy(info, dev, sizeof(device_info));
@@ -1632,6 +1631,7 @@
 	unsigned long long ptn = 0;
 	unsigned long long size = 0;
 	int index = INVALID_PTN;
+	uint8_t lun = 0;
 
 	index = partition_get_index(arg);
 	ptn = partition_get_offset(index);
@@ -1642,6 +1642,9 @@
 		return;
 	}
 
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
 #if MMC_SDHCI_SUPPORT
 	if (mmc_erase_card(ptn, size)) {
 		fastboot_fail("failed to erase partition\n");
@@ -1668,8 +1671,22 @@
 	unsigned long long ptn = 0;
 	unsigned long long size = 0;
 	int index = INVALID_PTN;
+	char *token = NULL;
+	char *pname = NULL;
+	uint8_t lun = 0;
+	bool lun_set = false;
 
-	if (!strcmp(arg, "partition"))
+	token = strtok(arg, ":");
+	pname = token;
+	token = strtok(NULL, ":");
+	if(token)
+	{
+		lun = atoi(token);
+		mmc_set_lun(lun);
+		lun_set = true;
+	}
+
+	if (!strcmp(pname, "partition"))
 	{
 		dprintf(INFO, "Attempt to write partition image.\n");
 		if (write_partition(sz, (unsigned char *) data)) {
@@ -1679,20 +1696,26 @@
 	}
 	else
 	{
-		index = partition_get_index(arg);
+		index = partition_get_index(pname);
 		ptn = partition_get_offset(index);
 		if(ptn == 0) {
 			fastboot_fail("partition table doesn't exist");
 			return;
 		}
 
-		if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) {
+		if (!strcmp(pname, "boot") || !strcmp(pname, "recovery")) {
 			if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
 				fastboot_fail("image is not a boot image");
 				return;
 			}
 		}
 
+		if(!lun_set)
+		{
+			lun = partition_get_lun(index);
+			mmc_set_lun(lun);
+		}
+
 		size = partition_get_size(index);
 		if (ROUND_TO_PAGE(sz,511) > size) {
 			fastboot_fail("size too large");
@@ -1721,6 +1744,7 @@
 	unsigned long long size = 0;
 	int index = INVALID_PTN;
 	int i;
+	uint8_t lun = 0;
 
 	index = partition_get_index(arg);
 	ptn = partition_get_offset(index);
@@ -1735,6 +1759,9 @@
 		return;
 	}
 
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
 	/* Read and skip over sparse image header */
 	sparse_header = (sparse_header_t *) data;
 	if ((sparse_header->total_blks * sparse_header->blk_sz) > size) {
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index 3c1ff7b..09da146 100755
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -169,6 +169,7 @@
 	bool ret = true;
 	char *default_str;
 	int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG;
+	int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
 
 	if (panelstruct.paneldata)
 	{
@@ -188,6 +189,18 @@
 		{
 			default_str = "0:dsi:0:";
 		}
+
+		arg_size = prefix_string_len + strlen(default_str);
+		if (buf_size < arg_size)
+		{
+			dprintf(CRITICAL, "display command line buffer is small\n");
+			return false;
+		}
+
+		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
+		pbuf += prefix_string_len;
+		buf_size -= prefix_string_len;
+
 		strlcpy(pbuf, default_str, buf_size);
 		return true;
 	}
@@ -206,7 +219,8 @@
 	panel_node_len = strlen(panel_node);
 	slave_panel_node_len = strlen(slave_panel_node);
 
-	arg_size = dsi_id_len + panel_node_len + LK_OVERRIDE_PANEL_LEN + 1;
+	arg_size = prefix_string_len + dsi_id_len + panel_node_len +
+						LK_OVERRIDE_PANEL_LEN + 1;
 
 	/* For dual pipe or split display */
 	if (panel_mode)
@@ -219,6 +233,10 @@
 	}
 	else
 	{
+		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
+		pbuf += prefix_string_len;
+		buf_size -= prefix_string_len;
+
 		strlcpy(pbuf, LK_OVERRIDE_PANEL, buf_size);
 		pbuf += LK_OVERRIDE_PANEL_LEN;
 		buf_size -= LK_OVERRIDE_PANEL_LEN;
diff --git a/platform/msm_shared/dme.c b/platform/msm_shared/dme.c
index bc564f2..670d344 100644
--- a/platform/msm_shared/dme.c
+++ b/platform/msm_shared/dme.c
@@ -268,7 +268,7 @@
 	return UFS_SUCCESS;
 }
 
-int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index, uint64_t *capacity)
+int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index)
 {
 	STACKBUF_DMA_ALIGN(unit_desc, sizeof(struct ufs_unit_desc));
 	struct ufs_unit_desc           *desc = unit_desc;
@@ -285,7 +285,9 @@
 	/* Flush buffer. */
 	arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_unit_desc));
 
-	*capacity = BE64(desc->logical_blk_cnt) * dev->block_size;
+	dev->lun_cfg[index].logical_blk_cnt = BE64(desc->logical_blk_cnt);
+
+	dev->lun_cfg[index].erase_blk_size = BE32(desc->erase_blk_size);
 
 	return UFS_SUCCESS;
 }
diff --git a/platform/msm_shared/include/dme.h b/platform/msm_shared/include/dme.h
index c93e23a..31be6c5 100644
--- a/platform/msm_shared/include/dme.h
+++ b/platform/msm_shared/include/dme.h
@@ -147,27 +147,6 @@
 	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;
@@ -242,6 +221,6 @@
 								  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);
+int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index);
 
 #endif
diff --git a/platform/msm_shared/include/mmc_wrapper.h b/platform/msm_shared/include/mmc_wrapper.h
index a05b42b..57f74a0 100644
--- a/platform/msm_shared/include/mmc_wrapper.h
+++ b/platform/msm_shared/include/mmc_wrapper.h
@@ -1,4 +1,4 @@
-/* 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 are
@@ -45,4 +45,7 @@
 uint32_t mmc_get_device_blocksize();
 uint32_t mmc_page_size();
 void mmc_device_sleep();
+void mmc_set_lun(uint8_t lun);
+uint8_t mmc_get_lun(void);
+void  mmc_read_partition_table(uint8_t arg);
 #endif
diff --git a/platform/msm_shared/include/partition_parser.h b/platform/msm_shared/include/partition_parser.h
index bbd8422..cf89433 100644
--- a/platform/msm_shared/include/partition_parser.h
+++ b/platform/msm_shared/include/partition_parser.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -155,11 +155,13 @@
 	unsigned long long size;
 	unsigned long long attribute_flag;
 	unsigned char name[MAX_GPT_NAME_SIZE];
+	uint8_t lun;
 };
 
 int partition_get_index(const char *name);
 unsigned long long partition_get_size(int index);
 unsigned long long partition_get_offset(int index);
+uint8_t partition_get_lun(int index);
 unsigned int partition_read_table();
 unsigned int write_partition(unsigned size, unsigned char *partition);
 bool partition_gpt_exists();
diff --git a/platform/msm_shared/include/sdhci_msm.h b/platform/msm_shared/include/sdhci_msm.h
index bc36348..93a8457 100644
--- a/platform/msm_shared/include/sdhci_msm.h
+++ b/platform/msm_shared/include/sdhci_msm.h
@@ -1,4 +1,4 @@
-/* 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 are
@@ -110,5 +110,5 @@
 
 void sdhci_msm_init(struct sdhci_host *host, struct sdhci_msm_data *data);
 uint32_t sdhci_msm_execute_tuning(struct sdhci_host *host, uint32_t bus_width);
-
+void sdhci_mode_disable(struct sdhci_host *host);
 #endif
diff --git a/platform/msm_shared/include/ucs.h b/platform/msm_shared/include/ucs.h
index 5a7d7b9..e4d366e 100644
--- a/platform/msm_shared/include/ucs.h
+++ b/platform/msm_shared/include/ucs.h
@@ -29,7 +29,7 @@
 #ifndef _UCS_H
 #define _UCS_H
 
-#define SCSI_MAX_DATA_TRANS_BLK_LEN    0x40
+#define SCSI_MAX_DATA_TRANS_BLK_LEN    0xFFFF
 #define UFS_DEFAULT_SECTORE_SIZE       4096
 
 #define SCSI_STATUS_GOOD               0x00
@@ -98,6 +98,28 @@
 	uint8_t  resv[6];
 }__PACKED;
 
+struct scsi_unmap_req
+{
+	uint8_t  lun;
+	uint64_t start_lba;
+	uint32_t num_blocks;
+}__PACKED;
+
+struct unmap_blk_desc
+{
+	uint64_t lba;
+	uint32_t num_blks;
+	uint32_t reserved;
+}__PACKED;
+
+struct unmap_param_list
+{
+	uint16_t data_len;
+	uint16_t blk_desc_data_len;
+	uint32_t reserved;
+	struct unmap_blk_desc blk_desc;
+}__PACKED;
+
 struct scsi_sense_cdb
 {
 	uint8_t  opcode;
diff --git a/platform/msm_shared/include/ufs.h b/platform/msm_shared/include/ufs.h
index e5578bd..bbe9a40 100644
--- a/platform/msm_shared/include/ufs.h
+++ b/platform/msm_shared/include/ufs.h
@@ -65,13 +65,38 @@
 	event_t  uic_event;
 };
 
+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_dev
 {
 	uint8_t                      instance;
 	uint32_t                     base;
 	uint8_t                      num_lus;
-	uint32_t                      serial_num;
+	uint8_t                      current_lun;
+	uint32_t                     serial_num;
 	uint32_t                     block_size;
+	uint32_t                     erase_blk_size;
+	uint64_t                     capacity;
+	struct ufs_unit_desc         lun_cfg[8];
 
 	/* UTRD maintainance data structures.*/
 	struct ufs_utp_req_meta_data utrd_data;
@@ -90,7 +115,10 @@
 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);
+int ufs_erase(struct ufs_dev* dev, uint64_t start_lba, uint32_t num_blocks);
 uint64_t ufs_get_dev_capacity(struct ufs_dev* dev);
 uint32_t ufs_get_serial_num(struct ufs_dev* dev);
-
+uint8_t ufs_get_num_of_luns(struct ufs_dev* dev);
+uint32_t ufs_get_erase_blk_size(struct ufs_dev* dev);
+void ufs_dump_hc_registers(struct ufs_dev* dev);
 #endif
diff --git a/platform/msm_shared/include/ufs_hw.h b/platform/msm_shared/include/ufs_hw.h
index cf4da12..9b06a42 100644
--- a/platform/msm_shared/include/ufs_hw.h
+++ b/platform/msm_shared/include/ufs_hw.h
@@ -41,6 +41,9 @@
 #define UFS_HCE(_base)                             (_base + 0x00000034)
 #define UFS_UECPA(_base)                           (_base + 0x00000038)
 #define UFS_UECDL(_base)                           (_base + 0x0000003C)
+#define UFS_UECN(_base)                            (_base + 0x00000040)
+#define UFS_UECT(_base)                            (_base + 0x00000044)
+#define UFS_UECDME(_base)                          (_base + 0x00000048)
 #define UFS_UTRIACR(_base)                         (_base + 0x0000004C)
 #define UFS_UTRLBA(_base)                          (_base + 0x00000050)
 #define UFS_UTRLBAU(_base)                         (_base + 0x00000054)
diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index 46ce941..29eeaee 100644
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -1,4 +1,4 @@
-/* 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 are
@@ -66,6 +66,21 @@
 	return 0;
 }
 
+__WEAK uint32_t ufs_get_erase_blk_size(struct ufs_dev *dev)
+{
+	return 0;
+}
+
+__WEAK int ufs_erase(struct ufs_dev* dev, uint64_t start_lba, uint32_t num_blocks)
+{
+	return 0;
+}
+
+__WEAK uint8_t ufs_get_num_of_luns(struct ufs_dev* dev)
+{
+	return 0;
+}
+
 /*
  * Function: get mmc card
  * Arg     : None
@@ -208,6 +223,7 @@
 	return ret;
 }
 
+
 /*
  * Function: mmc get erase unit size
  * Arg     : None
@@ -306,20 +322,21 @@
 	uint32_t blk_count;
 	uint64_t blks_to_erase;
 
+	block_size = mmc_get_device_blocksize();
+
+	dev = target_mmc_device();
+
+	ASSERT(!(addr % block_size));
+	ASSERT(!(len % block_size));
+
 	if (target_boot_device_emmc())
 	{
-		block_size = mmc_get_device_blocksize();
 		erase_unit_sz = mmc_get_eraseunit_size();
 		dprintf(SPEW, "erase_unit_sz:0x%x\n", erase_unit_sz);
 
-		ASSERT(!(addr % block_size));
-		ASSERT(!(len % block_size));
-
 		blk_addr = addr / block_size;
 		blk_count = len / block_size;
 
-		dev = target_mmc_device();
-
 		dprintf(INFO, "Erasing card: 0x%x:0x%x\n", blk_addr, blk_count);
 
 		head_unit = blk_addr / erase_unit_sz;
@@ -363,6 +380,14 @@
 		}
 
 	}
+	else
+	{
+		if(ufs_erase((struct ufs_dev *)dev, addr, (len / block_size)))
+		{
+			dprintf(CRITICAL, "mmc_erase_card: UFS erase failed\n");
+			return 1;
+		}
+	}
 
 	return 0;
 }
@@ -483,3 +508,72 @@
 		mmc_put_card_to_sleep((struct mmc_device *)dev);
 	}
 }
+
+/*
+ * Function     : mmc set LUN for ufs
+ * Arg          : LUN number
+ * Return type  : void
+ */
+void mmc_set_lun(uint8_t lun)
+{
+	void *dev;
+	dev = target_mmc_device();
+
+	if (!target_boot_device_emmc())
+	{
+		((struct ufs_dev*)dev)->current_lun = lun;
+	}
+}
+
+/*
+ * Function     : mmc get LUN from ufs
+ * Arg          : LUN number
+ * Return type  : lun number for UFS and 0 for emmc
+ */
+uint8_t mmc_get_lun(void)
+{
+	void *dev;
+	uint8_t lun=0;
+
+	dev = target_mmc_device();
+
+	if (!target_boot_device_emmc())
+	{
+		lun = ((struct ufs_dev*)dev)->current_lun;
+	}
+
+	return lun;
+}
+
+void mmc_read_partition_table(uint8_t arg)
+{
+	void *dev;
+	uint8_t lun = 0;
+	uint8_t max_luns;
+
+	dev = target_mmc_device();
+
+	if(!target_boot_device_emmc())
+	{
+		max_luns = ufs_get_num_of_luns((struct ufs_dev*)dev);
+
+		ASSERT(max_luns);
+
+		for(lun = arg; lun < max_luns; lun++)
+		{
+			mmc_set_lun(lun);
+
+			if(partition_read_table())
+			{
+				dprintf(CRITICAL, "Error reading the partition table info for lun %d\n", lun);
+			}
+		}
+	}
+	else
+	{
+		if(partition_read_table())
+		{
+			dprintf(CRITICAL, "Error reading the partition table info\n");
+		}
+	}
+}
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 6facb93..5534024 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -31,6 +31,24 @@
 #include "mmc.h"
 #include "partition_parser.h"
 
+__WEAK void mmc_set_lun(uint8_t lun)
+{
+}
+
+__WEAK uint8_t mmc_get_lun(void)
+{
+	return 0;
+}
+
+__WEAK void mmc_read_partition_table(uint8_t arg)
+{
+	if(partition_read_table())
+	{
+		dprintf(CRITICAL, "Error reading the partition table info\n");
+		ASSERT(0);
+	}
+}
+
 static uint32_t mmc_boot_read_gpt(uint32_t block_size);
 static uint32_t mmc_boot_read_mbr(uint32_t block_size);
 static void mbr_fill_name(struct partition_entry *partition_ent,
@@ -60,7 +78,7 @@
 
 struct partition_entry *partition_entries;
 static unsigned gpt_partitions_exist = 0;
-unsigned partition_count = 0;
+static unsigned partition_count;
 
 unsigned int partition_read_table()
 {
@@ -70,8 +88,11 @@
 	block_size = mmc_get_device_blocksize();
 
 	/* Allocate partition entries array */
-	partition_entries = (struct partition_entry *) calloc(NUM_PARTITIONS, sizeof(struct partition_entry));
-	ASSERT(partition_entries);
+	if(!partition_entries)
+	{
+		partition_entries = (struct partition_entry *) calloc(NUM_PARTITIONS, sizeof(struct partition_entry));
+		ASSERT(partition_entries);
+	}
 
 	/* Read MBR of the card */
 	ret = mmc_boot_read_mbr(block_size);
@@ -130,7 +151,6 @@
 	 * Process each of the four partitions in the MBR by reading the table
 	 * information into our mbr table.
 	 */
-	partition_count = 0;
 	idx = TABLE_ENTRY_0;
 	for (i = 0; i < 4; i++) {
 		/* Type 0xEE indicates end of MBR and GPT partitions exist */
@@ -239,8 +259,6 @@
 	uint8_t *data = NULL;
 	uint32_t part_entry_cnt = block_size / ENTRY_SIZE;
 
-	partition_count = 0;
-
 	/* Get the density of the mmc device */
 
 	device_density = mmc_get_device_capacity();
@@ -343,6 +361,8 @@
 			memcpy(UTF16_name, &data[(j * partition_entry_size) +
 						 PARTITION_NAME_OFFSET],
 			       MAX_GPT_NAME_SIZE);
+			partition_entries[partition_count].lun = mmc_get_lun();
+
 			/*
 			 * Currently partition names in *.xml are UTF-8 and lowercase
 			 * Only supporting english for now so removing 2nd byte of UTF-16
@@ -719,12 +739,8 @@
 
 	/* Re-read the GPT partition table */
 	dprintf(INFO, "Re-reading the GPT Partition Table\n");
-	ret = mmc_boot_read_gpt(block_size);
-	if (ret) {
-		dprintf(CRITICAL,
-			"GPT: Failure to re- read the GPT Partition table\n");
-		goto end;
-	}
+	partition_count = 0;
+	mmc_read_partition_table(0);
 	partition_dump();
 	dprintf(CRITICAL, "GPT: Partition Table written\n");
 	memset(primary_gpt_header, 0x00, size);
@@ -894,6 +910,11 @@
 	}
 }
 
+uint8_t partition_get_lun(int index)
+{
+	return partition_entries[index].lun;
+}
+
 /* Debug: Print all parsed partitions */
 void partition_dump()
 {
diff --git a/platform/msm_shared/sdhci_msm.c b/platform/msm_shared/sdhci_msm.c
index 9c1129a..fb278a7 100644
--- a/platform/msm_shared/sdhci_msm.c
+++ b/platform/msm_shared/sdhci_msm.c
@@ -1,4 +1,4 @@
-/* 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 are
@@ -623,3 +623,13 @@
 	host->msm_host->tuning_done = true;
 	return ret;
 }
+
+/*
+ * API to disable HC mode
+ */
+void sdhci_mode_disable(struct sdhci_host *host)
+{
+	/* Disable HC mode */
+	RMWREG32((host->msm_host->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0);
+}
+
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
index 783737f..1e03410 100644
--- a/platform/msm_shared/ucs.c
+++ b/platform/msm_shared/ucs.c
@@ -60,7 +60,7 @@
 
 	if (utp_enqueue_upiu(dev, &req_upiu))
 	{
-		dprintf(CRITICAL, "Data read failed\n");
+		dprintf(CRITICAL, "ucs_do_scsi_cmd: enqueue failed\n");
 		return -UFS_FAILURE;
 	}
 
@@ -73,7 +73,7 @@
 				dprintf(CRITICAL, "SCSI request sense failed.\n");
 		}
 
-		dprintf(CRITICAL, "SCSI read failed. status = %x\n", resp_upiu.status);
+		dprintf(CRITICAL, "ucs_do_scsi_cmd failed status = %x\n", resp_upiu.status);
 		return -UFS_FAILURE;
 	}
 
@@ -132,7 +132,7 @@
 
 		if (ucs_do_scsi_cmd(dev, &req_upiu))
 		{
-			dprintf(CRITICAL, "Data read failed\n");
+			dprintf(CRITICAL, "ucs_do_scsi_read: failed\n");
 			return -UFS_FAILURE;
 		}
 
@@ -195,7 +195,7 @@
 
 		if (ucs_do_scsi_cmd(dev, &req_upiu))
 		{
-			dprintf(CRITICAL, "Data read failed\n");
+			dprintf(CRITICAL, "ucs_do_scsi_write: failed\n");
 			return -UFS_FAILURE;
 		}
 
@@ -206,6 +206,58 @@
 	return UFS_SUCCESS;
 }
 
+int ucs_do_scsi_unmap(struct ufs_dev *dev, struct scsi_unmap_req *req)
+{
+	STACKBUF_DMA_ALIGN(cdb_param, SCSI_CDB_PARAM_LEN);
+	STACKBUF_DMA_ALIGN(param, sizeof(struct unmap_param_list));
+	struct scsi_req_build_type req_upiu;
+	struct unmap_param_list *param_list;
+	struct unmap_blk_desc *blk_desc;
+
+	param_list                    = (struct unmap_param_list *)param;
+	param_list->data_len          = (sizeof(struct unmap_param_list) - 1) << 0x8; /* n-1 */
+
+	param_list->blk_desc_data_len = sizeof(struct unmap_blk_desc) << 0x8;
+
+
+	blk_desc = &(param_list->blk_desc);
+
+	blk_desc->lba      = BE64(req->start_lba);
+	blk_desc->num_blks = BE32(req->num_blocks);
+
+	memset((void*)cdb_param, 0, SCSI_CDB_PARAM_LEN);
+	cdb_param[0] = SCSI_CMD_UNMAP;
+	cdb_param[1] = 0;                    /*ANCHOR = 0 for UFS*/
+	cdb_param[6] = 0;                    /*Group No = 0*/
+	cdb_param[7] = 0;                    /* Param list length is 1, we erase 1 contiguous blk*/
+	cdb_param[8] = sizeof(struct unmap_param_list);
+	cdb_param[9] = 0;
+
+        /* Flush cdb to memory. */
+	dsb();
+	arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+
+	memset((void*)&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                  = sizeof(struct unmap_param_list);
+	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, "Failed to send SCSI unmap command \n");
+		return -UFS_FAILURE;
+	}
+
+	/* Flush buffer. */
+	arch_invalidate_cache_range((addr_t) param, SCSI_INQUIRY_LEN);
+
+	return UFS_SUCCESS;
+}
+
 int ucs_scsi_send_inquiry(struct ufs_dev *dev)
 {
 	STACKBUF_DMA_ALIGN(cdb_param, SCSI_CDB_PARAM_LEN);
@@ -242,6 +294,17 @@
 	return UFS_SUCCESS;
 }
 
+void dump_sense_buffer(uint8_t *buf, int buf_len)
+{
+	int index=0;
+
+	dprintf(CRITICAL,"----Sense buffer----\n");
+	for(index=0; index < buf_len; index++)
+		dprintf(CRITICAL,"buf[%d] = %x\n",index, buf[index]);
+
+	dprintf(CRITICAL,"----end of buffer---\n");
+}
+
 static int ucs_do_request_sense(struct ufs_dev *dev)
 {
 	STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sense_cdb));
@@ -271,12 +334,14 @@
 
 	if (ucs_do_scsi_cmd(dev, &req_upiu))
 	{
-		dprintf(CRITICAL, "Data read failed\n");
+		dprintf(CRITICAL, "ucs_do_request_sense: failed\n");
 		return -UFS_FAILURE;
 	}
 
 	/* Flush buffer. */
 	arch_invalidate_cache_range((addr_t) buf, SCSI_INQUIRY_LEN);
 
+	dump_sense_buffer(buf, SCSI_SENSE_BUF_LEN);
+
 	return UFS_SUCCESS;
 }
diff --git a/platform/msm_shared/ufs.c b/platform/msm_shared/ufs.c
index b0470cd..8244576 100644
--- a/platform/msm_shared/ufs.c
+++ b/platform/msm_shared/ufs.c
@@ -91,7 +91,7 @@
 	int                  ret;
 
 	req.data_buffer_base = buffer;
-	req.lun              = 0;
+	req.lun              = dev->current_lun;
 	req.num_blocks       = num_blocks;
 	req.start_lba        = start_lba / dev->block_size;
 
@@ -99,6 +99,7 @@
 	if (ret)
 	{
 		dprintf(CRITICAL, "UFS read failed.\n");
+		ufs_dump_hc_registers(dev);
 	}
 
 	return ret;
@@ -110,7 +111,7 @@
 	int                  ret;
 
 	req.data_buffer_base = buffer;
-	req.lun              = 0;
+	req.lun              = dev->current_lun;
 	req.num_blocks       = num_blocks;
 	req.start_lba        = start_lba / dev->block_size;
 
@@ -118,24 +119,50 @@
 	if (ret)
 	{
 		dprintf(CRITICAL, "UFS write failed.\n");
+		ufs_dump_hc_registers(dev);
 	}
 
 	return ret;
 }
+
+int ufs_erase(struct ufs_dev* dev, uint64_t start_lba, uint32_t num_blocks)
+{
+	struct scsi_unmap_req req;
+	int                    ret;
+
+	req.lun        = dev->current_lun;
+	req.start_lba  = start_lba / dev->block_size;
+	req.num_blocks = num_blocks;
+
+	ret = ucs_do_scsi_unmap(dev, &req);
+	if(ret)
+	{
+		dprintf(CRITICAL, "UFS erase failed \n");
+	}
+
+	return ret;
+}
+
 uint64_t ufs_get_dev_capacity(struct ufs_dev* dev)
 {
 	uint64_t capacity;
-	int ret = 0;
+	uint8_t lun = dev->current_lun;
 
-	ret = dme_read_unit_desc(dev, 0, &capacity);
-	if (ret)
-	{
-		dprintf(CRITICAL, "Failed to read unit descriptor\n");
-	}
+	capacity = dev->lun_cfg[lun].logical_blk_cnt * dev->block_size;
 
 	return capacity;
 }
 
+uint32_t ufs_get_erase_blk_size(struct ufs_dev* dev)
+{
+	uint32_t erase_blk_size;
+	uint8_t lun = dev->current_lun;
+
+	erase_blk_size = dev->lun_cfg[lun].erase_blk_size;
+
+	return erase_blk_size;
+}
+
 uint32_t ufs_get_serial_num(struct ufs_dev* dev)
 {
 	int ret;
@@ -144,6 +171,7 @@
 	if (ret)
 	{
 		dprintf(CRITICAL, "UFS get serial number failed.\n");
+		ufs_dump_hc_registers(dev);
 	}
 
 	return dev->serial_num;
@@ -154,10 +182,16 @@
 	return dev->block_size;
 }
 
+uint8_t ufs_get_num_of_luns(struct ufs_dev* dev)
+{
+	return dev->num_lus;
+}
+
 int ufs_init(struct ufs_dev *dev)
 {
 	uint32_t ret = UFS_SUCCESS;
 	uint64_t cap;
+	uint8_t lun = 0;
 
 	dev->block_size = 4096;
 
@@ -165,7 +199,7 @@
 	ret = ufs_dev_init(dev);
 	if (ret != UFS_SUCCESS)
 	{
-		dprintf(CRITICAL, "UFS init failed\n");
+		dprintf(CRITICAL, "UFS dev_init failed\n");
 		goto ufs_init_err;
 	}
 
@@ -173,7 +207,7 @@
 	ret = uic_init(dev);
 	if (ret != UFS_SUCCESS)
 	{
-		dprintf(CRITICAL, "UFS init failed\n");
+		dprintf(CRITICAL, "UFS uic_init failed\n");
 		goto ufs_init_err;
 	}
 
@@ -184,24 +218,64 @@
 	ret = dme_send_nop_query(dev);
 	if (ret != UFS_SUCCESS)
 	{
-		dprintf(CRITICAL, "UFS init failed\n");
+		dprintf(CRITICAL, "UFS dme_send_nop_query 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;
-    }
+	if (ret != UFS_SUCCESS)
+	{
+		dprintf(CRITICAL, "UFS dme_set_fdeviceinit 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;
-    }
+	if (ret != UFS_SUCCESS)
+	{
+		dprintf(CRITICAL, "UFS ucs_scsi_send_inquiry failed\n");
+		goto ufs_init_err;
+	}
+
+	ret = dme_read_device_desc(dev);
+	if (ret != UFS_SUCCESS)
+	{
+		dprintf(CRITICAL, "dme_read_dev_desc read failed\n");
+		goto ufs_init_err;
+	}
+
+
+	for(lun=0; lun < dev->num_lus; lun++)
+	{
+		ret = dme_read_unit_desc(dev, lun);
+		if (ret != UFS_SUCCESS)
+		{
+			dprintf(CRITICAL, "UFS dme_read_unit_desc failed\n");
+			goto ufs_init_err;
+		}
+	}
+
+	dprintf(CRITICAL,"UFS init success\n");
 
 ufs_init_err:
+
+	if(ret != UFS_SUCCESS)
+	{
+		ufs_dump_hc_registers(dev);
+	}
+
 	return ret;
 }
+
+void ufs_dump_hc_registers(struct ufs_dev *dev)
+{
+	uint32_t base = dev->base;
+
+	dprintf(CRITICAL,"------Host controller register dump ---------\n");
+	dprintf(CRITICAL,"UFS_UECPA 0x%x\n",readl(UFS_UECPA(base)));
+	dprintf(CRITICAL,"UFS_UECDL 0x%x\n",readl(UFS_UECDL(base)));
+	dprintf(CRITICAL,"UFS_UECN 0x%x\n", readl(UFS_UECN(base)));
+	dprintf(CRITICAL,"UFS_UECT 0x%x\n",readl(UFS_UECT(base)));
+	dprintf(CRITICAL,"UFS_UECDME 0x%x\n",readl(UFS_UECDME(base)));
+	dprintf(CRITICAL,"UFS_HCS 0x%x\n", readl(UFS_HCS(base)));
+	dprintf(CRITICAL,"-----------End--------------------------------\n");
+}
diff --git a/target/apq8084/include/target/display.h b/target/apq8084/include/target/display.h
index 728d7bf..921b05c 100644
--- a/target/apq8084/include/target/display.h
+++ b/target/apq8084/include/target/display.h
@@ -94,6 +94,8 @@
 /*---------------------------------------------------------------------------*/
 /* Other Configuration                                                       */
 /*---------------------------------------------------------------------------*/
+#define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
+
 #define MIPI_FB_ADDR  0x03200000
 
 #define MIPI_HSYNC_PULSE_WIDTH       12
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index 7e3bae7..cf7f18f 100644
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -380,6 +380,9 @@
 /* Do any target specific intialization needed before entering fastboot mode */
 void target_fastboot_init(void)
 {
+	/* We are entering fastboot mode, so read partition table */
+	mmc_read_partition_table(1);
+
 	if (target_is_ssd_enabled()) {
 		clock_ce_enable(SSD_CE_INSTANCE);
 		target_load_ssd_keystore();
diff --git a/target/msm8226/include/target/display.h b/target/msm8226/include/target/display.h
index 3d6ba61..67fcec5 100755
--- a/target/msm8226/include/target/display.h
+++ b/target/msm8226/include/target/display.h
@@ -1,4 +1,4 @@
-/* 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 are
@@ -95,8 +95,7 @@
 /*---------------------------------------------------------------------------*/
 /* Other Configuration                                                       */
 /*---------------------------------------------------------------------------*/
-
-#define msm8226_DSI_FEATURE_ENABLE 0
+#define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
 
 #define MIPI_FB_ADDR  0x03200000
 
diff --git a/target/msm8610/include/target/display.h b/target/msm8610/include/target/display.h
index c6e93c4..5e9fa26 100644
--- a/target/msm8610/include/target/display.h
+++ b/target/msm8610/include/target/display.h
@@ -1,4 +1,4 @@
-/* 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 are
@@ -99,8 +99,7 @@
 /*---------------------------------------------------------------------------*/
 /* Other Configuration                                                       */
 /*---------------------------------------------------------------------------*/
-
-#define msm8610_DSI_FEATURE_ENABLE 0
+#define DISPLAY_CMDLINE_PREFIX " mdss_mdp3.panel="
 
 #define MIPI_FB_ADDR  0x03200000
 
diff --git a/target/msm8974/include/target/display.h b/target/msm8974/include/target/display.h
index b827cf6..dd9f9c0 100644
--- a/target/msm8974/include/target/display.h
+++ b/target/msm8974/include/target/display.h
@@ -91,6 +91,7 @@
 /*---------------------------------------------------------------------------*/
 /* Other Configuration                                                       */
 /*---------------------------------------------------------------------------*/
+#define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
 
 #define MIPI_FB_ADDR  0x03200000
 #define EDP_FB_ADDR   MIPI_FB_ADDR
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index 3e0ff5d..848307a 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -680,6 +680,9 @@
 #endif
 	if (crypto_initialized())
 		crypto_eng_cleanup();
+
+	/* Disable HC mode before jumping to kernel */
+	sdhci_mode_disable(&dev->host);
 }
 
 void shutdown_device()