Merge "platform: msm_shared: Add support to use DMA pipe for splash logo"
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/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/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;