Merge "platform: msm_shared: Add support for byte addressing"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 7d774f4..4b887f0 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -610,6 +610,49 @@
 	}
 }
 
+static bool check_format_bit()
+{
+	bool ret = false;
+	int index;
+	uint64_t offset;
+	struct boot_selection_info *in = NULL;
+	char *buf = NULL;
+
+	index = partition_get_index("bootselect");
+	if (index == INVALID_PTN)
+	{
+		dprintf(INFO, "Unable to locate /bootselect partition\n");
+		return ret;
+	}
+	offset = partition_get_offset(index);
+	if(!offset)
+	{
+		dprintf(INFO, "partition /bootselect doesn't exist\n");
+		return ret;
+	}
+	buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
+	ASSERT(buf);
+	if (mmc_read(offset, (unsigned int *)buf, page_size))
+	{
+		dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
+		free(buf);
+		return ret;
+	}
+	in = (struct boot_selection_info *) buf;
+	if ((in->signature == BOOTSELECT_SIGNATURE) &&
+			(in->version == BOOTSELECT_VERSION)) {
+		if ((in->state_info & BOOTSELECT_FORMAT) &&
+				!(in->state_info & BOOTSELECT_FACTORY))
+			ret = true;
+	} else {
+		dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
+				in->signature, in->version);
+		ASSERT(0);
+	}
+	free(buf);
+	return ret;
+}
+
 int boot_linux_from_mmc(void)
 {
 	struct boot_img_hdr *hdr = (void*) buf;
@@ -632,6 +675,9 @@
 	uint32_t dt_actual;
 	uint32_t dt_hdr_size;
 #endif
+	if (check_format_bit())
+		boot_into_recovery = 1;
+
 	if (!boot_into_recovery) {
 		memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
 		rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
diff --git a/app/aboot/recovery.h b/app/aboot/recovery.h
index fa034e0..204312b 100644
--- a/app/aboot/recovery.h
+++ b/app/aboot/recovery.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -29,11 +29,22 @@
 #ifndef _BOOTLOADER_RECOVERY_H
 #define _BOOTLOADER_RECOVERY_H
 
-#define UPDATE_MAGIC       "MSM-RADIO-UPDATE"
-#define UPDATE_MAGIC_SIZE  16
-#define UPDATE_VERSION     0x00010000
-#define FFBM_MODE_BUF_SIZE 8
+#define UPDATE_MAGIC         "MSM-RADIO-UPDATE"
+#define UPDATE_MAGIC_SIZE    16
+#define UPDATE_VERSION       0x00010000
+#define FFBM_MODE_BUF_SIZE   8
+#define BOOTSELECT_SIGNATURE ('B' | ('S' << 8) | ('e' << 16) | ('l' << 24))
+#define BOOTSELECT_VERSION   0x00010001
+#define BOOTSELECT_FORMAT    (1 << 31)
+#define BOOTSELECT_FACTORY   (1 << 30)
 
+/* bootselect partition format structure */
+struct boot_selection_info {
+	uint32_t signature;                // Contains value BOOTSELECT_SIGNATURE defined above
+	uint32_t version;
+	uint32_t boot_partition_selection; // Decodes which partitions to boot: 0-Windows,1-Android
+	uint32_t state_info;               // Contains factory and format bit as definded above
+};
 
 /* Recovery Message */
 struct recovery_message {
diff --git a/dev/gcdb/display/include/panel_jdi_1080p_video.h b/dev/gcdb/display/include/panel_jdi_1080p_video.h
index e390da4..187d85e 100755
--- a/dev/gcdb/display/include/panel_jdi_1080p_video.h
+++ b/dev/gcdb/display/include/panel_jdi_1080p_video.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
@@ -54,7 +54,7 @@
 /* Panel resolution                                                          */
 /*---------------------------------------------------------------------------*/
 static struct panel_resolution jdi_1080p_video_panel_res = {
-  1080, 1920, 96, 64, 16, 0, 3, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  1080, 1920, 96, 64, 16, 0, 4, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
 /*---------------------------------------------------------------------------*/
@@ -149,7 +149,7 @@
 /* Panel Timing                                                              */
 /*---------------------------------------------------------------------------*/
 static const uint32_t jdi_1080p_video_timings[] = {
-  0xe1, 0x37, 0x25, 0x00, 0x67, 0x6b, 0x2a, 0x3a,  0x59, 0x03, 0x04, 0x00
+  0xe7, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x2a, 0x3a,  0x2d, 0x03, 0x04, 0x00
 };
 
 
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index 3fecd61..17fbf88 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -348,14 +348,21 @@
 					 void *ctx_ptr,
 					 crypto_auth_alg_type auth_alg)
 {
-    crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
-    uint32_t i = 0;
-    uint32_t iv_len = SHA256_INIT_VECTOR_SIZE;
-    uint32_t *auth_iv = sha256_ctx->auth_iv;
-    uint32_t seg_cfg_val;
-    uint32_t total_bytes_to_write = sha256_ctx->bytes_to_write;
-    uint32_t bytes_to_write = total_bytes_to_write;
-    uint32_t burst_mask;
+	crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
+	crypto_SHA1_ctx *sha1_ctx = (crypto_SHA1_ctx *) ctx_ptr;
+	uint32_t i = 0;
+	uint32_t iv_len = 0;
+	uint32_t *auth_iv = sha1_ctx->auth_iv;
+	uint32_t seg_cfg_val;
+
+	if(auth_alg == CRYPTO_AUTH_ALG_SHA1)
+	{
+		iv_len = SHA1_INIT_VECTOR_SIZE;
+	}
+	else if(auth_alg == CRYPTO_AUTH_ALG_SHA256)
+	{
+		iv_len = SHA256_INIT_VECTOR_SIZE;
+	}
 
     seg_cfg_val = crypto5_get_sha_cfg(ctx_ptr, auth_alg);
 
@@ -368,7 +375,9 @@
 	/* Initialize CE pointers. */
 	REG_WRITE_QUEUE_INIT(dev);
 
-    REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_CFG(dev->base), seg_cfg_val);
+	/* For authentication operation set the encryption cfg reg to 0 as per HPG */
+	REG_WRITE_QUEUE(dev, CRYPTO_ENCR_SEG_CFG(dev->base), 0);
+	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_CFG(dev->base), seg_cfg_val);
 
     for (i = 0; i < iv_len; i++)
     {
@@ -378,31 +387,77 @@
 			REG_WRITE_QUEUE(dev, CRYPTO_AUTH_IVn(dev->base, i), (*(auth_iv + i)));
     }
 
-	/* Check if the transfer length is a 8 beat burst multiple. */
-	burst_mask = CRYPTO_BURST_LEN - 1;
-	if (bytes_to_write & burst_mask)
-	{
-		/* Add trailer to make it a burst multiple. */
-		total_bytes_to_write = (bytes_to_write + burst_mask) & (~burst_mask);
-	}
-
-	sha256_ctx->bytes_to_write = total_bytes_to_write;
-
 	/* Typecast with crypto_SHA1_ctx because offset of auth_bytecnt
 	 * in both crypto_SHA1_ctx and crypto_SHA256_ctx are same.
 	 */
-    REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 0), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[0]);
-    REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 1), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[1]);
+	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 0), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[0]);
+	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 1), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[1]);
+}
 
