Merge "dev: gcdb: display: update truly 720p panel init sequence" into lk.lnx.1.0-dev.1.0
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 5f1b5ff..1b94bd3 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1386,13 +1386,16 @@
 	unsigned kernel_actual;
 	unsigned ramdisk_actual;
 	unsigned imagesize_actual;
-	unsigned second_actual;
+	unsigned second_actual = 0;
 
 #if DEVICE_TREE
 	struct dt_table *table;
 	struct dt_entry dt_entry;
+	unsigned dt_table_offset;
 	uint32_t dt_actual;
 	uint32_t dt_hdr_size;
+	unsigned int dtb_size = 0;
+	unsigned char *best_match_dt_addr = NULL;
 #endif
 
 	if (target_is_emmc_boot()) {
@@ -1535,14 +1538,33 @@
 		memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
 		memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
 #if DEVICE_TREE
-		/* Validate and Read device device tree in the "tags_add */
-		if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
-		{
-			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
-			return -1;
-		}
+		if(hdr->dt_size != 0) {
 
-		memmove((void*) hdr->tags_addr, (char *)(image_addr + page_size + kernel_actual + ramdisk_actual), hdr->dt_size);
+			dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
+
+			table = (struct dt_table*) dt_table_offset;
+
+			if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0){
+				dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
+				return -1;
+			}
+
+			/* Find index of device tree within device tree table */
+			if(dev_tree_get_entry_info(table, &dt_entry) != 0){
+				dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
+				return -1;
+			}
+
+			/* Validate and Read device device tree in the "tags_add */
+			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size)){
+				dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+				return -1;
+			}
+
+			best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
+			dtb_size = dt_entry.size;
+			memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
+		}
 #endif
 
 		/* Make sure everything from scratch address is read before next step!*/
@@ -2165,17 +2187,22 @@
 	unsigned int kernel_size = 0;
 	unsigned int scratch_offset = 0;
 
+#if FBCON_DISPLAY_MSG
+	/* Exit keys' detection thread firstly */
+	exit_menu_keys_detection();
+#endif
+
 #if VERIFIED_BOOT
 	if(target_build_variant_user() && !device.is_unlocked)
 	{
 		fastboot_fail("unlock device to use this command");
-		return;
+		goto boot_failed;
 	}
 #endif
 
 	if (sz < sizeof(hdr)) {
 		fastboot_fail("invalid bootimage header");
-		return;
+		goto boot_failed;
 	}
 
 	hdr = (struct boot_img_hdr *)data;
@@ -2204,7 +2231,7 @@
 	/* sz should have atleast raw boot image */
 	if (image_actual > sz) {
 		fastboot_fail("bootimage: incomplete or not signed");
-		return;
+		goto boot_failed;
 	}
 
 	// Initialize boot state before trying to verify boot.img
@@ -2216,7 +2243,7 @@
 	if ((target_get_max_flash_size() - (image_actual - sig_actual)) < page_size)
 	{
 		fastboot_fail("booimage: size is greater than boot image buffer can hold");
-		return;
+		goto boot_failed;
 	}
 #endif
 
@@ -2244,7 +2271,7 @@
 	mdtp_activated(&is_mdtp_activated);
 	if(is_mdtp_activated){
 		dprintf(CRITICAL, "fastboot boot command is not available.\n");
-		return;
+		goto boot_failed;
 	}
 #endif /* MDTP_SUPPORT */
 
@@ -2302,7 +2329,7 @@
 		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
 	{
 		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
-		return;
+		goto boot_failed;
 	}
 
 #if DEVICE_TREE
@@ -2315,7 +2342,7 @@
 	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
 	{
 		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
-		return;
+		goto boot_failed;
 	}
 #endif
 