-	/* Assume no header, always. */
-	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_START(dev->base), 0);
+/* Function: crypto5_set_auth_cfg
+ * Arg     : dev, ptr to data buffer, buffer_size, burst_mask for alignment
+ * Return  : aligned buffer incase of unaligned data_ptr and total no. of bytes
+ *           passed to crypto HW(includes header and trailer size).
+ * Flow    : If data buffer is aligned, we just configure the crypto auth
+ *           registers for start, size of data etc. If buffer is unaligned
+ *           we align it to burst(64-byte) boundary and also make the no. of
+ *           bytes a multiple of 64 for bam and then configure the registers
+ *           for header/trailer settings.
+ */
 
-    REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_SIZE(dev->base), bytes_to_write);
-    REG_WRITE_QUEUE(dev, CRYPTO_SEG_SIZE(dev->base), total_bytes_to_write);
-    REG_WRITE_QUEUE(dev, CRYPTO_GOPROC(dev->base), GOPROC_GO);
+static void crypto5_set_auth_cfg(struct crypto_dev *dev, uint8_t **buffer,
+							uint8_t *data_ptr,
+							uint32_t burst_mask,
+							uint32_t bytes_to_write,
+							uint32_t *total_bytes_to_write)
+{
+	uint32_t minor_ver = 0;
+	uint32_t auth_seg_start = 0;
 
+	/* Bits 23:16 - minor version */
+        minor_ver = (readl(CRYPTO_VERSION(dev->base)) & 0x00FF0000) >> 16;
+
+	/* A H/W bug on Crypto 5.0.0 enforces a rule that the desc lengths must
+	 * be burst aligned. Here we use the header/trailer crypto register settings.
+         * buffer                : The previous 64 byte aligned address for data_ptr.
+         * CRYPTO_AUTH_SEG_START : Number of bytes to skip to reach the address data_ptr.
+         * CRYPTO_AUTH_SEG_SIZE  : Number of  bytes to be sent to crypto HW.
+         * CRYPTO_SEG_SIZE       : CRYPTO_AUTH_SEG_START + CRYPTO_AUTH_SEG_SIZE.
+         * Function: We pick a previous 64 byte aligned address buffer, and tell crypto to
+         * skip (data_ptr - buffer) number of bytes.
+         * This bug is fixed in 5.1.0 onwards.*/
+
+	if(minor_ver == 0)
+	{
+		if ((uint32_t) data_ptr & (CRYPTO_BURST_LEN - 1))
+		{
+			dprintf(CRITICAL, "Data start not aligned at burst length.\n");
+
+			*buffer = (uint8_t *)ROUNDDOWN((uint32_t)data_ptr, CRYPTO_BURST_LEN);
+
+			/* Header & Trailer */
+			*total_bytes_to_write = ((bytes_to_write +(data_ptr - *buffer) + burst_mask) & (~burst_mask));
+
+			auth_seg_start = (data_ptr - *buffer);
+		}
+		else
+		{
+			/* No header */
+			/* Add trailer to make it a burst multiple as 5.0.x HW mandates data to be a multiple of 64. */
+			*total_bytes_to_write = (bytes_to_write + burst_mask) & (~burst_mask);
+		}
+	}
+	else
+	{
+		/* No header. 5.1 crypto HW doesnt require alignment as partial reads and writes are possible*/
+		*total_bytes_to_write = bytes_to_write;
+	}
+
+	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_START(dev->base), auth_seg_start);
+	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_SIZE(dev->base), bytes_to_write);
+	REG_WRITE_QUEUE(dev, CRYPTO_SEG_SIZE(dev->base), *total_bytes_to_write);
+	REG_WRITE_QUEUE(dev, CRYPTO_GOPROC(dev->base), GOPROC_GO);
 	REG_WRITE_QUEUE_DONE(dev, BAM_DESC_LOCK_FLAG | BAM_DESC_INT_FLAG);
-
 	REG_WRITE_EXEC(&dev->bam, 1, CRYPTO_WRITE_PIPE_INDEX);
 }
 
@@ -414,19 +469,23 @@
 	crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
 	uint32_t wr_flags = BAM_DESC_NWD_FLAG | BAM_DESC_INT_FLAG | BAM_DESC_EOT_FLAG;
 	uint32_t ret_status;
+	uint8_t *buffer = NULL;
+	uint32_t total_bytes_to_write = 0;
 
-	/* A H/W bug on Crypto 5.0.0 enforces a rule that the desc lengths must be burst aligned. */
-	if ((uint32_t) data_ptr & (CRYPTO_BURST_LEN - 1))
+	crypto5_set_auth_cfg(dev, &buffer, data_ptr, CRYPTO_BURST_LEN - 1, sha256_ctx->bytes_to_write,
+											&total_bytes_to_write);
+
+	if(buffer)
 	{
-		dprintf(CRITICAL, "Crypto send data failed\n");
-		dprintf(CRITICAL, "Data start not aligned at burst length.\n");
-		ret_status = CRYPTO_ERR_FAIL;
-		goto CRYPTO_SEND_DATA_ERR;
+		arch_clean_invalidate_cache_range((addr_t) buffer, total_bytes_to_write);
+
+		bam_status = ADD_WRITE_DESC(&dev->bam, buffer, total_bytes_to_write, wr_flags);
 	}
-
-	arch_clean_invalidate_cache_range((addr_t) data_ptr, sha256_ctx->bytes_to_write);
-
-	bam_status = ADD_WRITE_DESC(&dev->bam, data_ptr, sha256_ctx->bytes_to_write, wr_flags);
+	else
+	{
+		arch_clean_invalidate_cache_range((addr_t) data_ptr, total_bytes_to_write);
+		bam_status = ADD_WRITE_DESC(&dev->bam, data_ptr, total_bytes_to_write, wr_flags);
+	}
 
 	if (bam_status)
 	{
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
index e9b1e7b..03a1bb0 100644
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -184,7 +184,7 @@
 		break;
 	case MIPI_VIDEO_PANEL:
 		dprintf(INFO, "Turn on MIPI_VIDEO_PANEL.\n");
-		ret = mdp_dsi_video_on();
+		ret = mdp_dsi_video_on(pinfo);
 		if (ret)
 			goto msm_display_on_out;
 		ret = mipi_dsi_on();
@@ -193,7 +193,7 @@
 		break;
 	case MIPI_CMD_PANEL:
 		dprintf(INFO, "Turn on MIPI_CMD_PANEL.\n");
-		ret = mdp_dma_on();
+		ret = mdp_dma_on(pinfo);
 		if (ret)
 			goto msm_display_on_out;
 		mdp_rev = mdp_get_revision();
@@ -221,7 +221,7 @@
 		break;
 	case EDP_PANEL:
 		dprintf(INFO, "Turn on EDP PANEL.\n");
-		ret = mdp_edp_on();
+		ret = mdp_edp_on(pinfo);
 		if (ret)
 			goto msm_display_on_out;
 		break;
diff --git a/platform/msm_shared/include/mdp3.h b/platform/msm_shared/include/mdp3.h
index 8dff686..9ca4abf 100644
--- a/platform/msm_shared/include/mdp3.h
+++ b/platform/msm_shared/include/mdp3.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, 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
@@ -56,5 +56,5 @@
 
 /* defining no-op functions that are implemented only for mdp5 */
 int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
-int mdp_edp_on(void);
+int mdp_edp_on(struct msm_panel_info *pinfo);
 int mdp_edp_off(void);
diff --git a/platform/msm_shared/include/mdp4.h b/platform/msm_shared/include/mdp4.h
index c988dee..d979645 100644
--- a/platform/msm_shared/include/mdp4.h
+++ b/platform/msm_shared/include/mdp4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, 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
@@ -104,7 +104,7 @@
 void mdp_disable(void);
 void mdp_start_dma(void);
 int mdp_dsi_video_off();
-int mdp_dsi_video_on();
+int mdp_dsi_video_on(struct msm_panel_info *pinfo);
 int mdp_dsi_video_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
 int mdp_lcdc_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
 int mdp_lcdc_on();
@@ -114,7 +114,7 @@
 
 /* defining no-op functions that are implemented only for mdp5 */
 int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
-int mdp_edp_on(void);
+int mdp_edp_on(struct msm_panel_info *pinfo);
 int mdp_edp_off(void);
 
 #endif
diff --git a/platform/msm_shared/include/mdp5.h b/platform/msm_shared/include/mdp5.h
index 8b68ca0..54dc82f 100644
--- a/platform/msm_shared/include/mdp5.h
+++ b/platform/msm_shared/include/mdp5.h
@@ -34,6 +34,8 @@
 
 #define MDP_VP_0_RGB_0_BASE                     REG_MDP(0x1E00)
 #define MDP_VP_0_RGB_1_BASE                     REG_MDP(0x2200)
+#define MDP_VP_0_DMA_0_BASE                     REG_MDP(0x2A00)
+#define MDP_VP_0_DMA_1_BASE                     REG_MDP(0x2E00)
 
 #define PIPE_SSPP_SRC0_ADDR                     0x14
 #define PIPE_SSPP_SRC_YSTRIDE                   0x24
@@ -176,10 +178,10 @@
 int mdp_dsi_video_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
 int mipi_dsi_cmd_config(struct fbcon_config mipi_fb_cfg,
 			unsigned short num_of_lanes);
-int mdp_dsi_video_on(void);
-int mdp_dma_on(void);
+int mdp_dsi_video_on(struct msm_panel_info *pinfo);
+int mdp_dma_on(struct msm_panel_info *pinfo);
 int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
-int mdp_edp_on(void);
+int mdp_edp_on(struct msm_panel_info *pinfo);
 int mdp_edp_off(void);
 void mdp_disable(void);
 
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index 1eb9745..d704d8c 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.h
@@ -294,6 +294,7 @@
 	uint32_t pwrctl_base;  /* Base address for power control registers */
 	uint16_t bus_width;    /* Bus width used */
 	uint32_t max_clk_rate; /* Max clock rate supported */
+	uint8_t hs400_support; /* SDHC HS400 mode supported or not */
 };
 
 /* mmc device structure */
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index 1d8ebad..4407074 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -189,6 +189,8 @@
 	uint32_t wait_cycle;
 	uint32_t clk_rate;
 	uint32_t rotation;