@@ -2327,7 +2354,7 @@
 	if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
 	{
 		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
-		return;
+		goto boot_failed;
 	}
 
 	/*
@@ -2343,7 +2370,7 @@
 					(void *)hdr->tags_addr);
 		if (!dtb) {
 			fastboot_fail("dtb not found");
-			return;
+			goto boot_failed;
 		}
 	}
 #endif
@@ -2354,6 +2381,15 @@
 	boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
 		   (const char*) hdr->cmdline, board_machtype(),
 		   (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
+
+	/* fastboot already stop, it's no need to show fastboot menu */
+	return;
+boot_failed:
+#if FBCON_DISPLAY_MSG
+	/* revert to fastboot menu if boot failed */
+	display_fastboot_menu();
+#endif
+	return;
 }
 
 void cmd_erase_nand(const char *arg, void *data, unsigned sz)
@@ -2521,7 +2557,7 @@
 					fastboot_fail("unlock device to flash keystore");
 					return;
 				}
-				if(!boot_verify_validate_keystore((unsigned char *)data))
+				if(!boot_verify_validate_keystore((unsigned char *)data,sz))
 				{
 					fastboot_fail("image is not a keystore file");
 					return;
diff --git a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
index f317ed3..eb56bbf 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
@@ -163,7 +163,7 @@
 /* Dynamic fps supported frequencies by panel                                */
 /*---------------------------------------------------------------------------*/
 static const struct dfps_panel_info sharp_wqxga_dualdsi_video_dfps = {
-	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
+	1, 9, {48, 53, 54, 55, 56, 57, 58, 59, 60}
 };
 
 /* 2LM + 2CTL */
diff --git a/include/platform.h b/include/platform.h
index 6711836..f3f970b 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -69,6 +69,7 @@
 int platform_is_msmgold();
 uint32_t platform_get_apcs_ipc_base();
 int platform_is_msm8952();
+int platform_is_msm8953();
 int platform_is_msm8956();
 uint32_t platform_is_msm8976_v_1_1();
 uint32_t platform_get_tz_app_add();
diff --git a/platform/mdm9640/acpuclock.c b/platform/mdm9640/acpuclock.c
index 99fd7d0..d927fa6 100644
--- a/platform/mdm9640/acpuclock.c
+++ b/platform/mdm9640/acpuclock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 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:
@@ -36,6 +36,26 @@
 #include <platform/iomap.h>
 #include <platform/timer.h>
 #include <platform.h>
+#include <rpm-smd.h>
+#include <regulator.h>
+
+#define RPM_CE_CLK_TYPE    0x6563
+#define CE1_CLK_ID         0x0
+#define RPM_SMD_KEY_RATE   0x007A484B
+
+uint32_t CE1_CLK[][8]=
+{
+    {
+        RPM_CE_CLK_TYPE, CE1_CLK_ID,
+        KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+        RPM_SMD_KEY_RATE, 4, 0,
+    },
+    {
+        RPM_CE_CLK_TYPE, CE1_CLK_ID,
+        KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+        RPM_SMD_KEY_RATE, 4, 171430, /* clk rate in KHZ */
+    },
+};
 
 void clock_config_uart_dm(uint8_t id)
 {
@@ -270,3 +290,132 @@
 	}
 
 }