+	/*  Enable if DMA pipe used for handoff */
+	uint32_t use_dma_pipe;
 	char     lowpowerstop;
 
 	struct lcd_panel_info lcd;
diff --git a/platform/msm_shared/mdp3.c b/platform/msm_shared/mdp3.c
index d83fa9e..2cde8ea 100644
--- a/platform/msm_shared/mdp3.c
+++ b/platform/msm_shared/mdp3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, 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
@@ -169,7 +169,7 @@
 	return mdp_rev;
 }
 
-int mdp_dsi_video_on()
+int mdp_dsi_video_on(struct msm_panel_info *pinfo)
 {
 	int ret = 0;
 
@@ -178,7 +178,7 @@
 	return ret;
 }
 
-int mdp_dma_on()
+int mdp_dma_on(struct msm_panel_info *pinfo)
 {
 	int ret = 0;
 	mdelay(100);
@@ -202,7 +202,7 @@
 	return NO_ERROR;
 }
 
-int mdp_edp_on(void)
+int mdp_edp_on(struct msm_panel_info *pinfo)
 {
 	return NO_ERROR;
 }
diff --git a/platform/msm_shared/mdp4.c b/platform/msm_shared/mdp4.c
index b3ade80..7b7c0cf 100644
--- a/platform/msm_shared/mdp4.c
+++ b/platform/msm_shared/mdp4.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, 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
@@ -229,7 +229,7 @@
 	writel(0x00000003, MDP_OVERLAYPROC0_CFG);
 }
 
-int mdp_dma_on(void)
+int mdp_dma_on(struct msm_panel_info *pinfo)
 {
 	int ret = 0;
 
@@ -364,7 +364,7 @@
 	return ret;
 }
 
-int mdp_dsi_video_on()
+int mdp_dsi_video_on(struct msm_panel_info *pinfo)
 {
 	int ret = NO_ERROR;
 
@@ -414,7 +414,7 @@
 	return NO_ERROR;
 }
 
-int mdp_edp_on(void)
+int mdp_edp_on(struct msm_panel_info *pinfo)
 {
 	return NO_ERROR;
 }
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index 73294f5..e1106bf 100644
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -79,10 +79,10 @@
 	writel(0x40000000, MDP_CLK_CTRL4);
 }
 