+
+void clock_ce_enable(uint8_t instance)
+{
+	int ret;
+	char clk_name[64];
+
+	if (platform_is_mdmcalifornium())
+	{
+		if (instance == 1)
+			rpm_send_data(&CE1_CLK[GENERIC_ENABLE][0], 24, RPM_REQUEST_TYPE);
+		else
+		{
+			dprintf(CRITICAL, "Unsupported CE instance\n");
+			ASSERT(0);
+		}
+		return;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
+	ret = clk_get_set_enable(clk_name, 160000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
+	ret = clk_get_set_enable(clk_name, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
+		ASSERT(0);
+	}
+
+	/* Wait for 48 * #pipes cycles.
+	* This is necessary as immediately after an access control reset (boot up)
+	* or a debug re-enable, the Crypto core sequentially clears its internal
+	* pipe key storage memory. If pipe key initialization writes are attempted
+	* during this time, they may be overwritten by the internal clearing logic.
+	*/
+	udelay(1);
+}
+
+void clock_ce_disable(uint8_t instance)
+{
+	struct clk *ahb_clk;
+	struct clk *cclk;
+	struct clk *axi_clk;
+	struct clk *src_clk;
+	char clk_name[64];
+
+	if (platform_is_mdmcalifornium())
+	{
+		if (instance == 1)
+		rpm_send_data(&CE1_CLK[GENERIC_DISABLE][0], 24, RPM_REQUEST_TYPE);
+		else
+		{
+			dprintf(CRITICAL, "Unsupported CE instance\n");
+			ASSERT(0);
+		}
+		return;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
+	src_clk = clk_get(clk_name);
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
+	ahb_clk = clk_get(clk_name);
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
+	axi_clk = clk_get(clk_name);
+
+	snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
+	cclk    = clk_get(clk_name);
+
+	clk_disable(ahb_clk);
+	clk_disable(axi_clk);
+	clk_disable(cclk);
+	clk_disable(src_clk);
+
+	/* Some delay for the clocks to stabalize. */
+	udelay(1);
+}
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+	/* Start the block reset for CE */
+	writel(1, GCC_CRYPTO_BCR);
+
+	udelay(2);
+
+	/* Take CE block out of reset */
+	writel(0, GCC_CRYPTO_BCR);
+
+	udelay(2);
+}
+
+void clock_config_ce(uint8_t instance)
+{
+	/* Need to enable the clock before disabling since the clk_disable()
+	 * has a check to default to nop when the clk_enable() is not called
+	 * on that particular clock.
+	 */
+	clock_ce_enable(instance);
+
+	clock_ce_disable(instance);
+
+	ce_async_reset(instance);
+
+	clock_ce_enable(instance);
+}
diff --git a/platform/mdm9640/include/platform/clock.h b/platform/mdm9640/include/platform/clock.h
index 7fdf8a7..2efd1ce 100644
--- a/platform/mdm9640/include/platform/clock.h
+++ b/platform/mdm9640/include/platform/clock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014,2016 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:
@@ -36,5 +36,6 @@
 void clock_config_uart_dm(uint8_t id);
 void clock_usb30_init(void);
 void clock_reset_usb_phy();
+void clock_config_ce(uint8_t instance);
 
 #endif
diff --git a/platform/mdm9640/include/platform/iomap.h b/platform/mdm9640/include/platform/iomap.h
index 2a21206..a55687c 100644
--- a/platform/mdm9640/include/platform/iomap.h
+++ b/platform/mdm9640/include/platform/iomap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -92,9 +92,11 @@
 #define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL  0x004A3000
 
 /* CRYPTO ENGINE */
+#define  MSM_CE1_BASE                      0x073A000
+#define  MSM_CE1_BAM_BASE                  0x0704000
 #define  GCC_CRYPTO_BCR             (CLK_CTL_BASE + 0x16000)
 #define  GCC_CRYPTO_CMD_RCGR        (CLK_CTL_BASE + 0x16004)
-#define  GCC_0RYPTO_CFG_RCGR        (CLK_CTL_BASE + 0x16008)
+#define  GCC_CRYPTO_CFG_RCGR        (CLK_CTL_BASE + 0x16008)
 #define  GCC_CRYPTO_CBCR            (CLK_CTL_BASE + 0x1601C)
 #define  GCC_CRYPTO_AXI_CBCR        (CLK_CTL_BASE + 0x16020)
 #define  GCC_CRYPTO_AHB_CBCR        (CLK_CTL_BASE + 0x16024)
diff --git a/platform/mdm9640/mdm9640-clock.c b/platform/mdm9640/mdm9640-clock.c
index 0d4c26f..8e26bcf 100644
--- a/platform/mdm9640/mdm9640-clock.c
+++ b/platform/mdm9640/mdm9640-clock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -382,6 +382,57 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+	F(160000000,  gpll0,   5,   0,   0),
+	F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_CRYPTO_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_CRYPTO_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_ce1_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "ce1_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct vote_clk gcc_ce1_clk = {
+	.cbcr_reg      = (uint32_t *) GCC_CRYPTO_CBCR,
+	.vote_reg      = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask       = BIT(2),
+
+	.c = {
+		.dbg_name  = "gcc_ce1_clk",
+		.ops       = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CRYPTO_AHB_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(0),
+
+	.c = {
+		.dbg_name = "gcc_ce1_ahb_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_CRYPTO_AXI_CBCR,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask      = BIT(1),
+
+	.c = {
+		.dbg_name = "gcc_ce1_axi_clk",
+		.ops      = &clk_ops_vote,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src[] = {
 	F(  60000000, gpll0,   10,    0,     0),
 	F_END
@@ -443,6 +494,10 @@
 	CLK_LOOKUP("usb30_mock_utmi_clk", gcc_usb30_mock_utmi_clk.c),
 	CLK_LOOKUP("usb_phy_cfg_ahb_clk", gcc_usb_phy_cfg_ahb_clk.c),
 	CLK_LOOKUP("usb30_sleep_clk",     gcc_usb30_sleep_clk.c),
+	CLK_LOOKUP("ce1_ahb_clk",  gcc_ce1_ahb_clk.c),
+	CLK_LOOKUP("ce1_axi_clk",  gcc_ce1_axi_clk.c),
+	CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
+	CLK_LOOKUP("ce1_src_clk",  ce1_clk_src.c),
 };
 
 void platform_clock_init(void)
diff --git a/platform/msm8953/platform.c b/platform/msm8953/platform.c
index 26dee27..cd39620 100644
--- a/platform/msm8953/platform.c
+++ b/platform/msm8953/platform.c
@@ -171,6 +171,16 @@
 		return MSM_SHARED_BASE;
 }
 
+int platform_is_msm8953()
+{
+	uint32_t platform = board_platform_id();
+
+	if ((platform == MSM8953) || (platform == APQ8053))
+		return 1;
+	else
+		return 0;
+}
+
 uint32_t platform_get_qmp_rev()
 {
         return readl(USB3_PHY_REVISION_ID3) << 24 | readl(USB3_PHY_REVISION_ID2) << 16 |
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 9c80839..12488a9 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -96,14 +96,14 @@
 	} ASN1_SEQUENCE_END(KEYSTORE)
 IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
 
-static uint32_t read_der_message_length(unsigned char* input)
+static uint32_t read_der_message_length(unsigned char* input, unsigned sz)
 {
 	uint32_t len = 0;
-	int pos = 0;
+	uint32_t pos = 0;
 	uint8_t len_bytes = 1;
 
 	/* Check if input starts with Sequence id (0X30) */
-	if(input[pos] != 0x30)
+	if(sz < 3 || input[pos] != 0x30)
 		return len;
 	pos++;
 
@@ -132,7 +132,7 @@
 		}
 
 		/* Read next octet */
-		if (pos < (int) ASN1_SIGNATURE_BUFFER_SZ)
+		if (pos < (uint32_t) ASN1_SIGNATURE_BUFFER_SZ && pos < sz)
 			len = len | input[pos];
 		else
 		{
@@ -550,7 +550,7 @@
 
 	/* Copy the signature from scratch memory to buffer */
 	memcpy(signature, sig_addr, ASN1_SIGNATURE_BUFFER_SZ);
-	sig_len = read_der_message_length(signature);
+	sig_len = read_der_message_length(signature, ASN1_SIGNATURE_BUFFER_SZ);
 
 	if(!sig_len)
 	{
@@ -646,12 +646,12 @@
 	}
 }
 
-bool boot_verify_validate_keystore(unsigned char * user_addr)
+bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz)
 {
 	bool ret = false;
 	unsigned char *input = user_addr;
 	KEYSTORE *ks = NULL;
-	uint32_t len = read_der_message_length(input);
+	uint32_t len = read_der_message_length(input, sz);
 	if(!len)
 	{
 		dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index c40a435..485cc3c 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016, 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
@@ -172,7 +172,7 @@
 /* Print current boot state */
 void boot_verify_print_state();
 /* Function to validate keystore */
-bool boot_verify_validate_keystore(unsigned char * user_addr);
+bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz);
 /* Function to send root of trust to trust zone */
 bool send_rot_command(uint32_t is_unlocked);
 unsigned char* get_boot_fingerprint(unsigned int* buf_size);
diff --git a/platform/msm_shared/qgic_v3.c b/platform/msm_shared/qgic_v3.c
index 692801b..7549e3a 100644
--- a/platform/msm_shared/qgic_v3.c
+++ b/platform/msm_shared/qgic_v3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -77,9 +77,6 @@
 	uint32_t eoimode = 0;
 	uint32_t grpen1 = 0x1;
 
-	/* For cpu init need to wake up the redistributor */
-	writel((readl(GICR_WAKER_CPU0) & ~GIC_WAKER_PROCESSORSLEEP), GICR_WAKER_CPU0);
-
 	/* Wait until redistributor is up */
 	while(readl(GICR_WAKER_CPU0) & GIC_WAKER_CHILDRENASLEEP)
 	{
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 5728b92..e473882 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -394,6 +394,11 @@
 			$(LOCAL_DIR)/clock_pll.o \
 			$(LOCAL_DIR)/clock_lib2.o \
 			$(LOCAL_DIR)/gpio.o \
+			$(LOCAL_DIR)/crypto_hash.o \
+			$(LOCAL_DIR)/crypto5_eng.o \
+			$(LOCAL_DIR)/crypto5_wrapper.o \
+			$(LOCAL_DIR)/certificate.o \
+			$(LOCAL_DIR)/image_verify.o \
 			$(LOCAL_DIR)/scm.o \
 			$(LOCAL_DIR)/qmp_usb30_phy.o \
 			$(LOCAL_DIR)/qusb2_phy.o \
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 8ea4a1e..f6bd8d9 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -447,11 +447,16 @@
 	MSM8953  = 293,
 	MSM8937 = 294,
 	APQ8037 = 295,
+	MSM8996L = 302,
 	MSMGOLD = 303,
+	APQ8053 = 304,
+	MSM8996SG = 305,
 	APQGOLD = 307,
 	MSMGOLD2 = 308,
 	MSMGOLD3 = 309,
-	APQ8053 = 304,
+	MSM8996AU = 310,
+	APQ8096AU = 311,
+	APQ8096SG = 312,
 };
 
 enum platform {
diff --git a/project/mdm9640.mk b/project/mdm9640.mk
index 2aa002a..2c81541 100644
--- a/project/mdm9640.mk
+++ b/project/mdm9640.mk
@@ -10,6 +10,10 @@
 DEBUG := 1
 endif
 
+ifeq ($(TARGET_BOOTIMG_SIGNED),true)
+  CFLAGS += -D_SIGNED_KERNEL=1
+endif
+
 ENABLE_USB30_SUPPORT := 1
 ENABLE_SDHCI_SUPPORT := 1
 ENABLE_BOOT_CONFIG_SUPPORT := 1
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 0b8cb1e..219d0f8 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -55,6 +55,7 @@
 #include <uart_dm.h>
 #include <boot_device.h>
 #include <qmp_phy.h>
+#include <crypto5_wrapper.h>
 
 extern void smem_ptable_init(void);
 extern void smem_add_modem_partitions(struct ptable *flash_ptable);
@@ -87,6 +88,16 @@
 #define EXT4_CMDLINE  " rootwait rootfstype=ext4 root=/dev/mmcblk0p"
 #define UBI_CMDLINE " rootfstype=ubifs rootflags=bulk_read"
 
+#define CE1_INSTANCE            1
+#define CE_EE                   1
+#define CE_FIFO_SIZE            64
+#define CE_READ_PIPE            3
+#define CE_WRITE_PIPE           2
+#define CE_READ_PIPE_LOCK_GRP   0
+#define CE_WRITE_PIPE_LOCK_GRP  0
+#define CE_ARRAY_SIZE           20
+#define SUB_TYPE_SKUT           0x0A
+
 struct qpic_nand_init_config config;
 
 void update_ptable_names(void)
@@ -139,6 +150,7 @@
 	pmic_info_populate();
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
+	rpm_smd_init();
 
 	if (platform_boot_dev_isemmc()) {
 		target_sdc_init();
@@ -172,6 +184,9 @@
 		update_ptable_names();
 		flash_set_ptable(&flash_ptable);
 	}
+
+	if (target_use_signed_kernel())
+		target_crypto_init_params();
 }
 
 /* reboot */
@@ -372,6 +387,11 @@
 		mmc_put_card_to_sleep(dev);
 		sdhci_mode_disable(&dev->host);
 	}
+
+	if (crypto_initialized())
+		crypto_eng_cleanup();
+
+	rpm_smd_uninit();
 }
 
 void target_usb_phy_reset(void)
@@ -525,3 +545,38 @@
 	else
 		return 0;
 }
+
+crypto_engine_type board_ce_type(void)
+{
+	return CRYPTO_ENGINE_TYPE_HW;
+}
+
+/* Set up params for h/w CE. */
+void target_crypto_init_params()
+{
+	struct crypto_init_params ce_params;
+
+	/* Set up base addresses and instance. */
+	ce_params.crypto_instance  = CE1_INSTANCE;
+	ce_params.crypto_base      = MSM_CE1_BASE;
+	ce_params.bam_base         = MSM_CE1_BAM_BASE;
+
+	/* Set up BAM config. */
+	ce_params.bam_ee               = CE_EE;
+	ce_params.pipes.read_pipe      = CE_READ_PIPE;
+	ce_params.pipes.write_pipe     = CE_WRITE_PIPE;
+	ce_params.pipes.read_pipe_grp  = CE_READ_PIPE_LOCK_GRP;
+	ce_params.pipes.write_pipe_grp = CE_WRITE_PIPE_LOCK_GRP;
+
+	/* Assign buffer sizes. */
+	ce_params.num_ce           = CE_ARRAY_SIZE;
+	ce_params.read_fifo_size   = CE_FIFO_SIZE;
+	ce_params.write_fifo_size  = CE_FIFO_SIZE;
+
+	/* BAM is initialized by TZ for this platform.
+	* Do not do it again as the initialization address space
+	* is locked.
+	*/
+	ce_params.do_bam_init      = 0;
+	crypto_init_params(&ce_params);
+}
diff --git a/target/msm8953/target_display.c b/target/msm8953/target_display.c
index 5f9ac3b..fcd4b0a 100644
--- a/target/msm8953/target_display.c
+++ b/target/msm8953/target_display.c
@@ -390,11 +390,13 @@
 
 	if (!strcmp(oem.panel, NO_PANEL_CONFIG)
 		|| !strcmp(oem.panel, SIM_VIDEO_PANEL)
+		|| !strcmp(oem.panel, SIM_DUALDSI_VIDEO_PANEL)
 		|| !strcmp(oem.panel, SIM_CMD_PANEL)
+		|| !strcmp(oem.panel, SIM_DUALDSI_CMD_PANEL)
 		|| oem.skip) {
 		dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
 			oem.panel);
-		return;
+		oem.cont_splash = false;
 	}
 
 	do {
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 42a0614..9463dee 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -456,13 +456,15 @@
 	{
 		switch(platform) {
 		case APQ8096:
+		case APQ8096AU:
+		case APQ8096SG:
 			board->baseband = BASEBAND_APQ;
 			break;
 		case MSM8996:
-			if (board->platform_version == 0x10000)
-				board->baseband = BASEBAND_APQ;
-			else
-				board->baseband = BASEBAND_MSM;
+		case MSM8996SG:
+		case MSM8996AU:
+		case MSM8996L:
+			board->baseband = BASEBAND_MSM;
 			break;
 		default:
 			dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);