-static void mdss_rgb_pipe_config(struct fbcon_config *fb, struct msm_panel_info
+static void mdss_source_pipe_config(struct fbcon_config *fb, struct msm_panel_info
 		*pinfo, uint32_t pipe_base)
 {
-	uint32_t src_size, out_size, stride;
+	uint32_t src_size, out_size, stride, pipe_swap;
 	uint32_t fb_off = 0;
 
 	/* write active region size*/
@@ -91,11 +91,13 @@
 
 	if (pinfo->lcdc.dual_pipe) {
 		out_size = (fb->height << 16) + (fb->width / 2);
-		if ((pinfo->lcdc.pipe_swap == TRUE) && (pipe_base ==
-					MDP_VP_0_RGB_0_BASE))
+		pipe_swap = (pinfo->lcdc.pipe_swap == TRUE) ? 1 : 0;
+
+		if (pipe_swap && ((pipe_base == MDP_VP_0_RGB_0_BASE) ||
+				(pipe_base == MDP_VP_0_DMA_0_BASE)))
 			fb_off = (pinfo->xres / 2);
-		else if ((pinfo->lcdc.pipe_swap != TRUE) && (pipe_base ==
-					MDP_VP_0_RGB_1_BASE))
+		else if (!pipe_swap && ((pipe_base == MDP_VP_0_RGB_1_BASE) ||
+				(pipe_base == MDP_VP_0_DMA_1_BASE)))
 			fb_off = (pinfo->xres / 2);
 	}
 
@@ -155,7 +157,6 @@
 {
 	uint32_t i, j;
 	uint32_t reg_val = 0;
-	uint32_t mdss_mdp_rev = readl(MDP_HW_REV);
 
 	for (i = fixed_smp_cnt, j = 0; i < smp_cnt; i++) {
 		/* max 3 MMB per register */
@@ -179,9 +180,11 @@
 	return free_smp_offset;
 }
 
-void mdss_smp_setup(struct msm_panel_info *pinfo)
+static void mdss_smp_setup(struct msm_panel_info *pinfo, uint32_t left_pipe,
+		uint32_t right_pipe)
+
 {
-	uint32_t rgb0_client_id, rgb1_client_id;
+	uint32_t left_sspp_client_id, right_sspp_client_id;
 	uint32_t bpp = 3, free_smp_offset = 0, xres = MDSS_MAX_LINE_BUF_WIDTH;
 	uint32_t smp_cnt, smp_size = 4096, fixed_smp_cnt = 0;
 	uint32_t mdss_mdp_rev = readl(MDP_HW_REV);
@@ -193,11 +196,15 @@
 		free_smp_offset = 0xC;
 	}
 
-	rgb1_client_id = 0x11; /* 17 */
-	if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_101))
-		rgb0_client_id = 0x7;
+	if (pinfo->use_dma_pipe)
+		right_sspp_client_id = 0xD; /* 13 */
 	else
-		rgb0_client_id = 0x10; /* 16 */
+		right_sspp_client_id = 0x11; /* 17 */
+
+	if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_101))
+		left_sspp_client_id = (pinfo->use_dma_pipe) ? 0x4 : 0x07; /* 4 or 7 */
+	else
+		left_sspp_client_id = (pinfo->use_dma_pipe) ? 0xA : 0x10; /* 10 or 16 */
 
 	/* Each pipe driving half the screen */
 	if (pinfo->lcdc.dual_pipe)
@@ -213,20 +220,20 @@
 		ASSERT(0); /* Max 4 SMPs can be allocated per client */
 	}
 
-	writel(smp_cnt * 0x40, MDP_VP_0_RGB_0_BASE + REQPRIORITY_FIFO_WATERMARK0);
-	writel(smp_cnt * 0x80, MDP_VP_0_RGB_0_BASE + REQPRIORITY_FIFO_WATERMARK1);
-	writel(smp_cnt * 0xc0, MDP_VP_0_RGB_0_BASE + REQPRIORITY_FIFO_WATERMARK2);
+	writel(smp_cnt * 0x40, left_pipe + REQPRIORITY_FIFO_WATERMARK0);
+	writel(smp_cnt * 0x80, left_pipe + REQPRIORITY_FIFO_WATERMARK1);
+	writel(smp_cnt * 0xc0, left_pipe + REQPRIORITY_FIFO_WATERMARK2);
 
 	if (pinfo->lcdc.dual_pipe) {
-		writel(smp_cnt * 0x40, MDP_VP_0_RGB_1_BASE + REQPRIORITY_FIFO_WATERMARK0);
-		writel(smp_cnt * 0x80, MDP_VP_0_RGB_1_BASE + REQPRIORITY_FIFO_WATERMARK1);
-		writel(smp_cnt * 0xc0, MDP_VP_0_RGB_1_BASE + REQPRIORITY_FIFO_WATERMARK2);
+		writel(smp_cnt * 0x40, right_pipe + REQPRIORITY_FIFO_WATERMARK0);
+		writel(smp_cnt * 0x80, right_pipe + REQPRIORITY_FIFO_WATERMARK1);
+		writel(smp_cnt * 0xc0, right_pipe + REQPRIORITY_FIFO_WATERMARK2);
 	}
 
-	free_smp_offset = mdss_smp_alloc(rgb0_client_id, smp_cnt,
+	free_smp_offset = mdss_smp_alloc(left_sspp_client_id, smp_cnt,
 		fixed_smp_cnt, free_smp_offset);
 	if (pinfo->lcdc.dual_pipe)
-		mdss_smp_alloc(rgb1_client_id, smp_cnt, fixed_smp_cnt,
+		mdss_smp_alloc(right_sspp_client_id, smp_cnt, fixed_smp_cnt,
 			free_smp_offset);
 }
 
@@ -318,7 +325,7 @@
 void mdss_layer_mixer_setup(struct fbcon_config *fb, struct msm_panel_info
 		*pinfo)
 {
-	uint32_t mdp_rgb_size, height, width;
+	uint32_t mdp_rgb_size, height, width, val;
 
 	height = fb->height;
 	width = fb->width;
@@ -341,7 +348,10 @@
 	writel(0xFF, MDP_VP_0_MIXER_0_BASE + LAYER_3_BLEND0_FG_ALPHA);
 
 	/* Baselayer for layer mixer 0 */
-	writel(0x0000200, MDP_CTL_0_BASE + CTL_LAYER_0);
+	if (pinfo->use_dma_pipe)
+		writel(0x0040000, MDP_CTL_0_BASE + CTL_LAYER_0);
+	else
+		writel(0x0000200, MDP_CTL_0_BASE + CTL_LAYER_0);
 
 	if (pinfo->lcdc.dual_pipe) {
 		writel(mdp_rgb_size, MDP_VP_0_MIXER_1_BASE + LAYER_0_OUT_SIZE);
@@ -356,10 +366,11 @@
 		writel(0xFF, MDP_VP_0_MIXER_1_BASE + LAYER_3_BLEND0_FG_ALPHA);
 
 		/* Baselayer for layer mixer 1 */
+		val = pinfo->use_dma_pipe ? 0x200000 : 0x1000;
 		if (pinfo->lcdc.split_display)
-			writel(0x1000, MDP_CTL_1_BASE + CTL_LAYER_1);
+			writel(val, MDP_CTL_1_BASE + CTL_LAYER_1);
 		else
-			writel(0x01000, MDP_CTL_0_BASE + CTL_LAYER_1);
+			writel(val, MDP_CTL_0_BASE + CTL_LAYER_1);
 	}
 }
 
@@ -390,6 +401,7 @@
 	int ret = NO_ERROR;
 	struct lcdc_panel_info *lcdc = NULL;
 	uint32_t intf_sel = 0x100;
+	uint32_t left_pipe, right_pipe;
 
 	mdss_intf_tg_setup(pinfo, MDP_INTF_1_BASE);
 
@@ -398,14 +410,23 @@
 
 	mdp_clk_gating_ctrl();
 
+	if (pinfo->use_dma_pipe) {
+		left_pipe = MDP_VP_0_DMA_0_BASE;
+		right_pipe = MDP_VP_0_DMA_1_BASE;
+	} else {
+		left_pipe = MDP_VP_0_RGB_0_BASE;
+		right_pipe = MDP_VP_0_RGB_1_BASE;
+	}
+
 	mdss_vbif_setup();
-	mdss_smp_setup(pinfo);
+	mdss_smp_setup(pinfo, left_pipe, right_pipe);
 
 	mdss_qos_remapper_setup();
 
-	mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_0_BASE);
+	mdss_source_pipe_config(fb, pinfo, left_pipe);
+
 	if (pinfo->lcdc.dual_pipe)
-		mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_1_BASE);
+		mdss_source_pipe_config(fb, pinfo, right_pipe);
 
 	mdss_layer_mixer_setup(fb, pinfo);
 
@@ -429,24 +450,31 @@
 {
 	int ret = NO_ERROR;
 	struct lcdc_panel_info *lcdc = NULL;
+	uint32_t left_pipe, right_pipe;
 
 	mdss_intf_tg_setup(pinfo, MDP_INTF_0_BASE);
 
+	if (pinfo->use_dma_pipe) {
+		left_pipe = MDP_VP_0_DMA_0_BASE;
+		right_pipe = MDP_VP_0_DMA_1_BASE;
+	} else {
+		left_pipe = MDP_VP_0_RGB_0_BASE;
+		right_pipe = MDP_VP_0_RGB_1_BASE;
+	}
+
 	mdp_clk_gating_ctrl();
 
 	mdss_vbif_setup();
-	mdss_smp_setup(pinfo);
+	mdss_smp_setup(pinfo, left_pipe, right_pipe);
 
 	mdss_qos_remapper_setup();
 
-	mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_0_BASE);
+	mdss_source_pipe_config(fb, pinfo, left_pipe);
 	if (pinfo->lcdc.dual_pipe)
-		mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_1_BASE);
-
+		mdss_source_pipe_config(fb, pinfo, right_pipe);
 
 	mdss_layer_mixer_setup(fb, pinfo);
 
-
 	if (pinfo->lcdc.dual_pipe)
 		writel(0x181F10, MDP_CTL_0_BASE + CTL_TOP);
 	else
@@ -465,6 +493,7 @@
 {
 	uint32_t intf_sel = BIT(8);
 	int ret = NO_ERROR;
+	uint32_t left_pipe, right_pipe;
 
 	struct lcdc_panel_info *lcdc = NULL;
 	uint32_t mdss_mdp_intf_off = 0;
@@ -491,13 +520,22 @@
 
 	writel(intf_sel, MDP_DISP_INTF_SEL);
 
+	if (pinfo->use_dma_pipe) {
+		left_pipe = MDP_VP_0_DMA_0_BASE;
+		right_pipe = MDP_VP_0_DMA_1_BASE;
+	} else {
+		left_pipe = MDP_VP_0_RGB_0_BASE;
+		right_pipe = MDP_VP_0_RGB_1_BASE;
+	}
+
 	mdss_vbif_setup();
-	mdss_smp_setup(pinfo);
+	mdss_smp_setup(pinfo, left_pipe, right_pipe);
 	mdss_qos_remapper_setup();
 
-	mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_0_BASE);
+	mdss_source_pipe_config(fb, pinfo, left_pipe);
+
 	if (pinfo->lcdc.dual_pipe)
-		mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_1_BASE);
+		mdss_source_pipe_config(fb, pinfo, right_pipe);
 
 	mdss_layer_mixer_setup(fb, pinfo);
 
@@ -512,13 +550,18 @@
 	return ret;
 }
 
-int mdp_dsi_video_on(void)
+int mdp_dsi_video_on(struct msm_panel_info *pinfo)
 {
-	int ret = NO_ERROR;
-	writel(0x22048, MDP_CTL_0_BASE + CTL_FLUSH);
-	writel(0x24090, MDP_CTL_1_BASE + CTL_FLUSH);
+	if (pinfo->use_dma_pipe) {
+		writel(0x22840, MDP_CTL_0_BASE + CTL_FLUSH);
+		writel(0x25080, MDP_CTL_1_BASE + CTL_FLUSH);
+	} else {
+		writel(0x22048, MDP_CTL_0_BASE + CTL_FLUSH);
+		writel(0x24090, MDP_CTL_1_BASE + CTL_FLUSH);
+	}
 	writel(0x01, MDP_INTF_1_TIMING_ENGINE_EN  + mdss_mdp_intf_offset());
-	return ret;
+
+	return NO_ERROR;
 }
 
 int mdp_dsi_video_off()
@@ -551,10 +594,15 @@
 	return NO_ERROR;
 }
 
-int mdp_dma_on(void)
+int mdp_dma_on(struct msm_panel_info *pinfo)
 {
-	writel(0x22048, MDP_CTL_0_BASE + CTL_FLUSH);
-	writel(0x24090, MDP_CTL_1_BASE + CTL_FLUSH);
+	if (pinfo->use_dma_pipe) {
+		writel(0x22840, MDP_CTL_0_BASE + CTL_FLUSH);
+		writel(0x25080, MDP_CTL_1_BASE + CTL_FLUSH);
+	} else {
+		writel(0x22048, MDP_CTL_0_BASE + CTL_FLUSH);
+		writel(0x24090, MDP_CTL_1_BASE + CTL_FLUSH);
+	}
 	writel(0x01, MDP_CTL_0_BASE + CTL_START);
 	return NO_ERROR;
 }
@@ -564,9 +612,12 @@
 
 }
 
-int mdp_edp_on(void)
+int mdp_edp_on(struct msm_panel_info *pinfo)
 {
-	writel(0x22048, MDP_CTL_0_BASE + CTL_FLUSH);
+	if (pinfo->use_dma_pipe)
+		writel(0x22840, MDP_CTL_0_BASE + CTL_FLUSH);
+	else
+		writel(0x22048, MDP_CTL_0_BASE + CTL_FLUSH);
 	writel(0x01, MDP_INTF_0_TIMING_ENGINE_EN  + mdss_mdp_intf_offset());
 	return NO_ERROR;
 }
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index 2f87e2f..3fa2e28 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -599,7 +599,7 @@
 
 	writel(0, DSI_CTRL);
 
-	writel(0, DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
 
 	DST_FORMAT = 0;		// RGB565
 	dprintf(SPEW, "DSI_Video_Mode - Dst Format: RGB565\n");
@@ -680,7 +680,7 @@
 	writel(0x0000001e, DSI_CLK_CTRL);
 	writel(0x0000003e, DSI_CLK_CTRL);
 
-	writel(0x10000000, DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
 
 	// writel(0, DSI_CTRL);
 
@@ -713,9 +713,9 @@
 	writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4 | 0x105,
 	       DSI_CTRL);
 	mdelay(10);
-	writel(0x10000000, DSI_COMMAND_MODE_DMA_CTRL);
+	writel(0x14000000, DSI_COMMAND_MODE_DMA_CTRL);
 	writel(0x10000000, DSI_MISR_CMD_CTRL);
-	writel(0x00000040, DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
 	writel(0x1, DSI_EOT_PACKET_CTRL);
 	// writel(0x0, MDP_OVERLAYPROC0_START);
 	mdp_start_dma();
@@ -944,7 +944,7 @@
 
 	writel(0, ctl_base + CTRL);
 
-	writel(0, ctl_base + DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, ctl_base + ERR_INT_MASK0);
 
 	writel(0x02020202, ctl_base + INT_CTRL);
 
@@ -1091,7 +1091,7 @@
 
 	writel(0, DSI_CTRL);
 
-	writel(0, DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
 
 	writel(0x02020202, DSI_INT_CTRL);
 
@@ -1191,7 +1191,7 @@
 
 	writel(0, ctl_base + CTRL);
 
-	writel(0, ctl_base + ERR_INT_MASK0);
+	writel(0x13ff3fe0, ctl_base + ERR_INT_MASK0);
 
 	writel(0x02020202, ctl_base + INT_CTRL);
 
@@ -1207,7 +1207,7 @@
 	writel(0x13c2c, ctl_base + COMMAND_MODE_MDP_DCS_CMD_CTRL);
 	writel(interleav << 30 | 0 << 24 | 0 << 20 | lane_en << 4 | 0x105,
 	       ctl_base + CTRL);
-	writel(0x10000000, ctl_base + COMMAND_MODE_DMA_CTRL);
+	writel(0x14000000, ctl_base + COMMAND_MODE_DMA_CTRL);
 	writel(0x10000000, ctl_base + MISR_CMD_CTRL);
 	writel(0x1, ctl_base + EOT_PACKET_CTRL);
 #endif
@@ -1241,7 +1241,7 @@
 	writel(0x0000001e, DSI_CLK_CTRL);
 	writel(0x0000003e, DSI_CLK_CTRL);
 
-	writel(0x10000000, DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
 
 
 	DST_FORMAT = 8;		// RGB888
@@ -1270,9 +1270,9 @@
 	writel(0x13c2c, DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL);
 	writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4 | 0x105,
 	       DSI_CTRL);
-	writel(0x10000000, DSI_COMMAND_MODE_DMA_CTRL);
+	writel(0x14000000, DSI_COMMAND_MODE_DMA_CTRL);
 	writel(0x10000000, DSI_MISR_CMD_CTRL);
-	writel(0x00000040, DSI_ERR_INT_MASK0);
+	writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
 	writel(0x1, DSI_EOT_PACKET_CTRL);
 
 	return NO_ERROR;
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index ca897ce..938cdeb 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -844,9 +844,15 @@
 	/* Run the clock @ 400 Mhz */
 	if (host->caps.hs400_support && mmc_card_supports_hs400_mode(card))
 	{
-		clock_config_mmc(host->msm_host->slot, SDHCI_CLK_400MHZ);
 		/* Save the timing value, before changing the clock */
 		MMC_SAVE_TIMING(host, MMC_HS400_TIMING);
+		/*
+		* Set the MCI_CLK divider before changing the sdcc core
+		* core clk to ensure card receives no more than 200 MHZ
+		* clock frequency
+		*/
+		sdhci_msm_set_mci_clk(host);
+		clock_config_mmc(host->msm_host->slot, SDHCI_CLK_400MHZ);
 	}
 	else
 	{
@@ -993,6 +999,10 @@
 	/* Save the timing value, before changing the clock */
 	MMC_SAVE_TIMING(host, MMC_HS400_TIMING);
 	sdhci_set_uhs_mode(host, SDHCI_SDR104_MODE);
+	/*
+	* Enable HS400 mode
+	*/
+	sdhci_msm_set_mci_clk(host);
 
 	/* 7. Execute Tuning for hs400 mode */
 	if ((mmc_ret = sdhci_msm_execute_tuning(host, width)))
@@ -1025,6 +1035,7 @@
 
 	host->base = cfg->sdhc_base;
 	host->sdhc_event = &sdhc_event;
+	host->caps.hs400_support = cfg->hs400_support;
 
 	data = (struct sdhci_msm_data *) malloc(sizeof(struct sdhci_msm_data));
 	ASSERT(data);
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index 547f4ec..9c4e8ed 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -264,13 +264,6 @@
 
 	REG_WRITE16(host, ctrl, SDHCI_HOST_CTRL2_REG);
 
-	/*
-	 * SDHC spec does not have matching UHS mode
-	 * So we use Vendor specific registers to enable
-	 * HS400 mode
-	 */
-	sdhci_msm_set_mci_clk(host);
-
 	/* Run the clock back */
 	sdhci_clk_supply(host, clk_val);
 }
diff --git a/platform/msm_shared/uart_dm.c b/platform/msm_shared/uart_dm.c
index f551a7a..c92a34f 100644
--- a/platform/msm_shared/uart_dm.c
+++ b/platform/msm_shared/uart_dm.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <debug.h>
+#include <kernel/thread.h>
 #include <reg.h>
 #include <sys/types.h>
 #include <platform/iomap.h>
@@ -339,6 +340,8 @@
 		}
 	}
 
+	//We need to make sure the DM_NO_CHARS_FOR_TX&DM_TF are are programmed atmoically.
+	enter_critical_section();
 	/* We are here. FIFO is ready to be written. */
 	/* Write number of characters to be written */
 	writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base));
@@ -366,6 +369,7 @@
 		tx_char_left = num_of_chars - (i + 1) * 4;
 		tx_data = tx_data + num_chars_written;
 	}
+	exit_critical_section();
 
 	return MSM_BOOT_UART_DM_E_SUCCESS;
 }
diff --git a/target/msm8226/oem_panel.c b/target/msm8226/oem_panel.c
index 258f77c..8326442 100755
--- a/target/msm8226/oem_panel.c
+++ b/target/msm8226/oem_panel.c
@@ -135,6 +135,12 @@
 	return NO_ERROR;
 }
 
+static void mdss_source_pipe_select(struct msm_panel_info *pinfo)
+{
+	/* Use DMA pipe for splash logo on 8x26 */
+	pinfo->use_dma_pipe = 1;
+}
+
 static void init_panel_data(struct panel_struct *panelstruct,
 			struct msm_panel_info *pinfo,
 			struct mdss_dsi_phy_ctrl *phy_db)
@@ -399,6 +405,7 @@
 
 panel_init:
 	init_panel_data(panelstruct, pinfo, phy_db);
+	mdss_source_pipe_select(pinfo);
 
 	return ret;
 }