Merge "msm8996: enable MDTP support"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 575e8e4..fdf4abb 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -76,6 +76,7 @@
 #include <wdog.h>
 #endif
 
+#include <reboot.h>
 #include "image_verify.h"
 #include "recovery.h"
 #include "bootimg.h"
@@ -87,6 +88,9 @@
 #include "board.h"
 #include "scm.h"
 #include "mdtp.h"
+#include "secapp_loader.h"
+#include <menu_keys_detect.h>
+#include <display_menu.h>
 
 extern  bool target_use_signed_kernel(void);
 extern void platform_uninit(void);
@@ -122,17 +126,9 @@
 
 #define MAX_TAGS_SIZE   1024
 
-#define RECOVERY_HARD_RESET_MODE   0x01
-#define FASTBOOT_HARD_RESET_MODE   0x02
-#define RTC_HARD_RESET_MODE        0x03
-
-#define RECOVERY_MODE   0x77665502
-#define FASTBOOT_MODE   0x77665500
-#define ALARM_BOOT      0x77665503
-
 /* make 4096 as default size to ensure EFS,EXT4's erasing */
 #define DEFAULT_ERASE_SIZE  4096
-#define MAX_PANEL_BUF_SIZE 128
+#define MAX_PANEL_BUF_SIZE 196
 
 #define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
 #define BOOT_DEV_MAX_LEN  64
@@ -167,6 +163,26 @@
 static const char *baseband_sglte2  = " androidboot.baseband=sglte2";
 static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
 
+#if VERIFIED_BOOT
+static const char *verity_mode = " androidboot.veritymode=";
+static const char *verified_state= " androidboot.verifiedbootstate=";
+
+//indexed based on enum values, green is 0 by default
+
+struct verified_boot_verity_mode vbvm[] =
+{
+	{false, "logging"},
+	{true, "enforcing"},
+};
+struct verified_boot_state_name vbsn[] =
+{
+	{GREEN, "green"},
+	{ORANGE, "orange"},
+	{YELLOW,"yellow"},
+	{RED,"red" },
+};
+#endif
+
 static unsigned page_size = 0;
 static unsigned page_mask = 0;
 static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
@@ -178,7 +194,7 @@
 /* Assuming unauthorized kernel image by default */
 static int auth_kernel_img = 0;
 
-static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}, {0},{0}};
+static device_info device = {DEVICE_MAGIC, 0, 0, 0, {0}, {0},{0}, 1};
 static bool is_allow_unlock = 0;
 
 static char frp_ptns[2][8] = {"config","frp"};
@@ -263,6 +279,10 @@
 	int have_target_boot_params = 0;
 	char *boot_dev_buf = NULL;
     bool is_mdtp_activated = 0;
+#if VERIFIED_BOOT
+    uint32_t boot_state = boot_verify_get_state();
+#endif
+
 #ifdef MDTP_SUPPORT
     mdtp_activated(&is_mdtp_activated);
 #endif /* MDTP_SUPPORT */
@@ -284,6 +304,11 @@
 	cmdline_len += strlen(usb_sn_cmdline);
 	cmdline_len += strlen(sn_buf);
 
+#if VERIFIED_BOOT
+	cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
+	cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
+#endif
+
 	if (boot_into_recovery && gpt_exists)
 		cmdline_len += strlen(secondary_gpt_enable);
 
@@ -398,6 +423,22 @@
 #endif
 		}
 
+#if VERIFIED_BOOT
+		src = verified_state;
+		if(have_cmdline) --dst;
+		have_cmdline = 1;
+		while ((*dst++ = *src++));
+		src = vbsn[boot_state].name;
+		if(have_cmdline) --dst;
+		while ((*dst++ = *src++));
+
+		src = verity_mode;
+		if(have_cmdline) --dst;
+		while ((*dst++ = *src++));
+		src = vbvm[device.verity_mode].name;
+		if(have_cmdline) -- dst;
+		while ((*dst++ = *src++));
+#endif
 		src = usb_sn_cmdline;
 		if (have_cmdline) --dst;
 		have_cmdline = 1;
@@ -793,24 +834,34 @@
 #endif
 
 #if VERIFIED_BOOT
-	if(boot_verify_get_state() == RED)
+	switch(boot_verify_get_state())
 	{
-		if(!boot_into_recovery)
-		{
+		case RED:
+#if FBCON_DISPLAY_MSG
+			display_menu_thread(DISPLAY_THREAD_BOOT_STATE);
+			wait_for_users_action();
+#else
 			dprintf(CRITICAL,
-					"Device verification failed. Rebooting into recovery.\n");
-			mdelay(1000);
-			reboot_device(RECOVERY_MODE);
-		}
-		else
-		{
-			dprintf(CRITICAL,
-					"Recovery image verification failed. Asserting..\n");
-			ASSERT(0);
-		}
-	}
+					"Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
+			mdelay(5000);
 #endif
 
+			break;
+		case YELLOW:
+#if FBCON_DISPLAY_MSG
+			display_menu_thread(DISPLAY_THREAD_BOOT_STATE);
+			wait_for_users_action();
+#else
+			dprintf(CRITICAL,
+					"Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
+			mdelay(5000);
+#endif
+			break;
+		default:
+			break;
+	}
+#endif
+#if !VERIFIED_BOOT
 	if(device.is_tampered)
 	{
 		write_device_info_mmc(&device);
@@ -822,7 +873,7 @@
 		ASSERT(0);
 	#endif
 	}
-
+#endif
 }
 
 static bool check_format_bit()
@@ -1060,6 +1111,20 @@
 		aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
 		#endif /* TZ_SAVE_KERNEL_HASH */
 
+#if VERIFIED_BOOT
+	if(boot_verify_get_state() == ORANGE)
+	{
+#if FBCON_DISPLAY_MSG
+		display_menu_thread(DISPLAY_THREAD_BOOT_STATE);
+		wait_for_users_action();
+#else
+		dprintf(CRITICAL,
+			"Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
+		mdelay(5000);
+#endif
+	}
+#endif
+
 #ifdef MDTP_SUPPORT
 		{
 			/* Verify MDTP lock.
@@ -1078,6 +1143,12 @@
 #endif /* MDTP_SUPPORT */
 	}
 
+#if VERIFIED_BOOT
+	// send root of trust
+	if(!send_rot_command((uint32_t)device.is_unlocked))
+		ASSERT(0);
+#endif
+
 	/*
 	 * Check if the kernel image is a gzip package. If yes, need to decompress it.
 	 * If not, continue booting.
@@ -1596,7 +1667,7 @@
 	unsigned long long ptn;
 	unsigned long long ptn_size;
 	unsigned blocksize = mmc_get_device_blocksize();
-	char buf[blocksize];
+	STACKBUF_DMA_ALIGN(buf, blocksize);
 
 	index = partition_get_index(frp_ptns[0]);
 	if (index == INVALID_PTN)
@@ -1613,7 +1684,7 @@
 	ptn_size = partition_get_size(index);
 	offset = ptn_size - blocksize;
 
-	if (mmc_read(ptn + offset, (void *)buf, sizeof(buf)))
+	if (mmc_read(ptn + offset, (void *)buf, blocksize))
 	{
 		dprintf(CRITICAL, "Reading MMC failed\n");
 		return -1;
@@ -1631,7 +1702,7 @@
 	unsigned long long ptn;
 	unsigned long long ptn_size;
 	unsigned blocksize = mmc_get_device_blocksize();
-	char buf[blocksize];
+	STACKBUF_DMA_ALIGN(buf, blocksize);
 
 	index = partition_get_index(frp_ptns[0]);
 	if (index == INVALID_PTN)
@@ -1648,7 +1719,7 @@
 	ptn_size = partition_get_size(index);
 	offset = ptn_size - blocksize;
 
-	if (mmc_read(ptn + offset, (void *)buf, sizeof(buf)))
+	if (mmc_read(ptn + offset, (void *)buf, blocksize))
 	{
 		dprintf(CRITICAL, "Reading MMC failed\n");
 		return -1;
@@ -1770,6 +1841,7 @@
 				info->is_unlocked = 1;
 			info->is_tampered = 0;
 			info->charger_screen_enabled = 0;
+			info->verity_mode = 1; //enforcing by default
 			write_device_info(info);
 		}
 		memcpy(dev, info, sizeof(device_info));
@@ -1880,6 +1952,9 @@
 
 void cmd_boot(const char *arg, void *data, unsigned sz)
 {
+#ifdef MDTP_SUPPORT
+	static bool is_mdtp_activated = 0;
+#endif /* MDTP_SUPPORT */
 	unsigned kernel_actual;
 	unsigned ramdisk_actual;
 	uint32_t image_actual;
@@ -1953,18 +2028,14 @@
 	else
 	{
 		/* fastboot boot is not allowed when MDTP is activated */
-
 		mdtp_ext_partition_verification_t ext_partition;
-		ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
-		ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
-		ext_partition.page_size = page_size;
-		ext_partition.image_addr = (uint32_t)data;
-		ext_partition.image_size = image_actual - sig_actual;
-		ext_partition.sig_avail = TRUE;
-		mdtp_fwlock_verify_lock(&ext_partition);
+
+		if (!is_mdtp_activated) {
+			ext_partition.partition = MDTP_PARTITION_NONE;
+			mdtp_fwlock_verify_lock(&ext_partition);
+		}
 	}
 
-	bool is_mdtp_activated = 0;
 	mdtp_activated(&is_mdtp_activated);
 	if(is_mdtp_activated){
 		dprintf(CRITICAL, "fastboot boot command is not available.\n");
@@ -2147,6 +2218,11 @@
 			return;
 		}
 	}
+#if VERIFIED_BOOT
+	if(!(strncmp(arg, "userdata", 8)))
+		if(send_delete_keys_to_tz())
+			ASSERT(0);
+#endif
 	fastboot_okay("");
 }
 
@@ -2155,19 +2231,11 @@
 #if VERIFIED_BOOT
 	if (target_build_variant_user())
 	{
-		if(!device.is_unlocked && !device.is_verified)
+		if(!device.is_unlocked)
 		{
 			fastboot_fail("device is locked. Cannot erase");
 			return;
 		}
-		if(!device.is_unlocked && device.is_verified)
-		{
-			if(!boot_verify_flash_allowed(arg))
-			{
-				fastboot_fail("cannot flash this partition in verified state");
-				return;
-			}
-		}
 	}
 #endif
 
@@ -2624,14 +2692,6 @@
 			fastboot_fail("device is locked. Cannot flash images");
 			return;
 		}
-		if(!device.is_unlocked && device.is_verified)
-		{
-			if(!boot_verify_flash_allowed(arg))
-			{
-				fastboot_fail("cannot flash this partition in verified state");
-				return;
-			}
-		}
 	}
 #endif
 
@@ -2643,6 +2703,16 @@
 		cmd_flash_meta_img(arg, data, sz);
 	else
 		cmd_flash_mmc_img(arg, data, sz);
+
+#if VERIFIED_BOOT
+	if((!strncmp(arg, "system", 6)) && !device.verity_mode)
+	{
+		// reset dm_verity mode to enforcing
+		device.verity_mode = 1;
+		write_device_info(&device);
+	}
+#endif
+
 	return;
 }
 
@@ -2737,6 +2807,9 @@
 
 	if (target_is_emmc_boot())
 	{
+#if FBCON_DISPLAY_MSG
+		keys_detect_init();
+#endif
 		boot_linux_from_mmc();
 	}
 	else
@@ -2792,13 +2865,20 @@
 		return;
 	}
 
-	display_fbcon_message("Oem Unlock requested");
+#if FBCON_DISPLAY_MSG
+	if(!device.is_unlocked)
+		display_menu_thread(DISPLAY_THREAD_UNLOCK);
+	else
+		fastboot_info("Device already unlocked!");
+	fastboot_okay("");
+#else
 	fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
+#endif
 }
 
 void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
 {
-	if(!device.is_unlocked || device.is_verified)
+	if(!device.is_unlocked)
 	{
 		if(!is_allow_unlock) {
 			fastboot_fail("oem unlock is not allowed");
@@ -2806,7 +2886,6 @@
 		}
 
 		device.is_unlocked = 1;
-		device.is_verified = 0;
 		write_device_info(&device);
 
 		struct recovery_message msg;
@@ -2821,24 +2900,16 @@
 
 void cmd_oem_lock(const char *arg, void *data, unsigned sz)
 {
-	/* TODO: Wipe user data */
-	if(device.is_unlocked || device.is_verified)
+	struct recovery_message msg;
+	if(device.is_unlocked)
 	{
 		device.is_unlocked = 0;
-		device.is_verified = 0;
 		write_device_info(&device);
-	}
-	fastboot_okay("");
-}
-
-void cmd_oem_verified(const char *arg, void *data, unsigned sz)
-{
-	/* TODO: Wipe user data */
-	if(device.is_unlocked || !device.is_verified)
-	{
-		device.is_unlocked = 0;
-		device.is_verified = 1;
-		write_device_info(&device);
+		// upon oem lock, reboot to recovery to wipe user data
+		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+		write_misc(0, &msg, sizeof(msg));
+		fastboot_okay("");
+		reboot_device(RECOVERY_MODE);
 	}
 	fastboot_okay("");
 }
@@ -3127,7 +3198,6 @@
 											{"oem unlock", cmd_oem_unlock},
 											{"oem unlock-go", cmd_oem_unlock_go},
 											{"oem lock", cmd_oem_lock},
-											{"oem verified", cmd_oem_verified},
 											{"oem device-info", cmd_oem_devinfo},
 											{"preflash", cmd_preflash},
 											{"oem enable-charger-screen", cmd_oem_enable_charger_screen},
@@ -3174,7 +3244,6 @@
 void aboot_init(const struct app_descriptor *app)
 {
 	unsigned reboot_mode = 0;
-	unsigned hard_reboot_mode = 0;
 	bool boot_into_fastboot = false;
 
 	/* Setup page size information for nv storage */
@@ -3254,18 +3323,38 @@
 		boot_into_fastboot = true;
 	#endif
 
+#if USE_PON_REBOOT_REG
+	reboot_mode = check_hard_reboot_mode();
+#else
 	reboot_mode = check_reboot_mode();
-	hard_reboot_mode = check_hard_reboot_mode();
-	if (reboot_mode == RECOVERY_MODE ||
-		hard_reboot_mode == RECOVERY_HARD_RESET_MODE) {
+#endif
+	if (reboot_mode == RECOVERY_MODE)
+	{
 		boot_into_recovery = 1;
-	} else if(reboot_mode == FASTBOOT_MODE ||
-		hard_reboot_mode == FASTBOOT_HARD_RESET_MODE) {
+	}
+	else if(reboot_mode == FASTBOOT_MODE)
+	{
 		boot_into_fastboot = true;
-	} else if(reboot_mode == ALARM_BOOT ||
-		hard_reboot_mode == RTC_HARD_RESET_MODE) {
+	}
+	else if(reboot_mode == ALARM_BOOT)
+	{
 		boot_reason_alarm = true;
 	}
+	else if (reboot_mode == DM_VERITY_ENFORCING)
+	{
+		device.verity_mode = 1;
+		write_device_info(&device);
+	}
+	else if (reboot_mode == DM_VERITY_LOGGING)
+	{
+		device.verity_mode = 0;
+		write_device_info(&device);
+	}
+	else if (reboot_mode == DM_VERITY_KEYSCLEAR)
+	{
+		if(send_delete_keys_to_tz())
+			ASSERT(0);
+	}
 
 normal_boot:
 	if (!boot_into_fastboot)
diff --git a/app/aboot/devinfo.h b/app/aboot/devinfo.h
index 7eee69b..97b8e12 100644
--- a/app/aboot/devinfo.h
+++ b/app/aboot/devinfo.h
@@ -42,11 +42,11 @@
 	unsigned char magic[DEVICE_MAGIC_SIZE];
 	bool is_unlocked;
 	bool is_tampered;
-	bool is_verified;
 	bool charger_screen_enabled;
 	char display_panel[MAX_PANEL_ID_LEN];
 	char bootloader_version[MAX_VERSION_LEN];
 	char radio_version[MAX_VERSION_LEN];
+	bool verity_mode; // 1 = enforcing, 0 = logging
 };
 
 #endif
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 8ed312b..01f907a 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -570,38 +570,40 @@
 	}
 	else
 	{
-		for(i=0; i<MAX_PARTITIONS; i++)
+		if (ext_partition->partition != MDTP_PARTITION_NONE)
 		{
-			if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
+			for(i=0; i<MAX_PARTITIONS; i++)
 			{
-				total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
-				if (validate_partition_params(dip->partition_cfg[i].size,
-					dip->partition_cfg[i].hash_mode,
-					dip->partition_cfg[i].verify_ratio))
+				if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
 				{
-					dprintf(CRITICAL, "mdtp: verify_all_partitions: Wrong partition parameters\n");
-					verify_failure = TRUE;
-					break;
-				}
+					total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
+					if (validate_partition_params(dip->partition_cfg[i].size,
+							dip->partition_cfg[i].hash_mode,
+							dip->partition_cfg[i].verify_ratio))
+					{
+						dprintf(CRITICAL, "mdtp: verify_all_partitions: Wrong partition parameters\n");
+						verify_failure = TRUE;
+						break;
+					}
 
-				verify_failure |= (verify_partition(dip->partition_cfg[i].name,
-							 dip->partition_cfg[i].size,
-							 dip->partition_cfg[i].hash_mode,
-							 (dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
-							 dip->partition_cfg[i].hash_table,
-							 dip->partition_cfg[i].force_verify_block) != 0);
+					verify_failure |= (verify_partition(dip->partition_cfg[i].name,
+							dip->partition_cfg[i].size,
+							dip->partition_cfg[i].hash_mode,
+							(dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
+							dip->partition_cfg[i].hash_table,
+							dip->partition_cfg[i].force_verify_block) != 0);
+				}
+			}
+
+			ext_partition_verify_failure = verify_ext_partition(ext_partition);
+
+			if (verify_failure || ext_partition_verify_failure)
+			{
+				dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
+				return;
 			}
 		}
-
-		ext_partition_verify_failure = verify_ext_partition(ext_partition);
-
-		if (verify_failure || ext_partition_verify_failure)
-		{
-			dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
-			return;
-		}
 		is_mdtp_activated = 1;
-
 	}
 
 	*verify_result = VERIFY_OK;
@@ -728,7 +730,7 @@
 
 	/* Disallow CIPHER_DIP SCM call from this point, unless we are in recovery */
 	/* The recovery image will disallow CIPHER_DIP SCM call by itself. */
-	if (ext_partition->partition != MDTP_PARTITION_RECOVERY)
+	if (ext_partition->partition == MDTP_PARTITION_BOOT)
 	{
 		mdtp_tzbsp_disallow_cipher_DIP();
 	}
@@ -752,7 +754,6 @@
 static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified)
 {
 	unsigned char hash[HASH_LEN];
-	unsigned char buf[HASH_LEN], digest[HASH_LEN];
 	SHA256_CTX sha256_ctx;
 	int ret;
 
@@ -763,9 +764,6 @@
 	arch_clean_invalidate_cache_range((addr_t)enc_dip, sizeof(DIP_t));
 	arch_invalidate_cache_range((addr_t)dec_dip, sizeof(DIP_t));
 
-	/* workaround: Dummy call to hash_find prevents a boot loop when using the CE from TZ */
-	hash_find(buf, HASH_LEN, digest, CRYPTO_AUTH_ALG_SHA1);
-
 	ret = mdtp_cipher_dip_cmd((uint8_t*)enc_dip, sizeof(DIP_t),
 								(uint8_t*)dec_dip, sizeof(DIP_t),
 								DIP_DECRYPT);
@@ -799,7 +797,6 @@
 /* Encrypt a given DIP and calculate its integrity information */
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
 {
-	unsigned char buf[HASH_LEN], digest[HASH_LEN];
 	SHA256_CTX sha256_ctx;
 	int ret;
 
@@ -813,9 +810,6 @@
 	arch_clean_invalidate_cache_range((addr_t)dec_dip, sizeof(DIP_t));
 	arch_invalidate_cache_range((addr_t)enc_dip, sizeof(DIP_t));
 
-	/* workaround: Dummy call to hash_find prevents a boot loop when using the CE from TZ */
-	hash_find(buf, HASH_LEN, digest, CRYPTO_AUTH_ALG_SHA1);
-
 	ret = mdtp_cipher_dip_cmd((uint8_t*)dec_dip, sizeof(DIP_t),
 								(uint8_t*)enc_dip, sizeof(DIP_t),
 								DIP_ENCRYPT);
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index c29dcc2..03e3b7c 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -113,6 +113,7 @@
 typedef enum {
 	MDTP_PARTITION_BOOT = 0,
 	MDTP_PARTITION_RECOVERY,
+	MDTP_PARTITION_NONE,
 	MDTP_PARTITION_NUM,
 } mdtp_ext_partition_t;
 
diff --git a/app/aboot/mdtp_fuse.c b/app/aboot/mdtp_fuse.c
index 81351f4..a66f87b 100644
--- a/app/aboot/mdtp_fuse.c
+++ b/app/aboot/mdtp_fuse.c
@@ -32,12 +32,11 @@
 #include <partition_parser.h>
 #include <string.h>
 #include <stdlib.h>
-
+#include <reg.h>
 #include "mdtp.h"
 #include "scm.h"
 
 #define MAX_METADATA_SIZE       (0x1000)
-#define QFPROM_ADDR_SPACE_RAW   (0)
 
 /********************************************************************************/
 
@@ -156,21 +155,12 @@
  */
 static int read_QFPROM_fuse(uint8_t *mask)
 {
-	static const uint32_t row_address = MDTP_EFUSE_ADDRESS;
-	uint32_t addr_type = QFPROM_ADDR_SPACE_RAW;
-	uint32_t row_data[2] = {0};
-	uint32_t qfprom_api_status = 0;
+	uint32_t val = 0;
 
-	/* Read the current row where the eFuse is located */
-	(void) qfprom_read_row_cmd(row_address, addr_type, row_data, &qfprom_api_status);
-	if (qfprom_api_status)
-	{
-			dprintf(CRITICAL, "mdtp: write_QFPROM_fuse: qsee_fuse_read failed. qfprom_api_status=%d", qfprom_api_status);
-			return -1;
-	}
+	val = readl(MDTP_EFUSE_ADDRESS);
 
 	/* Shift the read data to be reflected in mask */
-	*mask = (uint8_t)(row_data[0] >> MDTP_EFUSE_START);
+	*mask = (uint8_t)(val >> MDTP_EFUSE_START);
 
 	return 0;
 }
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index fcf7259..dcdf75f 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -34,33 +34,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "mdtp.h"
-
-// Image dimensions
-#define MDTP_ERROR_MSG_WIDTH                (1412)
-#define MDTP_ERROR_MSG_HEIGHT               (212)
-#define MDTP_MAIN_TEXT_WIDTH                (1364)
-#define MDTP_MAIN_TEXT_HEIGHT               (288)
-#define MDTP_PIN_DIGIT_WIDTH                (180)
-#define MDTP_PIN_DIGIT_HEIGHT               (180)
-#define MDTP_OK_BUTTON_WIDTH                (644)
-#define MDTP_OK_BUTTON_HEIGHT               (158)
-#define MDTP_DIGITS_INSTRUCTIONS_WIDTH      (1384)
-#define MDTP_DIGITS_INSTRUCTIONS_HEIGHT     (166)
-#define MDTP_PIN_INSTRUCTIONS_WIDTH         (920)
-#define MDTP_PIN_INSTRUCTIONS_HEIGHT        (204)
-
-// Image offsets
-#define MDTP_ERROR_MSG_OFFSET               (0x1000)
-#define MDTP_INITIAL_DELAY_OFFSET           (0xDD000)
-#define MDTP_ENTER_PIN_OFFSET               (0x1FD000)
-#define MDTP_INVALID_PIN_OFFSET             (0x31D000)
-#define MDTP_PIN_DIGIT_0_OFFSET             (0x43D000)
-#define MDTP_PIN_DIGITS_OFFSET              (0x18000)
-#define MDTP_PIN_SELECTED_DIGIT_0_OFFSET    (MDTP_PIN_DIGIT_0_OFFSET + 10*MDTP_PIN_DIGITS_OFFSET)  // (0x52D000)
-#define MDTP_OK_BUTTON_OFFSET               (0x61D000)
-#define MDTP_SELECTED_OK_BUTTON_OFFSET      (0x668000)
-#define MDTP_DIGITS_INSTRUCTIONS_OFFSET     (0x6B3000)
-#define MDTP_PIN_INSTRUCTIONS_OFFSET        (0x75C000)
+#include "mdtp_ui_defs.h"
 
 // Image releative locations
 #define ERROR_MESSAGE_RELATIVE_Y_LOCATION   (0.18)
@@ -70,8 +44,6 @@
 #define OK_BUTTON_RELATIVE_Y_LOCATION       (0.75)
 #define OK_TEXT_RELATIVE_Y_LOCATION         (0.82)
 
-#define DIGIT_SPACE                         (12)
-
 #define MDTP_PRESSING_DELAY_MSEC            (400)
 #define MDTP_MAX_IMAGE_SIZE                 (1183000)  //size in bytes, includes some extra bytes since we round up to block size in read
 #define RGB888_BLACK                        (0x000000)
@@ -90,6 +62,8 @@
     uint8_t image[MDTP_MAX_IMAGE_SIZE];
 };
 
+struct mdtp_ui_defs mdtp_ui_defs_data;
+
 /*----------------------------------------------------------------------------
  * Global Variables
  * -------------------------------------------------------------------------*/
@@ -286,10 +260,10 @@
 
     if (fb_config)
 	{
-        uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_ERROR_MSG_WIDTH,fb_config->width);
+        uint32_t x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.error_msg_width,fb_config->width);
 		uint32_t y = ((fb_config->height)*ERROR_MESSAGE_RELATIVE_Y_LOCATION);
 
-        fbimg = mdtp_read_mmc_image(MDTP_ERROR_MSG_OFFSET, MDTP_ERROR_MSG_WIDTH, MDTP_ERROR_MSG_HEIGHT);
+        fbimg = mdtp_read_mmc_image(mdtp_ui_defs_data.error_msg_offset, mdtp_ui_defs_data.error_msg_width, mdtp_ui_defs_data.error_msg_height);
         if (NULL == fbimg)
         {
             dprintf(CRITICAL,"ERROR: failed to read error image from mmc\n");
@@ -338,10 +312,10 @@
  */
 static void display_initial_delay()
 {
-    uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_MAIN_TEXT_WIDTH,fb_config->width);
+    uint32_t x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.main_text_width,fb_config->width);
 	uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_INITIAL_DELAY_OFFSET, MDTP_MAIN_TEXT_WIDTH, MDTP_MAIN_TEXT_HEIGHT, x, y);
+	display_image(mdtp_ui_defs_data.initial_delay_offset, mdtp_ui_defs_data.main_text_width, mdtp_ui_defs_data.main_text_height, x, y);
 }
 
 /**
@@ -349,10 +323,10 @@
  */
 static void display_enter_pin()
 {
-    uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_MAIN_TEXT_WIDTH,fb_config->width);
+    uint32_t x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.main_text_width,fb_config->width);
 	uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_ENTER_PIN_OFFSET, MDTP_MAIN_TEXT_WIDTH, MDTP_MAIN_TEXT_HEIGHT, x, y);
+	display_image(mdtp_ui_defs_data.enter_pin_offset, mdtp_ui_defs_data.main_text_width, mdtp_ui_defs_data.main_text_height, x, y);
 }
 
 /**
@@ -360,10 +334,10 @@
  */
 static void display_invalid_pin()
 {
-    uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_MAIN_TEXT_WIDTH,fb_config->width);
+    uint32_t x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.main_text_width,fb_config->width);
 	uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_INVALID_PIN_OFFSET, MDTP_MAIN_TEXT_WIDTH, MDTP_MAIN_TEXT_HEIGHT, x, y);
+	display_image(mdtp_ui_defs_data.invalid_pin_offset, mdtp_ui_defs_data.main_text_width, mdtp_ui_defs_data.main_text_height, x, y);
 }
 
 /**
@@ -371,10 +345,10 @@
  */
 static void display_digits_instructions()
 {
-    uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_DIGITS_INSTRUCTIONS_WIDTH,fb_config->width);
+    uint32_t x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.digits_instructions_width,fb_config->width);
 	uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_DIGITS_INSTRUCTIONS_OFFSET, MDTP_DIGITS_INSTRUCTIONS_WIDTH, MDTP_DIGITS_INSTRUCTIONS_HEIGHT, x, y);
+	display_image(mdtp_ui_defs_data.digits_instructions_offset, mdtp_ui_defs_data.digits_instructions_width, mdtp_ui_defs_data.digits_instructions_height, x, y);
 }
 
 /**
@@ -384,7 +358,7 @@
 {
     uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
 
-    fbcon_clear_section(y, MDTP_DIGITS_INSTRUCTIONS_HEIGHT);
+    fbcon_clear_section(y, mdtp_ui_defs_data.digits_instructions_height);
 }
 
 /**
@@ -392,8 +366,8 @@
  */
 static void display_digit(uint32_t x, uint32_t y, uint32_t digit)
 {
-    display_image(MDTP_PIN_DIGIT_0_OFFSET + digit*MDTP_PIN_DIGITS_OFFSET,
-            MDTP_PIN_DIGIT_WIDTH, MDTP_PIN_DIGIT_HEIGHT, x, y);
+    display_image(mdtp_ui_defs_data.pin_digit_0_offset + digit*mdtp_ui_defs_data.pin_digits_offset,
+            mdtp_ui_defs_data.pin_digit_width, mdtp_ui_defs_data.pin_digit_height, x, y);
 }
 
 /**
@@ -401,8 +375,8 @@
  */
 static void display_selected_digit(uint32_t x, uint32_t y, uint32_t digit)
 {
-    display_image(MDTP_PIN_SELECTED_DIGIT_0_OFFSET + digit*MDTP_PIN_DIGITS_OFFSET,
-			MDTP_PIN_DIGIT_WIDTH, MDTP_PIN_DIGIT_HEIGHT, x, y);
+    display_image(mdtp_ui_defs_data.pin_selected_digit_0_offset + digit*mdtp_ui_defs_data.pin_digits_offset,
+			mdtp_ui_defs_data.pin_digit_width, mdtp_ui_defs_data.pin_digit_height, x, y);
 }
 
 /**
@@ -410,10 +384,10 @@
  */
 static void display_ok_button()
 {
-    uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(MDTP_OK_BUTTON_WIDTH,fb_config->width);
+    uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.ok_button_width,fb_config->width);
 	uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_OK_BUTTON_OFFSET, MDTP_OK_BUTTON_WIDTH, MDTP_OK_BUTTON_HEIGHT, ok_x, ok_y);
+	display_image(mdtp_ui_defs_data.ok_button_offset, mdtp_ui_defs_data.ok_button_width, mdtp_ui_defs_data.ok_button_height, ok_x, ok_y);
 }
 
 /**
@@ -421,10 +395,10 @@
  */
 static void display_selected_ok_button()
 {
-    uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(MDTP_OK_BUTTON_WIDTH,fb_config->width);
+    uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.ok_button_width,fb_config->width);
 	uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_SELECTED_OK_BUTTON_OFFSET, MDTP_OK_BUTTON_WIDTH, MDTP_OK_BUTTON_HEIGHT,  ok_x, ok_y);
+	display_image(mdtp_ui_defs_data.selected_ok_button_offset, mdtp_ui_defs_data.ok_button_width, mdtp_ui_defs_data.ok_button_height,  ok_x, ok_y);
 }
 
 /**
@@ -432,10 +406,10 @@
  */
 static void display_pin_instructions()
 {
-    uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_PIN_INSTRUCTIONS_WIDTH,fb_config->width);
+    uint32_t x = CENTER_IMAGE_ON_X_AXIS(mdtp_ui_defs_data.pin_instructions_width,fb_config->width);
 	uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
 
-	display_image(MDTP_PIN_INSTRUCTIONS_OFFSET, MDTP_PIN_INSTRUCTIONS_WIDTH, MDTP_PIN_INSTRUCTIONS_HEIGHT, x, y);
+	display_image(mdtp_ui_defs_data.pin_instructions_offset, mdtp_ui_defs_data.pin_instructions_width, mdtp_ui_defs_data.pin_instructions_height, x, y);
 }
 
 /**
@@ -445,7 +419,17 @@
 {
     uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
 
-	fbcon_clear_section(y, MDTP_PIN_INSTRUCTIONS_HEIGHT);
+	fbcon_clear_section(y, mdtp_ui_defs_data.pin_instructions_height);
+}
+
+/**
+ * Initialize data structures required for MDTP UI.
+ */
+static void init_mdtp_ui_data()
+{
+	fb_config = fbcon_display();
+	alloc_mdtp_image();
+	mdtp_ui_defs_data = mdtp_get_target_ui_defs();
 }
 
 /**
@@ -456,8 +440,7 @@
 	if (g_initial_screen_displayed == true)
 		return;
 
-	fb_config = fbcon_display();
-	alloc_mdtp_image();
+	init_mdtp_ui_data();
 
 	if (fb_config)
 	{
@@ -471,12 +454,12 @@
 
 		g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION);
 
-		uint32_t total_pin_length = pin_length*MDTP_PIN_DIGIT_WIDTH + DIGIT_SPACE*(pin_length - 1);
+		uint32_t total_pin_length = pin_length*mdtp_ui_defs_data.pin_digit_width + mdtp_ui_defs_data.digit_space*(pin_length - 1);
 		uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
 
 		for (uint32_t i=0; i<pin_length; i++)
 		{
-			g_pin_frames_x_location[i] = complete_pin_centered + i*(DIGIT_SPACE+MDTP_PIN_DIGIT_WIDTH);
+			g_pin_frames_x_location[i] = complete_pin_centered + i*(mdtp_ui_defs_data.digit_space+mdtp_ui_defs_data.pin_digit_width);
 		}
 
 		for (uint32_t i=0; i<pin_length; i++)
@@ -609,8 +592,7 @@
  */
 void display_error_msg()
 {
-	fb_config = fbcon_display();
-	alloc_mdtp_image();
+	init_mdtp_ui_data();
 
 	if (fb_config)
 	{
diff --git a/app/aboot/mdtp_ui_defs.c b/app/aboot/mdtp_ui_defs.c
new file mode 100644
index 0000000..2c9fbb0
--- /dev/null
+++ b/app/aboot/mdtp_ui_defs.c
@@ -0,0 +1,68 @@
+/* Copyright (c) 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
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <compiler.h>
+#include "mdtp_ui_defs.h"
+
+struct mdtp_ui_defs mdtp_ui_defs_default = {
+        // Image dimensions
+        1412,     // error_msg_width;
+        212,      // error_msg_height;
+        1364,     // main_text_width;
+        288,      // main_text_height;
+        180,      // pin_digit_width;
+        180,      // pin_digit_height;
+        644,      // ok_button_width;
+        158,      // ok_button_height;
+        1384,     // digits_instructions_width;
+        166,      // digits_instructions_height;
+        920,      // pin_instructions_width;
+        204,      // pin_instructions_height;
+
+        // Image offsets
+        0x1000,   // error_msg_offset;
+        0xDD000,  // initial_delay_offset;
+        0x1FD000, // enter_pin_offset;
+        0x31D000, // invalid_pin_offset;
+        0x43D000, // pin_digit_0_offset;
+        0x18000,  // pin_digits_offset;
+        0x52D000, // pin_selected_digit_0_offset;
+        0x61D000, // ok_button_offset;
+        0x668000, // selected_ok_button_offset;
+        0x6B3000, // digits_instructions_offset;
+        0x75C000, // pin_instructions_offset;
+
+        //Display settings
+        12        // mdtp_digit_space;
+};
+
+__WEAK struct mdtp_ui_defs mdtp_get_target_ui_defs()
+{
+    return mdtp_ui_defs_default;
+}
diff --git a/app/aboot/mdtp_ui_defs.h b/app/aboot/mdtp_ui_defs.h
new file mode 100644
index 0000000..15e3b51
--- /dev/null
+++ b/app/aboot/mdtp_ui_defs.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 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
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+
+struct mdtp_ui_defs {
+
+    // Image dimensions
+    uint32_t error_msg_width;
+    uint32_t error_msg_height;
+    uint32_t main_text_width;
+    uint32_t main_text_height;
+    uint32_t pin_digit_width;
+    uint32_t pin_digit_height;
+    uint32_t ok_button_width;
+    uint32_t ok_button_height;
+    uint32_t digits_instructions_width;
+    uint32_t digits_instructions_height;
+    uint32_t pin_instructions_width;
+    uint32_t pin_instructions_height;
+
+    // Image offsets
+    uint32_t error_msg_offset;
+    uint32_t initial_delay_offset;
+    uint32_t enter_pin_offset;
+    uint32_t invalid_pin_offset;
+    uint32_t pin_digit_0_offset;
+    uint32_t pin_digits_offset;
+    uint32_t pin_selected_digit_0_offset;
+    uint32_t ok_button_offset;
+    uint32_t selected_ok_button_offset;
+    uint32_t digits_instructions_offset;
+    uint32_t pin_instructions_offset;
+
+    //Display settings
+    uint32_t digit_space;
+};
+
+struct mdtp_ui_defs mdtp_get_target_ui_defs();
diff --git a/app/aboot/recovery.c b/app/aboot/recovery.c
index 15797a1..96441e2 100644
--- a/app/aboot/recovery.c
+++ b/app/aboot/recovery.c
@@ -592,6 +592,10 @@
 
 		if (scratch_addr != buf)
 			memcpy(scratch_addr, buf, size);
+
+		/* Set Lun for misc partition */
+		mmc_set_lun(partition_get_lun(index));
+
 		if (mmc_write(ptn + offset, aligned_size, (unsigned int *)scratch_addr))
 		{
 			dprintf(CRITICAL, "Writing MMC failed\n");
diff --git a/app/aboot/rules.mk b/app/aboot/rules.mk
index 7774788..cbc053a 100644
--- a/app/aboot/rules.mk
+++ b/app/aboot/rules.mk
@@ -15,5 +15,6 @@
 OBJS += \
 	$(LOCAL_DIR)/mdtp.o \
 	$(LOCAL_DIR)/mdtp_ui.o \
-	$(LOCAL_DIR)/mdtp_fuse.o
+	$(LOCAL_DIR)/mdtp_fuse.o \
+	$(LOCAL_DIR)/mdtp_ui_defs.o
 endif
diff --git a/arch/arm/include/arch/arm/mmu.h b/arch/arm/include/arch/arm/mmu.h
index 12bcd23..43a474e 100644
--- a/arch/arm/include/arch/arm/mmu.h
+++ b/arch/arm/include/arch/arm/mmu.h
@@ -88,6 +88,7 @@
 #define MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_NO_ALLOCATE  ATTR_INDEX(5)
 
 #define MMU_MEMORY_AP_READ_WRITE                       (1 << 6) /* Read/Write at any priveledge */
+#define MMU_MEMORY_AP_READ_ONLY                        (0x3 << 6) /* Read only priveledge */
 #define MMU_MEMORY_XN                                  (1ULL << 54)
 #define MMU_MEMORY_PXN                                 (1ULL << 53)
 
diff --git a/dev/fbcon/fbcon.c b/dev/fbcon/fbcon.c
index 885ce87..532ec10 100644
--- a/dev/fbcon/fbcon.c
+++ b/dev/fbcon/fbcon.c
@@ -47,13 +47,30 @@
 	int y;
 };
 
+struct fb_color {
+	uint32_t fg;
+	uint32_t bg;
+};
+
 static struct fbcon_config *config = NULL;
 
 #define RGB565_BLACK		0x0000
 #define RGB565_WHITE		0xffff
+#define RGB565_CYAN		0x07ff
+#define RGB565_BLUE		0x001f
+#define RGB565_SILVER		0xc618
+#define RGB565_YELLOW		0xffe0
+#define RGB565_ORANGE		0xfd20
+#define RGB565_RED		0xf800
 
 #define RGB888_BLACK            0x000000
 #define RGB888_WHITE            0xffffff
+#define RGB888_CYAN             0x00ffff
+#define RGB888_BLUE             0x0000FF
+#define RGB888_SILVER           0xc0c0c0
+#define RGB888_YELLOW           0xffff00
+#define RGB888_ORANGE           0xffa500
+#define RGB888_RED              0xff0000
 
 #define FONT_WIDTH		5
 #define FONT_HEIGHT		12
@@ -62,26 +79,50 @@
 
 static uint32_t			BGCOLOR;
 static uint32_t			FGCOLOR;
+static uint32_t			SELECT_BGCOLOR;
 
 static struct pos		cur_pos;
 static struct pos		max_pos;
+static struct fb_color		*fb_color_formats;
+static struct fb_color		fb_color_formats_555[] = {
+					[FBCON_COMMON_MSG] = {RGB565_WHITE, RGB565_BLACK},
+					[FBCON_UNLOCK_TITLE_MSG] = {RGB565_CYAN, RGB565_BLACK},
+					[FBCON_TITLE_MSG] = {RGB565_WHITE, RGB565_BLACK},
+					[FBCON_SUBTITLE_MSG] = {RGB565_SILVER, RGB565_BLACK},
+					[FBCON_YELLOW_MSG] = {RGB565_YELLOW, RGB565_BLACK},
+					[FBCON_ORANGE_MSG] = {RGB565_ORANGE, RGB565_BLACK},
+					[FBCON_RED_MSG] = {RGB565_RED, RGB565_BLACK},
+					[FBCON_LINE_COLOR] = {RGB565_WHITE, RGB565_WHITE},
+					[FBCON_SELECT_MSG_BG_COLOR] = {RGB565_WHITE, RGB565_BLUE}};
+
+static struct fb_color		fb_color_formats_888[] = {
+					[FBCON_COMMON_MSG] = {RGB888_WHITE, RGB888_BLACK},
+					[FBCON_UNLOCK_TITLE_MSG] = {RGB888_CYAN, RGB888_BLACK},
+					[FBCON_TITLE_MSG] = {RGB888_WHITE, RGB888_BLACK},
+					[FBCON_SUBTITLE_MSG] = {RGB888_SILVER, RGB888_BLACK},
+					[FBCON_YELLOW_MSG] = {RGB888_YELLOW, RGB888_BLACK},
+					[FBCON_ORANGE_MSG] = {RGB888_ORANGE, RGB888_BLACK},
+					[FBCON_RED_MSG] = {RGB888_RED, RGB888_BLACK},
+					[FBCON_LINE_COLOR] = {RGB888_WHITE, RGB888_WHITE},
+					[FBCON_SELECT_MSG_BG_COLOR] = {RGB888_WHITE, RGB888_BLUE}};
+
 
 static void fbcon_drawglyph(char *pixels, uint32_t paint, unsigned stride,
-			    unsigned bpp, unsigned *glyph)
+			    unsigned bpp, unsigned *glyph, unsigned scale_factor)
 {
 	unsigned x, y, i, j, k;
 	unsigned data, temp;
 	uint32_t fg_color = paint;
-	stride -= FONT_WIDTH * SCALE_FACTOR;
+	stride -= FONT_WIDTH * scale_factor;
 
 	data = glyph[0];
 	for (y = 0; y < FONT_HEIGHT / 2; ++y) {
 		temp = data;
-		for (i = 0; i < SCALE_FACTOR; i++) {
+		for (i = 0; i < scale_factor; i++) {
 			data = temp;
 			for (x = 0; x < FONT_WIDTH; ++x) {
 				if (data & 1) {
-					for (j = 0; j < SCALE_FACTOR; j++) {
+					for (j = 0; j < scale_factor; j++) {
 						fg_color = paint;
 						for (k = 0; k < bpp; k++) {
 							*pixels = (unsigned char) fg_color;
@@ -92,7 +133,7 @@
 				}
 				else
 				{
-					for (j = 0; j < SCALE_FACTOR; j++) {
+					for (j = 0; j < scale_factor; j++) {
 						pixels = pixels + bpp;
 					}
 				}
@@ -105,11 +146,11 @@
 	data = glyph[1];
 	for (y = 0; y < FONT_HEIGHT / 2; ++y) {
 		temp = data;
-		for (i = 0; i < SCALE_FACTOR; i++) {
+		for (i = 0; i < scale_factor; i++) {
 			data = temp;
 			for (x = 0; x < FONT_WIDTH; ++x) {
 				if (data & 1) {
-					for (j = 0; j < SCALE_FACTOR; j++) {
+					for (j = 0; j < scale_factor; j++) {
 						fg_color = paint;
 						for (k = 0; k < bpp; k++) {
 							*pixels = (unsigned char) fg_color;
@@ -120,7 +161,7 @@
 				}
 				else
 				{
-					for (j = 0; j < SCALE_FACTOR; j++) {
+					for (j = 0; j < scale_factor; j++) {
 						pixels = pixels + bpp;
 					}
 				}
@@ -132,6 +173,44 @@
 
 }
 
+void fbcon_draw_msg_background(unsigned y_start, unsigned y_end,
+	uint32_t old_paint, int update)
+{
+	unsigned i, j;
+	uint32_t bg_color, check_color, tmp_color, tmp1_color;
+	char *pixels;
+	unsigned count = config->width * (FONT_HEIGHT * (y_end - y_start) - 1);
+
+	pixels = config->base;
+	pixels += y_start * ((config->bpp / 8) * FONT_HEIGHT * config->width);
+
+	if (update) {
+		bg_color = SELECT_BGCOLOR;
+		check_color = old_paint;
+	} else {
+		bg_color = old_paint;
+		check_color = SELECT_BGCOLOR;
+	}
+
+	for (i = 0; i < count; i++) {
+		tmp1_color = bg_color;
+		tmp_color = 0;
+		for (j = 0; j < (config->bpp / 8); j++) {
+			tmp_color |= *(pixels+j) << j*8;
+		}
+
+		if (tmp_color == check_color) {
+			for (j = 0; j < (config->bpp / 8); j++) {
+				*pixels = (unsigned char) tmp1_color;
+				tmp1_color = tmp1_color >> 8;
+				pixels++;
+			}
+		} else {
+			pixels += config->bpp / 8;
+		}
+	}
+}
+
 static void fbcon_flush(void)
 {
 	unsigned total_x, total_y;
@@ -167,13 +246,50 @@
 	fbcon_flush();
 }
 
-/* TODO: take stride into account */
+void fbcon_draw_line()
+{
+	char *pixels;
+	uint32_t bg_color, tmp_color;
+	int i, j;
+
+	bg_color = fb_color_formats[FBCON_LINE_COLOR].bg;
+
+	pixels = config->base;
+	pixels += cur_pos.y * ((config->bpp / 8) * FONT_HEIGHT * config->width);
+	pixels += cur_pos.x * ((config->bpp / 8) * (FONT_WIDTH + 1));
+
+	for (i = 0; i < (int)config->width; i++) {
+		tmp_color = bg_color;
+		for (j = 0; j < (int)(config->bpp / 8); j++) {
+			*pixels = (unsigned char) tmp_color;
+			tmp_color = tmp_color >> 8;
+			pixels++;
+		}
+	}
+
+	cur_pos.y += 1;
+	cur_pos.x = 0;
+	if(cur_pos.y >= max_pos.y) {
+		cur_pos.y = max_pos.y - 1;
+		fbcon_scroll_up();
+	} else
+		fbcon_flush();
+}
+
+static void fbcon_set_colors(int type)
+{
+	BGCOLOR = fb_color_formats[type].bg;
+	FGCOLOR = fb_color_formats[type].fg;
+}
+
 void fbcon_clear(void)
 {
 	unsigned long i = 0, j = 0;
 	unsigned char *pixels = config->base;
 	unsigned count = config->width * config->height;
 	uint32_t bg_color;
+
+	fbcon_set_colors(FBCON_COMMON_MSG);
 	for (i = 0; i < count; i++) {
 		bg_color = BGCOLOR;
 		for (j = 0; j < (config->bpp / 8); j++) {
@@ -182,16 +298,11 @@
 			pixels++;
 		}
 	}
+	cur_pos.x = 0;
+	cur_pos.y = 0;
 }
 
-
-static void fbcon_set_colors(unsigned bg, unsigned fg)
-{
-	BGCOLOR = bg;
-	FGCOLOR = fg;
-}
-
-void fbcon_putc(char c)
+void fbcon_putc_factor(char c, int type, unsigned scale_factor)
 {
 	char *pixels;
 
@@ -213,18 +324,28 @@
 			return;
 	}
 
-	pixels = config->base;
-	pixels += cur_pos.y * SCALE_FACTOR * ((config->bpp / 8) * FONT_HEIGHT * config->width);
-	pixels += cur_pos.x * SCALE_FACTOR * ((config->bpp / 8) * (FONT_WIDTH + 1));
-	fbcon_drawglyph(pixels, FGCOLOR, config->stride, (config->bpp / 8),
-			font5x12 + (c - 32) * 2);
-
-	cur_pos.x++;
-	if (cur_pos.x < max_pos.x)
+	if (cur_pos.x == 0 && (unsigned char)c == ' ' &&
+		type != FBCON_SUBTITLE_MSG &&
+		type != FBCON_TITLE_MSG)
 		return;
 
+	fbcon_set_colors(type);
+
+	pixels = config->base;
+	pixels += cur_pos.y * ((config->bpp / 8) * FONT_HEIGHT * config->width);
+	pixels += cur_pos.x * scale_factor * ((config->bpp / 8) * (FONT_WIDTH + 1));
+
+	fbcon_drawglyph(pixels, FGCOLOR, config->stride, (config->bpp / 8),
+			font5x12 + (c - 32) * 2, scale_factor);
+
+	cur_pos.x++;
+	if (cur_pos.x >= (int)(max_pos.x / scale_factor))
+		goto newline;
+
+	return;
+
 newline:
-	cur_pos.y++;
+	cur_pos.y += scale_factor;
 	cur_pos.x = 0;
 	if(cur_pos.y >= max_pos.y) {
 		cur_pos.y = max_pos.y - 1;
@@ -233,39 +354,57 @@
 		fbcon_flush();
 }
 
+void fbcon_putc(char c)
+{
+	fbcon_putc_factor(c, FBCON_COMMON_MSG, SCALE_FACTOR);
+}
+
+uint32_t fbcon_get_current_line(void)
+{
+	return cur_pos.y;
+}
+
+uint32_t fbcon_get_max_x(void)
+{
+	return max_pos.x;
+}
+
+uint32_t fbcon_get_current_bg(void)
+{
+	return BGCOLOR;
+}
+
 void fbcon_setup(struct fbcon_config *_config)
 {
-	uint32_t bg = 0;
-	uint32_t fg = 0;
-
 	ASSERT(_config);
 
 	config = _config;
 
 	switch (config->format) {
 	case FB_FORMAT_RGB565:
-		fg = RGB565_WHITE;
-		bg = RGB565_BLACK;
+		fb_color_formats = fb_color_formats_555;
 		break;
-	case FB_FORMAT_RGB888:
-		fg = RGB888_WHITE;
-		bg = RGB888_BLACK;
-		break;
+        case FB_FORMAT_RGB888:
+		fb_color_formats = fb_color_formats_888;
+                break;
 	default:
 		dprintf(CRITICAL, "unknown framebuffer pixel format\n");
 		ASSERT(0);
 		break;
 	}
 
-	fbcon_set_colors(bg, fg);
+	SELECT_BGCOLOR = fb_color_formats[FBCON_SELECT_MSG_BG_COLOR].bg;
+	fbcon_set_colors(FBCON_COMMON_MSG);
 
 	cur_pos.x = 0;
 	cur_pos.y = 0;
-	max_pos.x = config->width / ((FONT_WIDTH + 1) * SCALE_FACTOR);
+	max_pos.x = config->width / (FONT_WIDTH+1);
 	max_pos.y = (config->height - 1) / FONT_HEIGHT;
+
 #if !DISPLAY_SPLASH_SCREEN
 	fbcon_clear();
 #endif
+
 }
 
 struct fbcon_config* fbcon_display(void)
diff --git a/dev/gcdb/display/gcdb_display_param.c b/dev/gcdb/display/gcdb_display_param.c
index fcf0953..7bc472f 100644
--- a/dev/gcdb/display/gcdb_display_param.c
+++ b/dev/gcdb/display/gcdb_display_param.c
@@ -214,6 +214,10 @@
 	else if (strstr((char *) panel_name, "#sim"))
 		oem_data.sim_mode = SIM_MODE;
 
+	/* disable cont splash when booting in simulator mode */
+	if (oem_data.sim_mode)
+		oem_data.cont_splash = false;
+
 }
 
 static bool mdss_dsi_set_panel_node(char *panel_name, char **dsi_id,
@@ -350,11 +354,11 @@
 	/* Check for the DSI configuration */
 	if (slave_panel_node && (panel_mode & (DUAL_DSI_FLAG |
 		SPLIT_DISPLAY_FLAG | DST_SPLIT_FLAG)))
-		strcpy(oem_data.dsi_config, "split_dsi");
+		strlcpy(oem_data.dsi_config, "split_dsi", DSI_CFG_SIZE);
 	else if (slave_panel_node)
-		strcpy(oem_data.dsi_config, "dual_dsi");
+		strlcpy(oem_data.dsi_config, "dual_dsi", DSI_CFG_SIZE);
 	else
-		strcpy(oem_data.dsi_config, "single_dsi");
+		strlcpy(oem_data.dsi_config, "single_dsi", DSI_CFG_SIZE);
 
 	arg_size = DSI_CFG_STRING_LEN + strlen(oem_data.dsi_config);
 
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
index 6c7df16..b059bb3 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
@@ -289,7 +289,7 @@
 /* Panel timing                                                              */
 /*---------------------------------------------------------------------------*/
 static const uint32_t nt35597_wqxga_dsc_cmd_timings[] = {
-	0xe2, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x28, 0x38,  0x2a, 0x03, 0x04, 0x00
+	0xa4, 0x24, 0x18, 0x00, 0x4c, 0x50, 0x1c, 0x28, 0x1c, 0x03, 0x04, 0x00,
 };
 
 static const uint32_t nt35597_wqxga_dsc_thulium_cmd_timings[] = {
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
index c699219..382d75c 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
@@ -275,6 +275,10 @@
 /*---------------------------------------------------------------------------*/
 /* Panel timing                                                              */
 /*---------------------------------------------------------------------------*/
+static const uint32_t nt35597_wqxga_dsc_video_timings[] = {
+	0xa4, 0x24, 0x18, 0x00, 0x4c, 0x50, 0x1c, 0x28, 0x1c, 0x03, 0x04, 0x00,
+};
+
 static const uint32_t nt35597_wqxga_dsc_thulium_video_timings[] = {
 	0x20, 0x1d, 0x05, 0x07, 0x03, 0x03, 0x4, 0xa0,
 	0x20, 0x1d, 0x05, 0x07, 0x03, 0x03, 0x4, 0xa0,
diff --git a/dev/pmic/pmi8994/pm_app_smbchg.c b/dev/pmic/pmi8994/pm_app_smbchg.c
index 4d8a2db..d3d1d6b 100644
--- a/dev/pmic/pmi8994/pm_app_smbchg.c
+++ b/dev/pmic/pmi8994/pm_app_smbchg.c
@@ -203,8 +203,8 @@
       {
           //Ensure that Charging is enabled
           err_flag |= pm_smbchg_chgr_enable_src(device_index, FALSE);
-          err_flag |= pm_smbchg_chgr_set_chg_polarity_low(device_index, FALSE);
-          err_flag |= pm_smbchg_bat_if_config_chg_cmd(device_index, PM_SMBCHG_BAT_IF_CMD__EN_BAT_CHG, TRUE);
+          err_flag |= pm_smbchg_chgr_set_chg_polarity_low(device_index, TRUE);
+          err_flag |= pm_smbchg_bat_if_config_chg_cmd(device_index, PM_SMBCHG_BAT_IF_CMD__EN_BAT_CHG, FALSE);
           udelay(PM_WEAK_BATTERY_CHARGING_DELAY);
       }
 
diff --git a/dev/pmic/pmi8994/pm_smbchg_chgr.c b/dev/pmic/pmi8994/pm_smbchg_chgr.c
index 2179772..629ba15 100644
--- a/dev/pmic/pmi8994/pm_smbchg_chgr.c
+++ b/dev/pmic/pmi8994/pm_smbchg_chgr.c
@@ -1084,7 +1084,7 @@
       pm_register_address_type chgr_cfg2 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg2;
 
       err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr);
-      err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, chgr_cfg2, 0x40, chg_pol_low, 0);
+      err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, chgr_cfg2, 0x40, (chg_pol_low ? 0x40 : 0), 0);
    }
 
    return err_flag;
diff --git a/include/dev/fbcon.h b/include/dev/fbcon.h
index e96b663..123532c 100644
--- a/include/dev/fbcon.h
+++ b/include/dev/fbcon.h
@@ -37,6 +37,25 @@
 #define LOGO_IMG_MAGIC_SIZE sizeof(LOGO_IMG_MAGIC) - 1
 #define LOGO_IMG_HEADER_SIZE 512
 
+enum fbcon_msg_type {
+	/* type for menu */
+	FBCON_COMMON_MSG = 0,
+	FBCON_UNLOCK_TITLE_MSG,
+	FBCON_TITLE_MSG,
+	FBCON_SUBTITLE_MSG,
+
+	/* type for warning */
+	FBCON_YELLOW_MSG,
+	FBCON_ORANGE_MSG,
+	FBCON_RED_MSG,
+
+	/* type for line color */
+	FBCON_LINE_COLOR,
+
+	/* and the select message's background */
+	FBCON_SELECT_MSG_BG_COLOR,
+};
+
 typedef struct logo_img_header {
 	unsigned char magic[LOGO_IMG_MAGIC_SIZE]; // "SPLASH!!"
 	uint32_t width;  // logo's width, little endian
@@ -74,5 +93,11 @@
 void fbcon_clear(void);
 struct fbcon_config* fbcon_display(void);
 void fbcon_extract_to_screen(logo_img_header *header, void* address);
-
+void fbcon_putc_factor(char c, int type, unsigned scale_factor);
+void fbcon_draw_msg_background(unsigned y_start, unsigned y_end,
+	uint32_t paint, int update);
+void fbcon_draw_line(void);
+uint32_t fbcon_get_current_line(void);
+uint32_t fbcon_get_current_bg(void);
+uint32_t fbcon_get_max_x(void);
 #endif /* __DEV_FBCON_H */
diff --git a/include/km_main.h b/include/km_main.h
new file mode 100644
index 0000000..42920d1
--- /dev/null
+++ b/include/km_main.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef KM_MAIN_H
+#define KM_MAIN_H
+
+#include <sys/types.h>
+/**
+ * Commands supported
+ */
+#define KEYMASTER_CMD_ID  0x100UL
+#define KEYMASTER_UTILS_CMD_ID  0x200UL
+
+#define UINT32_MAX  (0xffffffff)
+
+typedef enum {
+    /*
+     * List the commands supportedin by the hardware.
+     */
+    KEYMASTER_GET_SUPPORTED_ALGORITHMS		= (KEYMASTER_CMD_ID + 1UL),
+    KEYMASTER_GET_SUPPORTED_BLOCK_MODES		= (KEYMASTER_CMD_ID + 2UL),
+    KEYMASTER_GET_SUPPORTED_PADDING_MODES	= (KEYMASTER_CMD_ID + 3UL),
+    KEYMASTER_GET_SUPPORTED_DIGESTS			= (KEYMASTER_CMD_ID + 4UL),
+    KEYMASTER_GET_SUPPORTED_IMPORT_FORMATS	= (KEYMASTER_CMD_ID + 5UL),
+    KEYMASTER_GET_SUPPORTED_EXPORT_FORMATS	= (KEYMASTER_CMD_ID + 6UL),
+    KEYMASTER_ADD_RNG_ENTROPY				= (KEYMASTER_CMD_ID + 7UL),
+    KEYMASTER_GENERATE_KEY					= (KEYMASTER_CMD_ID + 8UL),
+    KEYMASTER_GET_KEY_CHARACTERISTICS		= (KEYMASTER_CMD_ID + 9UL),
+    KEYMASTER_RESCOPE						= (KEYMASTER_CMD_ID + 10UL),
+    KEYMASTER_IMPORT_KEY					= (KEYMASTER_CMD_ID + 11UL),
+    KEYMASTER_EXPORT_KEY					= (KEYMASTER_CMD_ID + 12UL),
+    KEYMASTER_DELETE_KEY					= (KEYMASTER_CMD_ID + 13UL),
+    KEYMASTER_DELETE_ALL_KEYS				= (KEYMASTER_CMD_ID + 14UL),
+    KEYMASTER_BEGIN							= (KEYMASTER_CMD_ID + 15UL),
+    KEYMASTER_GET_OUTPUT_SIZE				= (KEYMASTER_CMD_ID + 16UL),
+    KEYMASTER_UPDATE						= (KEYMASTER_CMD_ID + 17UL),
+    KEYMASTER_FINISH						= (KEYMASTER_CMD_ID + 18UL),
+    KEYMASTER_ABORT							= (KEYMASTER_CMD_ID + 19UL),
+
+    KEYMASTER_SET_ROT						= (KEYMASTER_UTILS_CMD_ID + 1UL),
+    KEYMASTER_READ_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 2UL),
+    KEYMASTER_WRITE_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 3UL),
+    KEYMASTER_MILESTONE_CALL				= (KEYMASTER_UTILS_CMD_ID + 4UL),
+
+    KEYMASTER_LAST_CMD_ENTRY				= (int)0xFFFFFFFFULL
+} keymaster_cmd_t;
+
+
+/*
+ * Utils Api struct
+ */
+/**
+  @brief
+    Data structure
+
+  @param[in]   cmd_id      Requested command
+  @param[in]   rot_ofset   Offset from the top of the struct.
+  @param[in]   rot_size    Size of the ROT
+*/
+typedef struct _km_set_rot_req_t {
+	uint32 cmd_id;
+	uint32 rot_ofset;
+	uint32 rot_size;
+}__attribute__ ((packed)) km_set_rot_req_t;
+
+/**
+  @brief
+    Data structure
+
+  @param[out]   status      Status of the request
+*/
+typedef struct _km_set_rot_rsp_t {
+	int status;
+}__attribute__ ((packed)) km_set_rot_rsp_t;
+
+/**
+  @brief
+    Data structure
+
+  @param[in]   cmd_id      Requested command
+  @param[in]   data        information (could be data or a pointer to the memory that holds the data
+  @param[in]   len         if data is ptr to some buffer, len indicates length of the buffer
+*/
+typedef struct send_cmd{
+	uint32 cmd_id;
+	uint32 data;
+	uint32 len;
+} __attribute__ ((packed)) send_cmd_t;
+
+/*
+typedef struct send_cmd_rsp{
+	uint32 cmd_id;
+	uint32 data;
+	int32 status;
+}  __attribute__ ((packed)) send_cmd_rsp_t; */
+
+/**
+  @brief
+    Data structure
+
+  @param[in]   cmd_id      Requested command
+*/
+typedef struct _km_set_milestone_req_t {
+	uint32 cmd_id;
+}__attribute__ ((packed)) km_set_milestone_req_t;
+
+/**
+  @brief
+    Data structure
+
+  @param[out]   status      Status of the request
+*/
+typedef struct _km_set_milestone_rsp_t {
+	int status;
+}__attribute__ ((packed)) km_set_milestone_rsp_t;
+
+/*
+ * Structures for delete_all cmd
+ */
+/*
+  @brief
+  Data structure
+
+  @param[in]  cmd_id              Requested command
+*/
+typedef struct _key_op_delete_all_req_t {
+	uint32 cmd_id;
+}__attribute__ ((packed)) key_op_delete_all_req_t;
+
+/*
+  @brief
+  Data structure
+
+  @param[out]   status             Status of the request
+*/
+typedef struct _key_op_delete_all_rsp_t {
+	int status;
+}__attribute__ ((packed)) key_op_delete_all_rsp_t;
+
+#endif /* KM_MAIN_H */
diff --git a/lib/libc/malloc.c b/lib/libc/malloc.c
index 9cec44c..b8857b4 100644
--- a/lib/libc/malloc.c
+++ b/lib/libc/malloc.c
@@ -36,7 +36,7 @@
 	void *ptr;
 	ptr = heap_alloc(size, boundary);
 	/* Clean the cache before giving the memory */
-	arch_invalidate_cache_range((addr_t) ptr, size);
+	arch_clean_invalidate_cache_range((addr_t) ptr, size);
 	return ptr;
 }
 
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index 94488b5..035c7cb 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -150,6 +150,18 @@
 #define USB_HS_SYSTEM_CMD_RCGR             (CLK_CTL_BASE + 0x41010)
 #define USB_HS_SYSTEM_CFG_RCGR             (CLK_CTL_BASE + 0x41014)
 
+
+/* RPMB send receive buffer needs to be mapped
+ * as device memory, define the start address
+ * and size in MB
+ */
+#define RPMB_SND_RCV_BUF            0x90000000
+#define RPMB_SND_RCV_BUF_SZ         0x1
+
+/* QSEECOM: Secure app region notification */
+#define APP_REGION_ADDR 0x85E00000
+#define APP_REGION_SIZE 0x500000
+
 /* MDSS */
 #define MIPI_DSI_BASE               (0x1A98000)
 #define MIPI_DSI0_BASE              MIPI_DSI_BASE
@@ -383,6 +395,35 @@
 #endif
 #define VBIF_VBIF_IN_WR_LIM_CONF1               REG_MDP(0xc80C4)
 
+#ifdef MDP_INTF_2_TIMING_ENGINE_EN
+#undef MDP_INTF_2_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_2_TIMING_ENGINE_EN		REG_MDP(0x12F00)
+
+#ifdef MDP_PP_0_BASE
+#undef MDP_PP_0_BASE
+#endif
+#define MDP_PP_0_BASE				REG_MDP(0x71000)
+
+#ifdef MDP_PP_1_BASE
+#undef MDP_PP_1_BASE
+#endif
+#define MDP_PP_1_BASE				REG_MDP(0x71800)
+
+#ifdef MDSS_MDP_REG_DCE_SEL
+#undef MDSS_MDP_REG_DCE_SEL
+#endif
+#define MDSS_MDP_REG_DCE_SEL			REG_MDP(0x1428)
+
+#ifdef MDSS_MDP_PP_DCE_DATA_OUT_SWAP
+#undef MDSS_MDP_PP_DCE_DATA_OUT_SWAP
+#endif
+#define MDSS_MDP_PP_DCE_DATA_OUT_SWAP		0x0CC
+
+#define MDP_DSC_0_BASE				REG_MDP(0x81000)
+#define MDP_DSC_1_BASE				REG_MDP(0x81400)
+
+
 #define SOFT_RESET                  0x118
 #define CLK_CTRL                    0x11C
 #define TRIG_CTRL                   0x084
@@ -419,6 +460,12 @@
 #define VIDEO_MODE_CTRL             0x010
 #define HS_TIMER_CTRL               0x0BC
 
+#define VIDEO_COMPRESSION_MODE_CTRL	0x2A0
+#define VIDEO_COMPRESSION_MODE_CTRL_2	0x2A4
+#define CMD_COMPRESSION_MODE_CTRL	0x2A8
+#define CMD_COMPRESSION_MODE_CTRL_2	0x2AC
+#define CMD_COMPRESSION_MODE_CTRL_3	0x2B0
+
 #define TCSR_TZ_WONCE               0x193D000
 #define TCSR_BOOT_MISC_DETECT       0x193D100
 
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
index af4f279..92cd0c8 100644
--- a/platform/msm8952/platform.c
+++ b/platform/msm8952/platform.c
@@ -61,12 +61,13 @@
 
 static mmu_section_t mmu_section_table[] = {
 /*           Physical addr,         Virtual addr,            Size (in MB),     Flags */
-	{    MEMBASE,               MEMBASE,                 (MEMSIZE / MB),   LK_MEMORY},
-	{    MSM_IOMAP_BASE,        MSM_IOMAP_BASE,          MSM_IOMAP_SIZE,   IOMAP_MEMORY},
-	{    APPS_SS_BASE,          APPS_SS_BASE,            APPS_SS_SIZE,      IOMAP_MEMORY},
-	{    MSM_SHARED_IMEM_BASE,  MSM_SHARED_IMEM_BASE,    1,                COMMON_MEMORY},
-	{    SCRATCH_ADDR,          SCRATCH_ADDR,            512,              SCRATCH_MEMORY},
-	{    MIPI_FB_ADDR,          MIPI_FB_ADDR,            42,              COMMON_MEMORY},
+	{    MEMBASE,               MEMBASE,                 (MEMSIZE / MB),         LK_MEMORY},
+	{    MSM_IOMAP_BASE,        MSM_IOMAP_BASE,          MSM_IOMAP_SIZE,         IOMAP_MEMORY},
+	{    APPS_SS_BASE,          APPS_SS_BASE,            APPS_SS_SIZE,           IOMAP_MEMORY},
+	{    MSM_SHARED_IMEM_BASE,  MSM_SHARED_IMEM_BASE,    1,                      COMMON_MEMORY},
+	{    SCRATCH_ADDR,          SCRATCH_ADDR,            512,                    SCRATCH_MEMORY},
+	{    MIPI_FB_ADDR,          MIPI_FB_ADDR,            42,                     COMMON_MEMORY},
+	{    RPMB_SND_RCV_BUF,      RPMB_SND_RCV_BUF,        RPMB_SND_RCV_BUF_SZ,    IOMAP_MEMORY},
 };
 
 void platform_early_init(void)
diff --git a/platform/msm8994/include/platform/iomap.h b/platform/msm8994/include/platform/iomap.h
index e6d40c9..998246f 100644
--- a/platform/msm8994/include/platform/iomap.h
+++ b/platform/msm8994/include/platform/iomap.h
@@ -40,6 +40,12 @@
 #define RESTART_REASON_ADDR         (MSM_SHARED_IMEM_BASE + 0x65C)
 #define RESTART_REASON_ADDR2        (MSM_SHARED_IMEM_BASE2 + 0x65C)
 
+#define DLOAD_MODE_ADDR              (MSM_SHARED_IMEM_BASE + 0x0)
+#define EMERGENCY_DLOAD_MODE_ADDR    (MSM_SHARED_IMEM_BASE + 0xFE0)
+#define DLOAD_MODE_ADDR_V2           (MSM_SHARED_IMEM_BASE2 + 0x0)
+#define EMERGENCY_DLOAD_MODE_ADDR_V2 (MSM_SHARED_IMEM_BASE2 + 0xFE0)
+
+
 #define BS_INFO_OFFSET              (0x6B0)
 #define BS_INFO_ADDR                (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET)
 #define BS_INFO_ADDR2               (MSM_SHARED_IMEM_BASE2 + BS_INFO_OFFSET)
@@ -223,6 +229,18 @@
 
 #define SMEM_TARG_INFO_ADDR                  0xFE805FF0
 
+
+/* RPMB send receive buffer needs to be mapped
+ * as device memory, define the start address
+ * and size in MB
+ */
+#define RPMB_SND_RCV_BUF            0x10000000
+#define RPMB_SND_RCV_BUF_SZ         0x1
+
+/* QSEECOM: Secure app region notification */
+#define APP_REGION_ADDR 0x6500000
+#define APP_REGION_SIZE 0x500000
+
 /* MDSS */
 #define MSM_MMSS_CLK_CTL_BASE       0xFD8C0000
 #define MMSS_MISC_AHB_CBCR          (MSM_MMSS_CLK_CTL_BASE + 0x502C)
diff --git a/platform/msm8994/platform.c b/platform/msm8994/platform.c
index 82e33b9..c1533ed 100644
--- a/platform/msm8994/platform.c
+++ b/platform/msm8994/platform.c
@@ -67,6 +67,7 @@
 	{    MSM_SHARED_BASE,   MSM_SHARED_BASE,   2,                   COMMON_MEMORY},
 	{    HLOS_MEMORY_START, HLOS_MEMORY_START, HLOS_MEMORY_SIZE,    COMMON_MEMORY},
 	{    SCRATCH_ADDR,      SCRATCH_ADDR,      (SCRATCH_SIZE / MB), SCRATCH_MEMORY},
+	{    RPMB_SND_RCV_BUF,  RPMB_SND_RCV_BUF,  RPMB_SND_RCV_BUF_SZ,    IOMAP_MEMORY},
 };
 
 void platform_early_init(void)
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 758182e..2ae1d17 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -191,7 +191,7 @@
  * as device memory, define the start address
  * and size in MB
  */
-#define RPMB_SND_RCV_BUF            0x90F00000
+#define RPMB_SND_RCV_BUF            0x91400000
 #define RPMB_SND_RCV_BUF_SZ         0x2
 
 #define TCSR_BOOT_MISC_DETECT       0x007B3000
diff --git a/platform/msm8996/platform.c b/platform/msm8996/platform.c
index 633857a..090e81c 100644
--- a/platform/msm8996/platform.c
+++ b/platform/msm8996/platform.c
@@ -41,22 +41,26 @@
 #define MSM_IOMAP_SIZE     ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
 #define MSM_SHARED_SIZE    2
 
-/* LK memory - cacheable, write through */
-#define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+/* LK memory - cacheable, write back */
+#define LK_MEMORY         (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
                            MMU_MEMORY_AP_READ_WRITE)
 
 /* Peripherals - non-shared device */
 #define IOMAP_MEMORY      (MMU_MEMORY_TYPE_DEVICE_SHARED | \
                            MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN | MMU_MEMORY_PXN)
 
-/* SCRATCH memory - cacheable, write through */
-#define SCRATCH_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+/* SCRATCH memory - cacheable, write back */
+#define SCRATCH_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
                            MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
 
 /* COMMON memory - cacheable, write through */
 #define COMMON_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
                            MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
 
+/* downlaod mode memory - cacheable, write through */
+#define DLOAD_MEMORY       (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+                           MMU_MEMORY_AP_READ_ONLY | MMU_MEMORY_XN)
+
 static uint64_t ddr_start;
 
 static mmu_section_t default_mmu_section_table[] =
@@ -77,10 +81,12 @@
 };
 
 
+/* Map the ddr for download mode, this region belongs to non-hlos images and pil */
 static mmu_section_t dload_mmu_section_table[] =
 {
-/*    Physical addr,    Virtual addr,     Mapping type ,              Size (in MB),            Flags */
-    { 0x85800000, 0x85800000, MMU_L2_NS_SECTION_MAPPING, 178, COMMON_MEMORY},
+/*    Physical addr,    Virtual addr,     Mapping type ,              Size (in MB),      Flags */
+    { 0x85800000,       0x85800000,       MMU_L2_NS_SECTION_MAPPING,  8,                 DLOAD_MEMORY},
+    { 0x86200000,       0x86200000,       MMU_L2_NS_SECTION_MAPPING,  174,               DLOAD_MEMORY},
 };
 
 void platform_early_init(void)
@@ -119,14 +125,23 @@
 	int table_sz = ARRAY_SIZE(default_mmu_section_table);
 	mmu_section_t kernel_mmu_section_table;
 	uint64_t ddr_size = smem_get_ddr_size();
+	uint32_t kernel_size = 0;
 
 	if (ddr_size == MEM_4GB)
 	{
 		ddr_start = 0x80000000;
+		/* As per the memory map when DDR is 4GB first 88 MB is hlos memory
+		 * use this for loading the kernel
+		 */
+		kernel_size = 88;
 	}
 	else if (ddr_size == MEM_3GB)
 	{
 		ddr_start = 0x20000000;
+		/* As per memory map wheh DDR is 3GB the first 512 MB is assigned to hlos
+		 * use this region for loading kernel
+		 */
+		kernel_size = 512;
 	}
 	else
 	{
@@ -137,8 +152,8 @@
 	kernel_mmu_section_table.paddress = ddr_start;
 	kernel_mmu_section_table.vaddress = ddr_start;
 	kernel_mmu_section_table.type = MMU_L2_NS_SECTION_MAPPING;
-	kernel_mmu_section_table.size = KERNEL_SIZE;
-	kernel_mmu_section_table.flags = COMMON_MEMORY;
+	kernel_mmu_section_table.size = kernel_size;
+	kernel_mmu_section_table.flags = SCRATCH_MEMORY;
 
 	/* Map kernel entry */
 	arm_mmu_map_entry(&kernel_mmu_section_table);
diff --git a/platform/msm8996/rules.mk b/platform/msm8996/rules.mk
index 8db37d5..66d6af7 100644
--- a/platform/msm8996/rules.mk
+++ b/platform/msm8996/rules.mk
@@ -4,7 +4,7 @@
 ARM_CPU := cortex-a8
 CPU     := generic
 
-DEFINES += ARM_CPU_CORE_KRAIT
+DEFINES += ARM_CPU_CORE_KRYO
 
 MMC_SLOT         := 1
 
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 36c72c9..4a1749b 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -1,28 +1,30 @@
 /*
- * Copyright (c) 2014-2015 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 met:
+ * modification, are permitted provided that the following conditions are
+ * met:
  *  * Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <stdlib.h>
@@ -39,19 +41,17 @@
 #include <string.h>
 #include <openssl/err.h>
 #include <platform.h>
+#include <qseecom_lk_api.h>
+#include <secapp_loader.h>
+#include <target.h>
 
 static KEYSTORE *oem_keystore;
 static KEYSTORE *user_keystore;
 static uint32_t dev_boot_state = RED;
-BUF_DMA_ALIGN(keystore_buf, 4096);
 char KEYSTORE_PTN_NAME[] = "keystore";
-
-static const char *VERIFIED_FLASH_ALLOWED_PTN[] = {
-	"aboot",
-	"boot",
-	"recovery",
-	"system",
-	NULL };
+RSA *rsa_from_cert = NULL;
+unsigned char fp[EVP_MAX_MD_SIZE];
+uint32_t fp_size;
 
 ASN1_SEQUENCE(AUTH_ATTR) ={
 	ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
@@ -221,6 +221,7 @@
 	int shift_bytes;
 	RSA *rsa = NULL;
 	bool keystore_verification = false;
+	EVP_PKEY* key = NULL;
 
 	if(!strcmp(pname, "keystore"))
 		keystore_verification = true;
@@ -259,23 +260,68 @@
 
 	/* append attribute to image */
 	if(!keystore_verification)
+	{
+		// verifying a non keystore partition
 		img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
 				sig->auth_attr);
+	}
 
 	/* compare SHA256SUM of image with value in signature */
 	if(ks != NULL)
-		rsa = ks->mykeybag->mykey->key_material;
-
-	ret = boot_verify_compare_sha256(img_addr, img_size,
-			(unsigned char*)sig->sig->data, rsa);
-
-	if(!ret)
 	{
-		dprintf(CRITICAL,
-				"boot_verifier: Image verification failed.\n");
+		// use rsa from keystore
+		rsa = ks->mykeybag->mykey->key_material;
+	}
+	else
+	{
+		dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
+		ASSERT(0);
+	}
+
+	// verify boot.img with rsa from oem keystore
+	if((ret = boot_verify_compare_sha256(img_addr, img_size,
+			(unsigned char*)sig->sig->data, rsa)))
+
+	{
+		dprintf(SPEW, "Verified boot.img with oem keystore\n");
+		boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
+		goto verify_image_with_sig_done;
+	}
+	else
+	{
+		dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
+		// get the public key from certificate in boot.img
+		if ((key = X509_get_pubkey(sig->certificate)))
+		{
+			// convert to rsa key format
+			dprintf(INFO, "RSA KEY found from the embedded certificate\n");
+			rsa = EVP_PKEY_get1_RSA(key);
+			rsa_from_cert = rsa;
+		}
+		else
+		{
+			dprintf(CRITICAL, "Unable to extract public key from certificate\n");
+			ASSERT(0);
+		}
+	}
+
+	// verify boot.img with rsa from embedded certificate
+	if ((ret = boot_verify_compare_sha256(img_addr, img_size,
+			(unsigned char*)sig->sig->data, rsa)))
+	{
+		dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
+		boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
+		goto verify_image_with_sig_done;
+	}
+	else
+	{
+		dprintf(INFO, "verified for red state\n");
+		boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
+		goto verify_image_with_sig_done;
 	}
 
 verify_image_with_sig_error:
+verify_image_with_sig_done:
 	return ret;
 }
 
@@ -334,68 +380,126 @@
 	}
 }
 
-static int read_user_keystore_ptn()
-{
-	int index = INVALID_PTN;
-	unsigned long long ptn = 0;
-
-	index = partition_get_index(KEYSTORE_PTN_NAME);
-	ptn = partition_get_offset(index);
-	if(ptn == 0) {
-		dprintf(CRITICAL, "boot_verifier: No keystore partition found\n");
-		return -1;
-	}
-
-	if (mmc_read(ptn, (unsigned int *) keystore_buf, mmc_page_size())) {
-		dprintf(CRITICAL, "boot_verifier: Cannot read user keystore\n");
-		return -1;
-	}
-	return 0;
-}
-
-static void read_user_keystore(unsigned char *user_addr)
-{
-	unsigned char *input = user_addr;
-	KEYSTORE *ks = NULL;
-	uint32_t len = read_der_message_length(input);
-	if(!len)
-	{
-		dprintf(CRITICAL, "boot_verifier: user keystore length is invalid.\n");
-		return;
-	}
-
-	ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
-	if(ks != NULL)
-	{
-		if(verify_keystore(user_addr, ks) == false)
-		{
-			dprintf(CRITICAL, "boot_verifier: Keystore verification failed!\n");
-			boot_verify_send_event(KEYSTORE_VERIFICATION_FAIL);
-		}
-		else
-			dprintf(CRITICAL, "boot_verifier: Keystore verification success!\n");
-		user_keystore = ks;
-	}
-	else
-	{
-		user_keystore = oem_keystore;
-	}
-}
-
 uint32_t boot_verify_keystore_init()
 {
 	/* Read OEM Keystore */
 	read_oem_keystore();
 
-	/* Read User Keystore */
-	if(!read_user_keystore_ptn())
-		read_user_keystore((unsigned char *)keystore_buf);
 	return dev_boot_state;
 }
 
+bool send_rot_command(uint32_t is_unlocked)
+{
+	int ret = 0;
+	unsigned char *input = NULL;
+	char *rot_input = NULL;
+	unsigned int digest[9] = {0}, final_digest[8] = {0};
+	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
+	uint32_t boot_device_state = boot_verify_get_state();
+	int app_handle = 0;
+	uint32_t len_oem_rsa = 0, len_from_cert = 0;
+	km_set_rot_req_t *read_req;
+	km_set_rot_rsp_t read_rsp;
+	app_handle = get_secapp_handle();
+	int n = 0, e = 0;
+	switch (boot_device_state)
+	{
+		case GREEN:
+			// Locked device and boot.img verified against OEM keystore.
+			// Send hash of key from OEM KEYSTORE + Boot device state
+			n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
+			e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
+			len_oem_rsa = n + e;
+			if(!(input = malloc(len_oem_rsa)))
+			{
+				dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+				ASSERT(0);
+			}
+			BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
+			BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
+			hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
+			digest[8] = is_unlocked;
+			break;
+		case YELLOW:
+		case RED:
+			// Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
+			if (!rsa_from_cert)
+			{
+				dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
+				ASSERT(0);
+			}
+			// Send hash of key from certificate in boot image + boot device state
+			n = BN_num_bytes(rsa_from_cert->n);
+			e = BN_num_bytes(rsa_from_cert->e);
+			len_from_cert = n + e;
+			if(!(input = malloc(len_from_cert)))
+			{
+				dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+				ASSERT(0);
+			}
+			BN_bn2bin(rsa_from_cert->n, input);
+			BN_bn2bin(rsa_from_cert->e, input+n);
+			hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
+			digest[8] = is_unlocked;
+			break;
+		case ORANGE:
+			// Unlocked device and no verification done.
+			// Send the hash of boot device state
+			input = NULL;
+			digest[0] = is_unlocked;
+			break;
+	}
+
+	hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
+	dprintf(SPEW, "Digest: ");
+	for(uint8_t i = 0; i < 8; i++)
+		dprintf(SPEW, "0x%x ", final_digest[i]);
+	dprintf(SPEW, "\n");
+	if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
+	{
+		dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+		ASSERT(0);
+	}
+
+	void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
+	// set ROT stucture
+	read_req->cmd_id = KEYMASTER_SET_ROT;
+	read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
+	read_req->rot_size  = sizeof(final_digest);
+	// copy the digest
+	memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
+	dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
+
+	ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(final_digest), (void*) &read_rsp, sizeof(read_rsp));
+	if (ret < 0 || read_rsp.status < 0)
+	{
+		dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
+		if(input)
+			free(input);
+		free(read_req);
+		free(rot_input);
+		return false;
+	}
+	dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
+	if(input)
+		free(input);
+	free(read_req);
+	free(rot_input);
+	return true;
+}
+
+unsigned char* get_boot_fingerprint(unsigned int* buf_size)
+{
+	*buf_size = fp_size;
+
+	return fp;
+}
+
 bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
 {
 	bool ret = false;
+	X509 *cert = NULL;
+	const EVP_MD *fp_type = NULL;
 	VERIFIED_BOOT_SIG *sig = NULL;
 	unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
 	uint32_t sig_len = read_der_message_length(sig_addr);
@@ -409,7 +513,7 @@
 
 	if(!sig_len)
 	{
-		dprintf(CRITICAL, "boot_verifier: Error while reading singature length.\n");
+		dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
 		goto verify_image_error;
 	}
 
@@ -420,13 +524,17 @@
 		goto verify_image_error;
 	}
 
+	cert = sig->certificate;
+	fp_type = EVP_sha1();
+	if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
+		dprintf(INFO,"Fail to create certificate fingerprint.\n");
+	}
+
 	ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
 
 verify_image_error:
 	if(sig != NULL)
 		VERIFIED_BOOT_SIG_free(sig);
-	if(!ret)
-		boot_verify_send_event(BOOT_VERIFICATION_FAIL);
 	return ret;
 }
 
@@ -437,11 +545,14 @@
 		case BOOT_INIT:
 			dev_boot_state = GREEN;
 			break;
-		case KEYSTORE_VERIFICATION_FAIL:
+		case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
+			dev_boot_state = GREEN;
+			break;
+		case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
 			if(dev_boot_state == GREEN)
 				dev_boot_state = YELLOW;
 			break;
-		case BOOT_VERIFICATION_FAIL:
+		case BOOTIMG_VERIFICATION_FAIL:
 			if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
 				dev_boot_state = RED;
 			break;
@@ -516,8 +627,3 @@
 
 	return false;
 }
-
-bool boot_verify_flash_allowed(const char * entry)
-{
-	return check_list(VERIFIED_FLASH_ALLOWED_PTN, entry);
-}
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index 6f0cc8f..0861cc8 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -286,9 +286,6 @@
 	uint32_t config = CRYPTO_RESET_CONFIG
 			| (dev->bam.pipe[CRYPTO_READ_PIPE_INDEX].pipe_num >> 1) << PIPE_SET_SELECT_SHIFT;
 
-	/* Configure CE clocks. */
-	clock_config_ce(dev->instance);
-
 	/* Setup BAM */
 	if (crypto_bam_init(dev) != CRYPTO_ERR_NONE)
 	{
diff --git a/platform/msm_shared/crypto5_wrapper.c b/platform/msm_shared/crypto5_wrapper.c
index 0be227a..868eca0 100644
--- a/platform/msm_shared/crypto5_wrapper.c
+++ b/platform/msm_shared/crypto5_wrapper.c
@@ -28,6 +28,7 @@
 
 #include <debug.h>
 #include <crypto5_wrapper.h>
+#include <platform/clock.h>
 
 /* This file is a wrapper to the crypto5_eng.c.
  * This is required so that we maintian the backward compatibility
@@ -52,7 +53,8 @@
 
 void ce_clock_init(void)
 {
-	/* Clock init is done during crypto_init. */
+	/* Configure CE clocks. */
+	clock_config_ce(dev.instance);
 }
 
 void crypto_eng_reset(void)
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
new file mode 100644
index 0000000..895db07
--- /dev/null
+++ b/platform/msm_shared/display_menu.c
@@ -0,0 +1,341 @@
+/* Copyright (c) 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
+* met:
+*     * Redistributions of source code must retain the above copyright
+*	notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*	copyright notice, this list of conditions and the following
+*	disclaimer in the documentation and/or other materials provided
+*	with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*	contributors may be used to endorse or promote products derived
+*	from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <debug.h>
+#include <reg.h>
+#include <stdlib.h>
+#include <openssl/evp.h>
+#include <dev/fbcon.h>
+#include <kernel/thread.h>
+#include <display_menu.h>
+#include <menu_keys_detect.h>
+#include <boot_verifier.h>
+#include <string.h>
+#include <platform.h>
+
+#define UNLOCK_OPTION_NUM		2
+#define BOOT_VERIFY_OPTION_NUM		5
+
+static char *unlock_menu_common_msg = "If you unlock the bootloader, "\
+				"you will be able to install "\
+				"custom operating system on this phone.\n\n"\
+				"A custom OS is not subject to the same testing "\
+				"as the original OS, "\
+				"and can cause your phone and installed "\
+				"applications to stop working properly.\n\n"\
+				"To prevent unauthorized access to your personal data, "\
+				"unlocking the bootloader will also delete all personal "\
+				"data from your phone(a \"fatory data reset\").\n\n"\
+				"Press the Volume Up/Down buttons to select Yes "\
+				"or No. Then press the Power button to continue.\n";
+
+static char *yellow_warning_msg = "Your device has loaded a diffrent operating "\
+				"system\n\nTo learn more, visit:\n";
+
+static char *orange_warning_msg = "Your device has been unlocker and cann't "\
+				"be trusted\n\nTo learn more, visit:\n";
+
+static char *red_warning_msg = "Your device has failed verification and may "\
+				"not work properly\n\nTo learn more, visit:\n";
+
+static bool is_thread_start = false;
+struct select_msg_info msg_info;
+
+static char *option_menu[] = {
+		[POWEROFF] = "Power off\n",
+		[RESTART] = "Restart\n",
+		[RECOVER] = "Recovery\n",
+		[FASTBOOT] = "Fastboot\n",
+		[BACK] = "Back to previous page\n"};
+
+static int big_factor = 2;
+static int common_factor = 1;
+
+void wait_for_users_action()
+{
+	struct select_msg_info *select_msg;
+	select_msg = &msg_info;
+
+	while(1) {
+		if (select_msg->msg_timeout == true &&
+			select_msg->msg_volume_key_pressed == false)
+			break;
+		if (select_msg->msg_power_key_pressed == true)
+			break;
+
+		thread_sleep(10);
+	}
+	fbcon_clear();
+	display_image_on_screen();
+}
+
+static void set_message_factor()
+{
+	uint32_t tmp_factor = 0;
+	uint32_t max_x_count = 40;
+	uint32_t max_x = fbcon_get_max_x();
+
+	max_x = fbcon_get_max_x();
+	tmp_factor = max_x/max_x_count;
+
+	if(tmp_factor <= 1) {
+		big_factor = 2;
+		common_factor = 1;
+	} else {
+		big_factor = tmp_factor*2;
+		common_factor = tmp_factor;
+	}
+}
+
+static void display_fbcon_menu_message(char *str, unsigned type,
+	unsigned scale_factor)
+{
+	while(*str != 0) {
+		fbcon_putc_factor(*str++, type, scale_factor);
+	}
+}
+
+static char *str_align_right(char *str, int factor)
+{
+	uint32_t max_x = 0;
+	int diff = 0;
+	int i = 0;
+	char *str_target = NULL;
+
+	max_x = fbcon_get_max_x();
+	if (!str_target && max_x) {
+		str_target = malloc(max_x);
+	}
+
+	if (str_target) {
+		memset(str_target, 0, max_x);
+		if ( max_x/factor > strlen(str)) {
+			if (factor == 1)
+				diff = max_x/factor - strlen(str) - 1;
+			else
+				diff = max_x/factor - strlen(str);
+			for (i = 0; i < diff; i++) {
+				strcat(str_target, " ");
+			}
+			strcat(str_target, str);
+			return str_target;
+		} else {
+			free(str_target);
+			return str;
+		}
+	}
+	return str;
+}
+
+void display_unlock_menu(struct select_msg_info *unlock_msg_info)
+{
+	fbcon_clear();
+	memset(unlock_msg_info, 0, sizeof(struct select_msg_info));
+	display_fbcon_menu_message("Unlock bootloader?\n",
+		FBCON_UNLOCK_TITLE_MSG, big_factor);
+	fbcon_draw_line();
+
+	display_fbcon_menu_message(unlock_menu_common_msg,
+		FBCON_COMMON_MSG, common_factor);
+	fbcon_draw_line();
+	unlock_msg_info->option_start[0] = fbcon_get_current_line();
+	display_fbcon_menu_message("Yes\n",
+		FBCON_COMMON_MSG, big_factor);
+	unlock_msg_info->option_bg[0] = fbcon_get_current_bg();
+	display_fbcon_menu_message("Unlock bootloader(may void warranty)\n",
+		FBCON_COMMON_MSG, common_factor);
+	unlock_msg_info->option_end[0] = fbcon_get_current_line();
+	fbcon_draw_line();
+	unlock_msg_info->option_start[1] = fbcon_get_current_line();
+	display_fbcon_menu_message("No\n",
+		FBCON_COMMON_MSG, big_factor);
+	unlock_msg_info->option_bg[1] = fbcon_get_current_bg();
+	display_fbcon_menu_message("Do not unlock bootloader and restart phone\n",
+		FBCON_COMMON_MSG, common_factor);
+	unlock_msg_info->option_end[1] = fbcon_get_current_line();
+	fbcon_draw_line();
+
+	unlock_msg_info->msg_type = DISPLAY_MENU_UNLOCK;
+	unlock_msg_info->option_num = UNLOCK_OPTION_NUM;
+}
+
+void display_boot_verified_menu(struct select_msg_info *msg_info, int type)
+{
+	int msg_type = FBCON_COMMON_MSG;
+	char *warning_msg = NULL;
+	unsigned char* fp_buf = NULL;
+	char fp_str_temp[EVP_MAX_MD_SIZE] = {'\0'};
+	char fp_str[EVP_MAX_MD_SIZE*2] = {'\0'};
+	char str_temp[8];
+
+	char str1[]= "Start >";
+	char str2[] = "Continue boot";
+	char *str_target = NULL;
+	uint32 fp_size = 0;
+	unsigned int i = 0;
+
+	fbcon_clear();
+	memset(msg_info, 0, sizeof(struct select_msg_info));
+
+	switch (type) {
+	case DISPLAY_MENU_RED:
+		msg_type = FBCON_RED_MSG;
+		warning_msg = red_warning_msg;
+		break;
+        case DISPLAY_MENU_YELLOW:
+		msg_type = FBCON_YELLOW_MSG;
+		warning_msg = yellow_warning_msg;
+                break;
+	case DISPLAY_MENU_ORANGE:
+		msg_type = FBCON_ORANGE_MSG;
+		warning_msg = orange_warning_msg;
+                break;
+	}
+
+	/* Align Right */
+	str_target = str_align_right(str1, big_factor);
+	if(str_target != NULL)
+		display_fbcon_menu_message(str_target, FBCON_TITLE_MSG, big_factor);
+
+	str_target = str_align_right(str2, common_factor);
+	if(str_target != NULL)
+		display_fbcon_menu_message(str_target, FBCON_TITLE_MSG, common_factor);
+
+	display_fbcon_menu_message("\n< More options\n",
+		FBCON_COMMON_MSG, common_factor);
+	display_fbcon_menu_message("press VOLUME keys\n\n",
+		FBCON_SUBTITLE_MSG, common_factor);
+	if(warning_msg != NULL)
+		display_fbcon_menu_message(warning_msg, FBCON_COMMON_MSG, common_factor);
+
+	display_fbcon_menu_message("g.co/placeholder\n",
+		msg_type, common_factor);
+
+#if VERIFIED_BOOT
+	if (type == DISPLAY_MENU_YELLOW) {
+		fp_buf = get_boot_fingerprint(&fp_size);
+		if (fp_buf != NULL) {
+			strncpy(fp_str_temp, (char const *)fp_buf, fp_size);
+			for (i = 0; i < fp_size; i++) {
+				if(i == fp_size - 1)
+					sprintf(str_temp, "%02x", fp_str_temp[i]);
+				else
+					sprintf(str_temp, "%02x-", fp_str_temp[i]);
+
+				strcat(fp_str, str_temp);
+			}
+		}
+		display_fbcon_menu_message("ID:", FBCON_COMMON_MSG, common_factor);
+		display_fbcon_menu_message(fp_str, FBCON_COMMON_MSG, common_factor);
+	}
+#endif
+
+	display_fbcon_menu_message("\n\nIf no key pressed:\n"\
+		"Your device will boot in 5 seconds\n\n", FBCON_COMMON_MSG, common_factor);
+
+	msg_info->msg_type = type;
+	if(str_target) {
+		free(str_target);
+	}
+}
+
+void display_boot_verified_option(struct select_msg_info *msg_info)
+{
+	int i = 0;
+	fbcon_clear();
+	memset(msg_info, 0, sizeof(struct select_msg_info));
+
+	display_fbcon_menu_message("Options menu:\n\n",
+		FBCON_COMMON_MSG, big_factor);
+	display_fbcon_menu_message("Press volume key to select, and "\
+		"press power key to select\n\n", FBCON_COMMON_MSG, common_factor);
+
+	for (i = 0; i < BOOT_VERIFY_OPTION_NUM; i++) {
+		fbcon_draw_line();
+		msg_info->option_start[i] = fbcon_get_current_line();
+		display_fbcon_menu_message(option_menu[i],
+			FBCON_COMMON_MSG, common_factor);
+		msg_info->option_bg[i]= fbcon_get_current_bg();
+		msg_info->option_end[i]= fbcon_get_current_line();
+	}
+
+	fbcon_draw_line();
+	msg_info->msg_type = DISPLAY_MENU_MORE_OPTION;
+	msg_info->option_num = BOOT_VERIFY_OPTION_NUM;
+}
+
+static void display_menu_thread_start(struct select_msg_info *msg_info)
+{
+	thread_t *thr;
+
+	if (!is_thread_start) {
+		thr = thread_create("selectkeydetect", &select_msg_keys_detect,
+			(void*)msg_info, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
+		if (!thr) {
+			dprintf(CRITICAL, "ERROR: creat device status detect thread failed!!\n");
+			return;
+		}
+		thread_resume(thr);
+	}
+
+	is_thread_start = true;
+}
+
+void display_menu_thread(int type)
+{
+	struct select_msg_info *display_menu_msg_info;
+	display_menu_msg_info = &msg_info;
+	int menu_type = 0;
+
+	set_message_factor();
+	if (type == DISPLAY_THREAD_UNLOCK) {
+		display_unlock_menu(display_menu_msg_info);
+
+		dprintf(INFO, "creating oem unlock keys detect thread\n");
+		display_menu_thread_start(display_menu_msg_info);
+	} else {
+	#if VERIFIED_BOOT
+		if (boot_verify_get_state() == ORANGE) {
+			menu_type = DISPLAY_MENU_ORANGE;
+		} else if (boot_verify_get_state() == YELLOW) {
+			menu_type = DISPLAY_MENU_YELLOW;
+		} else if (boot_verify_get_state() == RED) {
+			menu_type = DISPLAY_MENU_RED;
+		}
+		display_boot_verified_menu(display_menu_msg_info, menu_type);
+
+		dprintf(INFO, "creating device state keys detect thread\n");
+		display_menu_thread_start(display_menu_msg_info);
+
+	#else
+		dprintf(CRITICAL, "VERIFIED_BOOT is not enable!!\n");
+		return;
+	#endif
+	}
+}
+
diff --git a/platform/msm_shared/dme.c b/platform/msm_shared/dme.c
index 47e94b0..f83ee93 100644
--- a/platform/msm_shared/dme.c
+++ b/platform/msm_shared/dme.c
@@ -291,19 +291,19 @@
 
 int dme_set_fdeviceinit(struct ufs_dev *dev)
 {
-	STACKBUF_DMA_ALIGN(result, sizeof(uint32_t));
+	uint32_t result;
 	uint32_t try_again                        = DME_FDEVICEINIT_RETRIES;
 	struct utp_query_req_upiu_type read_query = {UPIU_QUERY_OP_READ_FLAG,
 												 UFS_IDX_fDeviceInit,
 												 0,
 												 0,
-												 (addr_t) result,
+												 (addr_t) &result,
 												 sizeof(uint32_t)};
 	struct utp_query_req_upiu_type set_query  = {UPIU_QUERY_OP_SET_FLAG,
 												 UFS_IDX_fDeviceInit,
 												 0,
 												 0,
-												 (addr_t) result,
+												 (addr_t) &result,
 												 sizeof(uint32_t)};
 
 
@@ -313,9 +313,7 @@
 		return -UFS_FAILURE;
 	}
 
-	arch_invalidate_cache_range((addr_t) result, sizeof(uint32_t));
-
-	if (*result == 1)
+	if (result == 1)
 		goto utp_set_fdeviceinit_done;
 
 	do
@@ -334,7 +332,7 @@
 			return -UFS_FAILURE;
 		}
 
-		if (*result == 1)
+		if (result == 1)
 			break;
 	} while (try_again);
 
@@ -383,15 +381,13 @@
 
 int dme_read_device_desc(struct ufs_dev *dev)
 {
-	STACKBUF_DMA_ALIGN(dev_desc, sizeof(struct ufs_dev_desc));
-	STACKBUF_DMA_ALIGN(desc, sizeof(struct ufs_string_desc));
-	struct ufs_dev_desc            *device_desc = (struct ufs_dev_desc *) dev_desc;
-	struct ufs_string_desc         *str_desc    = (struct ufs_string_desc *) desc;
+	struct ufs_dev_desc            device_desc;
+	struct ufs_string_desc         str_desc;
 	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
 											UFS_DESC_IDN_DEVICE,
 											0,
 											0,
-											(addr_t) dev_desc,
+											(addr_t) &device_desc,
 											sizeof(struct ufs_dev_desc)};
 
 	if (dme_send_query_upiu(dev, &query))
@@ -400,20 +396,14 @@
 		return -UFS_FAILURE;
 	}
 
-	/* Flush buffer. */
-	arch_invalidate_cache_range((addr_t) device_desc, sizeof(struct ufs_dev_desc));
-
 	/* Store all relevant data */
-	dev->num_lus = device_desc->num_lu;
+	dev->num_lus = device_desc.num_lu;
 
 	/* Get serial number for the device based on the string index. */
-	if (dme_read_string_desc(dev, device_desc->serial_num, (struct ufs_string_desc *) desc))
+	if (dme_read_string_desc(dev, device_desc.serial_num, (struct ufs_string_desc *) &str_desc))
 		return -UFS_FAILURE;
 
-	/* Flush buffer. */
-	arch_invalidate_cache_range((addr_t) str_desc, sizeof(struct ufs_string_desc));
-
-	dev->serial_num = dme_parse_serial_no(str_desc);
+	dev->serial_num = dme_parse_serial_no(&str_desc);
 
 	return UFS_SUCCESS;
 }
@@ -437,21 +427,19 @@
 		return -UFS_FAILURE;
 	}
 
-	// Flush buffer.
-	arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_geometry_desc));
 	dev->rpmb_rw_size = desc->rpmb_read_write_size;
 	return UFS_SUCCESS;
 }
 
 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 = (struct ufs_unit_desc *) unit_desc;
+	struct ufs_unit_desc unit_desc;
+	struct ufs_unit_desc           *desc = (struct ufs_unit_desc *) &unit_desc;
 	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
 											UFS_DESC_IDN_UNIT,
 											index,
 											0,
-											(addr_t) unit_desc,
+											(addr_t) &unit_desc,
 											sizeof(struct ufs_unit_desc)};
 
 	if (dme_send_query_upiu(dev, &query))
@@ -459,8 +447,6 @@
 		dprintf(CRITICAL, "%s:%d DME Read Unit Descriptor request failed\n", __func__, __LINE__);
 		return -UFS_FAILURE;
 	}
-	/* Flush buffer. */
-	arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_unit_desc));
 
 	dev->lun_cfg[index].logical_blk_cnt = BE64(desc->logical_blk_cnt);
 
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index efe0c1b..07fb923 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -1,29 +1,32 @@
 /*
- * Copyright (c) 2014-2015 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 met:
+ * modification, are permitted provided that the following conditions are
+ * met:
  *  * Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #ifndef __BOOT_VERIFIER_H
 #define __BOOT_VERIFIER_H
 
@@ -34,6 +37,7 @@
  *    AndroidVerifiedBootSignature DEFINITIONS ::=
  *    BEGIN
  *        FormatVersion ::= INTEGER
+ *        Certificate ::= Certificate
  *        AlgorithmIdentifier ::=  SEQUENCE {
  *            algorithm OBJECT IDENTIFIER,
  *            parameters ANY DEFINED BY algorithm OPTIONAL
@@ -134,12 +138,25 @@
 	RED,
 };
 
+struct verified_boot_verity_mode
+{
+	bool verity_mode_enforcing;
+	char *name;
+};
+
+struct verified_boot_state_name
+{
+	uint32_t boot_state;
+	char *name;
+};
+
 enum boot_verfiy_event
 {
 	BOOT_INIT,
 	DEV_UNLOCK,
-	KEYSTORE_VERIFICATION_FAIL,
-	BOOT_VERIFICATION_FAIL,
+	BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS,
+	BOOTIMG_KEYSTORE_VERIFICATION_PASS,
+	BOOTIMG_VERIFICATION_FAIL,
 	USER_DENIES,
 };
 
@@ -158,4 +175,7 @@
 bool boot_verify_validate_keystore(unsigned char * user_addr);
 /* Function to check if partition is allowed to flash in verified mode */
 bool boot_verify_flash_allowed(const char * entry);
+/* 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);
 #endif
diff --git a/platform/msm_shared/include/clock_lib2.h b/platform/msm_shared/include/clock_lib2.h
index 6b07d45..6023044 100644
--- a/platform/msm_shared/include/clock_lib2.h
+++ b/platform/msm_shared/include/clock_lib2.h
@@ -106,7 +106,7 @@
 #define CFG_SRC_DIV_MASK        (0x1F << CFG_SRC_DIV_OFFSET)
 
 #define CFG_SRC_SEL_OFFSET      8
-#define CFG_SRC_SEL_MASK        (0x3 << CFG_SRC_SEL_OFFSET)
+#define CFG_SRC_SEL_MASK        (0x7 << CFG_SRC_SEL_OFFSET)
 
 #define CFG_MODE_DUAL_EDGE      0x2
 
diff --git a/platform/msm_shared/include/display_menu.h b/platform/msm_shared/include/display_menu.h
new file mode 100644
index 0000000..2350fe9
--- /dev/null
+++ b/platform/msm_shared/include/display_menu.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 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
+* met:
+*     * Redistributions of source code must retain the above copyright
+*	notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*	copyright notice, this list of conditions and the following
+*	disclaimer in the documentation and/or other materials provided
+*	with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*	contributors may be used to endorse or promote products derived
+*	from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __PLATFORM_MSM_SHARED_DISPLAY_MENU_H
+#define __PLATFORM_MSM_SHARED_DISPLAY_MENU_H
+
+#include <openssl/evp.h>
+
+#define SELECT_OPTION_MAX	5
+
+enum display_menu_type {
+	DISPLAY_MENU_YELLOW = 0,
+	DISPLAY_MENU_ORANGE,
+	DISPLAY_MENU_RED,
+	DISPLAY_MENU_MORE_OPTION,
+	DISPLAY_MENU_UNLOCK,
+};
+
+struct select_msg_info {
+	uint32_t	option_start[SELECT_OPTION_MAX];
+	uint32_t	option_end[SELECT_OPTION_MAX];
+	uint32_t	option_bg[SELECT_OPTION_MAX];
+	uint32_t	option_num;
+	uint32_t	msg_type;
+	bool		msg_timeout;
+	bool		msg_power_key_pressed;
+	bool		msg_volume_key_pressed;
+};
+
+enum display_thread_type {
+	DISPLAY_THREAD_UNLOCK = 0,
+	DISPLAY_THREAD_BOOT_STATE,
+};
+
+void wait_for_users_action(void);
+void display_unlock_menu(struct select_msg_info *msg_info);
+void display_boot_verified_menu(struct select_msg_info *msg_info, int type);
+void display_boot_verified_option(struct select_msg_info *msg_info);
+void display_menu_thread(int type);
+#endif				/* __PLATFORM_MSM_SHARED_DISPLAY_MENU_H */
diff --git a/platform/msm_shared/include/menu_keys_detect.h b/platform/msm_shared/include/menu_keys_detect.h
new file mode 100644
index 0000000..31a5661
--- /dev/null
+++ b/platform/msm_shared/include/menu_keys_detect.h
@@ -0,0 +1,56 @@
+/* Copyright (c) 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
+* met:
+*     * Redistributions of source code must retain the above copyright
+*	notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*	copyright notice, this list of conditions and the following
+*	disclaimer in the documentation and/or other materials provided
+*	with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*	contributors may be used to endorse or promote products derived
+*	from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __PLATFORM_MSM_SHARED_KEYS_DETECT_H
+#define __PLATFORM_MSM_SHARED_KEYS_DETECT_H
+
+enum device_select_option {
+	POWEROFF = 0,
+	RESTART,
+	RECOVER,
+	FASTBOOT,
+	BACK,
+
+	CONTINUE,
+};
+
+enum keys_option {
+	VOLUME_UP = 0,
+	VOLUME_DOWN,
+	POWER_KEY,
+};
+
+enum pages_type {
+	UNLOCK_PAGE = 0,
+	BOOT_VERIFY_PAGE1,
+	BOOT_VERIFY_PAGE2,
+};
+
+int select_msg_keys_detect(void *param);
+void keys_detect_init();
+#endif				/* __PLATFORM_MSM_SHARED_KEYS_DETECT_H */
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index f954dfb..58f40a6 100644
--- a/platform/msm_shared/include/rpmb.h
+++ b/platform/msm_shared/include/rpmb.h
@@ -41,28 +41,6 @@
 #define RPMB_MIN_BLK_CNT            1
 #define RPMB_MIN_BLK_SZ             512
 
-enum app_commands
-{
-	CLIENT_CMD_READ_LK_DEVICE_STATE = 0,
-	CLIENT_CMD_LK_END_MILESTONE,
-	CLIENT_CMD_GET_VERSION,
-	CLIENT_CMD_WRITE_LK_DEVICE_STATE,
-};
-
-struct send_cmd_req
-{
-	uint32_t cmd_id;
-	uint32_t data;
-	uint32_t len;
-}__PACKED;
-
-struct send_cmd_rsp
-{
-	uint32_t cmd_id;
-	uint32_t data;
-	int32_t status;
-}__PACKED;
-
 enum device_type
 {
 	EMMC_RPMB = 3,
@@ -159,7 +137,4 @@
 int rpmb_read(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
 struct rpmb_init_info *rpmb_get_init_info();
 int rpmb_get_app_handle();
-bool is_sec_app_loaded();
-int load_sec_app();
-int unload_sec_app();
 #endif
diff --git a/platform/msm_shared/include/secapp_loader.h b/platform/msm_shared/include/secapp_loader.h
new file mode 100644
index 0000000..0949562
--- /dev/null
+++ b/platform/msm_shared/include/secapp_loader.h
@@ -0,0 +1,63 @@
+/* Copyright (c) 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
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SAL_MAIN_H
+#define SAL_MAIN_H
+
+#include <km_main.h>
+
+enum app_commands
+{
+	CLIENT_CMD_READ_LK_DEVICE_STATE = 0,
+	CLIENT_CMD_LK_END_MILESTONE,
+	CLIENT_CMD_GET_VERSION,
+	CLIENT_CMD_WRITE_LK_DEVICE_STATE,
+};
+
+struct send_cmd_req
+{
+	uint32_t cmd_id;
+	uint32_t data;
+	uint32_t len;
+}__PACKED;
+
+struct send_cmd_rsp
+{
+	uint32_t cmd_id;
+	uint32_t data;
+	int32_t status;
+}__PACKED;
+
+int get_secapp_handle();
+bool is_sec_app_loaded();
+int load_sec_app();
+int get_secapp_handle();
+int send_milestone_call_to_tz();
+int send_delete_keys_to_tz();
+
+#endif /* SAL_MAIN_H */
diff --git a/platform/msm_shared/menu_keys_detect.c b/platform/msm_shared/menu_keys_detect.c
new file mode 100644
index 0000000..472814d
--- /dev/null
+++ b/platform/msm_shared/menu_keys_detect.c
@@ -0,0 +1,325 @@
+/* Copyright (c) 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
+* met:
+*     * Redistributions of source code must retain the above copyright
+*	notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*	copyright notice, this list of conditions and the following
+*	disclaimer in the documentation and/or other materials provided
+*	with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*	contributors may be used to endorse or promote products derived
+*	from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <debug.h>
+#include <reg.h>
+#include <stdlib.h>
+#include <pm8x41.h>
+#include <pm8x41_hw.h>
+#include <kernel/timer.h>
+#include <platform/timer.h>
+#include <kernel/thread.h>
+#include <dev/keys.h>
+#include <dev/fbcon.h>
+#include <menu_keys_detect.h>
+#include <display_menu.h>
+#include <platform/gpio.h>
+#include <platform/iomap.h>
+#include <platform.h>
+#include <../../../app/aboot/recovery.h>
+
+#define KEY_DETECT_FREQUENCY		50
+#define KEY_PRESS_TIMEOUT		5000
+
+#define RECOVERY_MODE   0x77665502
+#define FASTBOOT_MODE   0x77665500
+
+static uint32_t wait_time = 0;
+static int old_device_type = -1;
+
+extern int target_volume_up();
+extern uint32_t target_volume_down();
+extern void reboot_device(unsigned reboot_reason);
+extern void shutdown_device();
+
+typedef uint32_t (*keys_detect_func)(void);
+typedef uint32_t (*keys_action_func)(struct select_msg_info* msg_info,
+	uint32_t option_index);
+
+struct keys_stru {
+	int type;
+	keys_detect_func keys_pressed_func;
+};
+
+struct keys_stru keys[] = {
+	{VOLUME_UP, (uint32_t (*)(void))target_volume_up},
+	{VOLUME_DOWN, target_volume_down},
+	{POWER_KEY, pm8x41_get_pwrkey_is_pressed},
+};
+
+struct pages_action {
+	keys_action_func up_action_func;
+	keys_action_func down_action_func;
+	keys_action_func enter_action_func;
+};
+
+static int is_key_pressed(int keys_type)
+{
+	int count = 0;
+
+	if (keys[keys_type].keys_pressed_func()) {
+		/*if key is pressed, wait for 1 second to see if it is released*/
+		while(count++ < 10 && keys[keys_type].keys_pressed_func())
+			thread_sleep(100);
+		return 1;
+	}
+
+	return 0;
+}
+
+static void update_device_status(unsigned reason)
+{
+	if (reason == RECOVER) {
+		/* wipe data */
+		struct recovery_message msg;
+
+		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+		write_misc(0, &msg, sizeof(msg));
+
+		reboot_device(RECOVERY_MODE);
+	} else if (reason == RESTART) {
+		reboot_device(0);
+	} else if (reason == POWEROFF) {
+		shutdown_device();
+	} else if (reason == FASTBOOT) {
+		reboot_device(FASTBOOT_MODE);
+	} else if (reason == CONTINUE) {
+		fbcon_clear();
+		display_image_on_screen();
+	}
+}
+
+static void update_volume_up_bg(struct select_msg_info* msg_info, uint32_t option_index)
+{
+	if (option_index == msg_info->option_num - 1) {
+		fbcon_draw_msg_background(msg_info->option_start[0],
+			msg_info->option_end[0],
+			msg_info->option_bg[0], 0);
+
+		fbcon_draw_msg_background(msg_info->option_start[msg_info->option_num - 1],
+			msg_info->option_end[msg_info->option_num - 1],
+			msg_info->option_bg[msg_info->option_num - 1], 1);
+	} else {
+		fbcon_draw_msg_background(msg_info->option_start[option_index],
+			msg_info->option_end[option_index],
+			msg_info->option_bg[option_index], 1);
+
+		fbcon_draw_msg_background(msg_info->option_start[option_index + 1],
+			msg_info->option_end[option_index + 1],
+			msg_info->option_bg[option_index + 1], 0);
+	}
+}
+
+static void update_volume_down_bg(struct select_msg_info* msg_info, uint32_t option_index)
+{
+	if (option_index == 0) {
+		fbcon_draw_msg_background(msg_info->option_start[0],
+			msg_info->option_end[0],
+			msg_info->option_bg[0], 1);
+
+		fbcon_draw_msg_background(msg_info->option_start[msg_info->option_num - 1],
+			msg_info->option_end[msg_info->option_num - 1],
+			msg_info->option_bg[msg_info->option_num - 1], 0);
+	} else {
+		fbcon_draw_msg_background(msg_info->option_start[option_index],
+			msg_info->option_end[option_index],
+			msg_info->option_bg[option_index], 1);
+
+		fbcon_draw_msg_background(msg_info->option_start[option_index - 1],
+			msg_info->option_end[option_index - 1],
+			msg_info->option_bg[option_index - 1], 0);
+	}
+}
+
+/* update select option's background when volume up key is pressed */
+static uint32_t menu_volume_up_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	if (option_index == msg_info->option_num ||
+		option_index == 0) {
+		option_index = msg_info->option_num - 1;
+	} else if (option_index > 0) {
+		option_index--;
+	}
+
+	update_volume_up_bg(msg_info, option_index);
+
+	return option_index;
+}
+
+/* update select option's background when volume down key is pressed */
+static uint32_t menu_volume_down_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	option_index++;
+	if (option_index >= msg_info->option_num)
+		option_index = 0;
+
+	update_volume_down_bg(msg_info, option_index);
+
+	return option_index;
+}
+
+/* enter to boot verify page2 if volume key is pressed */
+static uint32_t boot_page1_volume_keys_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	keys_detect_init();
+	old_device_type = msg_info->msg_type;
+	display_boot_verified_option(msg_info);
+	msg_info->msg_volume_key_pressed = true;
+	option_index = msg_info->option_num;
+
+	return option_index;
+}
+
+/* update device's status via select option */
+static uint32_t unlock_power_key_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	int device_state = -1;
+	if (option_index == 0)
+		device_state = RECOVER;
+	else if (option_index == 1)
+		device_state = RESTART;
+
+	update_device_status(device_state);
+	return 0;
+}
+
+/* continue booting when power key is pressed at boot-verify page1 */
+static uint32_t boot_page1_power_key_func (struct select_msg_info* msg_info,
+	uint32_t option_index){
+	update_device_status(CONTINUE);
+	return option_index;
+}
+
+/* update device's status via select option */
+static uint32_t boot_page2_power_key_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	if (option_index == BACK) {
+		wait_time = 0;
+		msg_info->msg_timeout = false;
+		option_index = msg_info->option_num;
+		display_boot_verified_menu(msg_info,
+			old_device_type);
+	} else {
+		msg_info->msg_power_key_pressed = true;
+		update_device_status(option_index);
+	}
+	return option_index;
+}
+
+/* initialize different page's function
+ * UNLOCK_PAGE/BOOT_VERIFY_PAGE2:
+ *	up_action_func: update select option's background when volume up
+ *	is pressed
+ *	down_action_func: update select option's background when volume up
+ *	is pressed
+ *	enter_action_func: update device's status via select option
+ * BOOT_VERIFY_PAGE1:
+ *	up_action_func/down_action_func: enter BOOT_VERIFY_PAGE2 when volume
+ *	key is pressed
+ *	enter_action_func: continue booting
+ */
+static struct pages_action menu_pages_action[] = {
+	[UNLOCK_PAGE] = {
+		menu_volume_up_func,
+		menu_volume_down_func,
+		unlock_power_key_func,
+	},
+	[BOOT_VERIFY_PAGE1] = {
+		boot_page1_volume_keys_func,
+		boot_page1_volume_keys_func,
+		boot_page1_power_key_func,
+	},
+	[BOOT_VERIFY_PAGE2] = {
+		menu_volume_up_func,
+		menu_volume_down_func,
+		boot_page2_power_key_func,
+	},
+};
+
+void keys_detect_init()
+{
+	wait_time = 0;
+}
+
+int select_msg_keys_detect(void *param) {
+	struct select_msg_info *msg_info = (struct select_msg_info*)param;
+	uint32_t current_page_index;
+	uint32_t option_index = msg_info->option_num;
+
+	keys_detect_init();
+	while(1) {
+		/* get page's index via different message type */
+		switch(msg_info->msg_type) {
+		case DISPLAY_MENU_UNLOCK:
+			current_page_index = UNLOCK_PAGE;
+			break;
+		case DISPLAY_MENU_MORE_OPTION:
+			current_page_index = BOOT_VERIFY_PAGE2;
+			break;
+		default:
+			current_page_index = BOOT_VERIFY_PAGE1;
+			break;
+		}
+
+		/* device will continue booting when user has no action
+		 * on BOOT_VERIFY_PAGE1
+		 */
+		if (wait_time > KEY_PRESS_TIMEOUT)
+			msg_info->msg_timeout = true;
+
+		/* 1: update select option's index, default it is the total option number
+		 *  volume up: index decrease, the option will scroll up from
+		 * 	the bottom to top if the key is pressed firstly.
+		 *	eg: 5->4->3->2->1->0
+		 *  volume down: index increase, the option will scroll down from
+		 * 	the bottom to top if the key is pressed firstly.
+		 *	eg: 5->0
+		 * 2: update device's status via select option's index
+		 */
+		if (is_key_pressed(VOLUME_UP)) {
+			option_index =
+				menu_pages_action[current_page_index].up_action_func(msg_info, option_index);
+		} else if (is_key_pressed(VOLUME_DOWN)) {
+			option_index =
+				menu_pages_action[current_page_index].down_action_func(msg_info, option_index);
+		} else if (is_key_pressed(POWER_KEY)) {
+			option_index =
+				menu_pages_action[current_page_index].enter_action_func(msg_info, option_index);
+		}
+
+		wait_time += KEY_DETECT_FREQUENCY;
+		thread_sleep(KEY_DETECT_FREQUENCY);
+	}
+
+	return 0;
+}
diff --git a/platform/msm_shared/mipi_dsi_phy.c b/platform/msm_shared/mipi_dsi_phy.c
index b7faf5d..1321e9f 100644
--- a/platform/msm_shared/mipi_dsi_phy.c
+++ b/platform/msm_shared/mipi_dsi_phy.c
@@ -399,13 +399,19 @@
 	writel(0x0a, phy_base + 0x0180);
 	dmb();
 
-	dsi0_phy_base = DSI0_PHY_BASE + target_display_get_base_offset(DSI0_PHY_BASE);
 	/* DSI_PHY_DSIPHY_GLBL_TEST_CTRL */
-	if ((phy_base == dsi0_phy_base) ||
-		(readl(mipi->ctl_base) == DSI_HW_REV_103_1))
+	if (mipi->dual_dsi) {
+		dsi0_phy_base = DSI0_PHY_BASE +
+			target_display_get_base_offset(DSI0_PHY_BASE);
+		if ((phy_base == dsi0_phy_base) ||
+			(readl(mipi->ctl_base) == DSI_HW_REV_103_1))
+			writel(0x01, phy_base + 0x01d4);
+		else
+			writel(0x00, phy_base + 0x01d4);
+	} else {
 		writel(0x01, phy_base + 0x01d4);
-	else
-		writel(0x00, phy_base + 0x01d4);
+	}
+	dmb();
 
 	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
 	writel(0x5f, phy_base + 0x0170);
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
index 4374601..0c9077b 100644
--- a/platform/msm_shared/qseecom_lk.c
+++ b/platform/msm_shared/qseecom_lk.c
@@ -1346,6 +1346,8 @@
 		goto err;
 	}
 	memset(buf, 0, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+	/* Make sure the buffer given to TZ is flushed */
+	arch_clean_invalidate_cache_range((addr_t) buf, QSEE_LOG_BUF_SIZE);
 	logbuf_req.qsee_cmd_id = QSEE_REGISTER_LOG_BUF_COMMAND;
 	logbuf_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
 	logbuf_req.len = QSEE_LOG_BUF_SIZE;
diff --git a/platform/msm_shared/qusb2_phy.c b/platform/msm_shared/qusb2_phy.c
index dfa4776..fab6e09 100644
--- a/platform/msm_shared/qusb2_phy.c
+++ b/platform/msm_shared/qusb2_phy.c
@@ -46,6 +46,8 @@
 void qusb2_phy_reset(void)
 {
 	uint32_t val;
+	/* Default tune value */
+	uint8_t tune2 = 0xB3;
 
 	/* Block Reset */
 	val = readl(GCC_QUSB2_PHY_BCR) | BIT(0);
@@ -59,7 +61,18 @@
 	if (platform_is_msm8996())
 	{
 		writel(0xF8, QUSB2PHY_PORT_TUNE1);
-		writel(0x83, QUSB2PHY_PORT_TUNE2);
+		/* Upper nibble of tune2 register should be updated based on the fuse value.
+		 * Read the bits 21..24 from fuse and update the upper nibble with this value
+		 */
+#if QFPROM_CORR_CALIB_ROW12_MSB
+		uint8_t fuse_val = (readl(QFPROM_CORR_CALIB_ROW12_MSB) & 0x1E00000) >> 21;
+		/* If fuse value is non zero then update the upper nibble with the fuse value
+		 * otherwise use the default value
+		 */
+		if (fuse_val)
+			tune2 = (tune2 & 0x0f) | (fuse_val << 4);
+#endif
+		writel(tune2, QUSB2PHY_PORT_TUNE2);
 		writel(0x93, QUSB2PHY_PORT_TUNE3);
 		writel(0xC0, QUSB2PHY_PORT_TUNE4);
 		writel(0x30, QUSB2PHY_PLL_TUNE);
diff --git a/platform/msm_shared/reboot.c b/platform/msm_shared/reboot.c
index 2fe514e..8f53633 100644
--- a/platform/msm_shared/reboot.c
+++ b/platform/msm_shared/reboot.c
@@ -69,14 +69,12 @@
 unsigned check_hard_reboot_mode(void)
 {
 	uint8_t hard_restart_reason = 0;
-	uint8_t value = 0;
 
 	/* Read reboot reason and scrub it
 	 * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
 	 */
-	value = REG_READ(PON_SOFT_RB_SPARE);
-	hard_restart_reason = value >> 5;
-	REG_WRITE(PON_SOFT_RB_SPARE, value & 0x1f);
+	hard_restart_reason = REG_READ(PON_SOFT_RB_SPARE);
+	REG_WRITE(PON_SOFT_RB_SPARE, hard_restart_reason & 0x1f);
 
 	return hard_restart_reason;
 }
@@ -112,7 +110,7 @@
 
 #if USE_PON_REBOOT_REG
 	value = REG_READ(PON_SOFT_RB_SPARE);
-	value |= ((reboot_reason << 5) & 0xff);
+	value |= reboot_reason;
 	REG_WRITE(PON_SOFT_RB_SPARE, value);
 #else
 	writel(reboot_reason, RESTART_REASON_ADDR);
diff --git a/platform/msm_shared/reboot.h b/platform/msm_shared/reboot.h
index c87f9d8..e8f14a6 100644
--- a/platform/msm_shared/reboot.h
+++ b/platform/msm_shared/reboot.h
@@ -26,9 +26,23 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#ifndef __REBOOT_H__
+#define __REBOOT_H__
+#if USE_PON_REBOOT_REG
+#define RECOVERY_MODE     0x20
+#define FASTBOOT_MODE     0x40
+#define ALARM_BOOT        0x60
+#define DM_VERITY_ENFORCING 0x80
+#define DM_VERITY_LOGGING   0xA0
+#define DM_VERITY_KEYSCLEAR 0xC0
+#else
 #define FASTBOOT_MODE     0x77665500
 #define RECOVERY_MODE     0x77665502
 #define ALARM_BOOT        0x77665503
+#define DM_VERITY_LOGGING    0x77665508
+#define DM_VERITY_ENFORCING  0x77665509
+#define DM_VERITY_KEYSCLEAR  0x7766550A
+#endif
 
 #define RTC_TRG           4
 #define PON_SOFT_RB_SPARE 0x88F
@@ -46,3 +60,5 @@
 
 void reboot_device(unsigned reboot_reason);
 void shutdown_device();
+
+#endif
diff --git a/platform/msm_shared/rpm-glink.c b/platform/msm_shared/rpm-glink.c
index 406f2ea..2635cd1 100644
--- a/platform/msm_shared/rpm-glink.c
+++ b/platform/msm_shared/rpm-glink.c
@@ -137,8 +137,6 @@
 	}
 	resp = (rpm_ack_msg *)rx_buffer;
 
-	arch_invalidate_cache_range((addr_t)resp, sizeof(rpm_gen_hdr));
-
 	if(resp->hdr.type == RPM_CMD_MAGIC)
 	{
 		type = RPM_CMD_TYPE;
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
index f6cb3e3..8ddfbd3 100644
--- a/platform/msm_shared/rpmb/rpmb.c
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -32,8 +32,8 @@
 #include <boot_device.h>
 #include <debug.h>
 #include <target.h>
+#include <secapp_loader.h>
 
-static bool lksec_app_loaded;
 
 static void *dev;
 static int app_handle;
@@ -76,6 +76,7 @@
 		}
 		info.dev_type  = EMMC_RPMB;
 	}
+#ifdef UFS_SUPPORT
 	else
 	{
 		struct ufs_dev *ufs_dev = (struct ufs_dev *) dev;
@@ -84,15 +85,7 @@
 		info.rel_wr_count = ufs_dev->rpmb_rw_size;
 		info.dev_type  = UFS_RPMB;
 	}
-
-	/* Initialize Qseecom */
-	ret = qseecom_init();
-
-	if (ret < 0)
-	{
-		dprintf(CRITICAL, "Failed to initialize qseecom, error: %d\n", ret);
-		goto err;
-	}
+#endif
 
 	/* Register & start the listener */
 	ret = rpmb_listener_start();
@@ -101,15 +94,7 @@
 		dprintf(CRITICAL, "Error registering the handler\n");
 		goto err;
 	}
-
-	/* Start Qseecom */
-	ret = qseecom_tz_init();
-
-	if (ret < 0)
-	{
-		dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
-		goto err;
-	}
+	rpmb_get_app_handle();
 
 err:
 	return ret;
@@ -122,18 +107,26 @@
 
 int rpmb_read(uint32_t *req, uint32_t req_len, uint32_t *resp, uint32_t *resp_len)
 {
+	int ret = 0;
 	if (platform_boot_dev_isemmc())
-		return rpmb_read_emmc(dev, req, req_len, resp, resp_len);
+		ret = rpmb_read_emmc(dev, req, req_len, resp, resp_len);
+#ifdef UFS_SUPPORT
 	else
-		return rpmb_read_ufs(dev, req, req_len, resp, resp_len);
+		ret = rpmb_read_ufs(dev, req, req_len, resp, resp_len);
+#endif
+	return ret;
 }
 
 int rpmb_write(uint32_t *req, uint32_t req_len, uint32_t rel_wr_count, uint32_t *resp, uint32_t *resp_len)
 {
+	int ret = 0;
 	if (platform_boot_dev_isemmc())
-		return rpmb_write_emmc(dev, req, req_len, rel_wr_count, resp, resp_len);
+		ret = rpmb_write_emmc(dev, req, req_len, rel_wr_count, resp, resp_len);
+#ifdef UFS_SUPPORT
 	else
-		return rpmb_write_ufs(dev, req, req_len, rel_wr_count, resp, resp_len);
+		ret = rpmb_write_ufs(dev, req, req_len, rel_wr_count, resp, resp_len);
+#endif
+	return ret;
 }
 
 /* This API calls into TZ app to read device_info */
@@ -143,20 +136,7 @@
 	struct send_cmd_req read_req = {0};
 	struct send_cmd_rsp read_rsp = {0};
 
-	/*
-	 * Load the sec app for first time
-	 */
-	if (!lksec_app_loaded)
-	{
-		if (load_sec_app() < 0)
-		{
-			dprintf(CRITICAL, "Failed to load App for rpmb\n");
-			ASSERT(0);
-		}
-		lksec_app_loaded = true;
-	}
-
-	read_req.cmd_id = CLIENT_CMD_READ_LK_DEVICE_STATE;
+	read_req.cmd_id = KEYMASTER_READ_LK_DEVICE_STATE;
 	read_req.data   = (uint32_t) info;
 	read_req.len    = sz;
 
@@ -181,7 +161,7 @@
 	struct send_cmd_req write_req = {0};
 	struct send_cmd_rsp write_rsp = {0};
 
-	write_req.cmd_id = CLIENT_CMD_WRITE_LK_DEVICE_STATE;
+	write_req.cmd_id = KEYMASTER_WRITE_LK_DEVICE_STATE;
 	write_req.data   = (uint32_t) info;
 	write_req.len    = sz;
 
@@ -201,6 +181,7 @@
 
 int rpmb_get_app_handle()
 {
+	app_handle = get_secapp_handle();
 	return app_handle;
 }
 
@@ -225,50 +206,4 @@
 	return ret;
 }
 
-int load_sec_app()
-{
-	/* start TZ app */
-	app_handle = qseecom_start_app("lksecapp");
 
-	if (app_handle < 0)
-	{
-		dprintf(CRITICAL, "Failure to load TZ app: lksecapp, error: %d\n", app_handle);
-		return app_handle;
-	}
-
-	return 0;
-}
-
-int unload_sec_app()
-{
-	int ret = 0;
-
-	struct send_cmd_req req = {0};
-	struct send_cmd_rsp rsp = {0};
-
-	req.cmd_id = CLIENT_CMD_LK_END_MILESTONE;
-	rsp.cmd_id = CLIENT_CMD_LK_END_MILESTONE;
-
-	/* Milestone end command */
-	ret = qseecom_send_command(app_handle, (void *)&req, sizeof(req), (void *)&rsp, sizeof(rsp));
-
-	if (ret < 0 || rsp.status < 0)
-	{
-		dprintf(CRITICAL, "Failed to send milestone end command: Error: %x\n", rsp.status);
-		return ret;
-	}
-
-	if (qseecom_shutdown_app(app_handle) < 0)
-	{
-		dprintf(CRITICAL, "Failed to Shutdown sec app\n");
-		ASSERT(0);
-	}
-
-
-	return 0;
-}
-
-bool is_sec_app_loaded()
-{
-	return lksec_app_loaded;
-}
diff --git a/platform/msm_shared/rpmb/rules.mk b/platform/msm_shared/rpmb/rules.mk
index 0e76433..da7b90e 100644
--- a/platform/msm_shared/rpmb/rules.mk
+++ b/platform/msm_shared/rpmb/rules.mk
@@ -4,5 +4,7 @@
 
 OBJS += $(LOCAL_DIR)/rpmb.o \
 		$(LOCAL_DIR)/rpmb_listener.o \
-		$(LOCAL_DIR)/rpmb_emmc.o \
-		$(LOCAL_DIR)/rpmb_ufs.o
+		$(LOCAL_DIR)/rpmb_emmc.o
+ifeq ($(ENABLE_UFS_SUPPORT), 1)
+	OBJS += $(LOCAL_DIR)/rpmb_ufs.o
+endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 944384e..ab0d5a6 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -23,6 +23,10 @@
 	$(LOCAL_DIR)/wdog.o
 endif
 
+ifeq ($(ENABLE_SECAPP_LOADER), 1)
+OBJS += $(LOCAL_DIR)/secapp_loader.o
+endif
+
 ifeq ($(ENABLE_QGIC3), 1)
 OBJS += $(LOCAL_DIR)/qgic_v3.o
 endif
@@ -50,6 +54,12 @@
 	$(LOCAL_DIR)/boot_verifier.o
 endif
 
+ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
+OBJS += \
+	$(LOCAL_DIR)/menu_keys_detect.o \
+	$(LOCAL_DIR)/display_menu.o
+endif
+
 ifeq ($(ENABLE_GLINK_SUPPORT),1)
 OBJS += \
 		$(LOCAL_DIR)/rpm-ipc.o \
@@ -466,6 +476,7 @@
 			$(LOCAL_DIR)/crypto5_eng.o \
 			$(LOCAL_DIR)/crypto5_wrapper.o \
 			$(LOCAL_DIR)/qusb2_phy.o \
+			$(LOCAL_DIR)/qseecom_lk.o \
 			$(LOCAL_DIR)/mdp5.o \
 			$(LOCAL_DIR)/display.o \
 			$(LOCAL_DIR)/mipi_dsi.o \
@@ -473,7 +484,8 @@
 			$(LOCAL_DIR)/mipi_dsi_autopll.o \
 			$(LOCAL_DIR)/mipi_dsi_autopll_20nm.o \
 			$(LOCAL_DIR)/mdss_hdmi.o \
-			$(LOCAL_DIR)/hdmi_pll_20nm.o
+			$(LOCAL_DIR)/hdmi_pll_20nm.o \
+			$(LOCAL_DIR)/dload_util.o
 endif
 
 ifeq ($(PLATFORM),msm8909)
@@ -584,6 +596,7 @@
 			$(LOCAL_DIR)/bam.o \
 			$(LOCAL_DIR)/qpic_nand.o \
 			$(LOCAL_DIR)/scm.o \
+			$(LOCAL_DIR)/qseecom_lk.o \
 			$(LOCAL_DIR)/dev_tree.o \
 			$(LOCAL_DIR)/gpio.o \
 			$(LOCAL_DIR)/dload_util.o \
@@ -596,6 +609,7 @@
 			$(LOCAL_DIR)/mdp5.o \
 			$(LOCAL_DIR)/display.o \
 			$(LOCAL_DIR)/mipi_dsi.o \
+			$(LOCAL_DIR)/mipi_dsc.o \
 			$(LOCAL_DIR)/mipi_dsi_phy.o \
 			$(LOCAL_DIR)/mipi_dsi_autopll.o
 endif
@@ -617,7 +631,6 @@
 	OBJS += $(LOCAL_DIR)/partial_goods.o
 endif
 
-
 ifeq ($(ENABLE_REBOOT_MODULE), 1)
 	OBJS += $(LOCAL_DIR)/reboot.o
 endif
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 2dda14e..df4b136 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -1202,7 +1202,7 @@
 		{
 			indir_arg[i] = arg->x5[i];
 		}
-		arch_clean_invalidate_cache_range((addr_t) indir_arg, ROUNDUP((SCM_INDIR_MAX_LEN * sizeof(uint32_t)), CACHE_LINE));
+		arch_clean_invalidate_cache_range((addr_t) indir_arg, (SCM_INDIR_MAX_LEN * sizeof(uint32_t)));
 		x5 = (addr_t) indir_arg;
 	}
 
diff --git a/platform/msm_shared/secapp_loader.c b/platform/msm_shared/secapp_loader.c
new file mode 100644
index 0000000..ad9cffd
--- /dev/null
+++ b/platform/msm_shared/secapp_loader.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 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
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <secapp_loader.h>
+#include <qseecom_lk_api.h>
+
+static bool lksec_app_loaded;
+static int app_handle;
+
+int load_sec_app()
+{
+	/* start TZ app */
+	app_handle = qseecom_start_app("keymaster");
+
+	if (app_handle <= 0)
+	{
+		dprintf(CRITICAL, "Failure to load TZ app: lksecapp, error: %d\n", app_handle);
+		return -1;
+	}
+	lksec_app_loaded = true;
+	return 0;
+}
+
+int get_secapp_handle()
+{
+	dprintf(INFO, "LK SEC APP Handle: 0x%x\n", app_handle);
+	return app_handle;
+}
+
+int send_delete_keys_to_tz()
+{
+	int ret = 0;
+	key_op_delete_all_req_t req = {0};
+	key_op_delete_all_rsp_t rsp = {0};
+	req.cmd_id = KEYMASTER_DELETE_ALL_KEYS;
+
+	// send delete all keys command
+	ret = qseecom_send_command(app_handle, (void *)&req, sizeof(req), (void *)&rsp, sizeof(rsp));
+
+	if (ret < 0 || rsp.status < 0)
+	{
+		dprintf(CRITICAL, "Failed to send delete keys command: Error: %x\n", rsp.status);
+		return -1;
+	}
+
+	return 0;
+}
+
+int send_milestone_call_to_tz()
+{
+	int ret = 0;
+
+	km_set_milestone_req_t req = {0};
+	km_set_milestone_rsp_t rsp = {0};
+
+	req.cmd_id = KEYMASTER_MILESTONE_CALL;
+
+	/* Milestone end command */
+	ret = qseecom_send_command(app_handle, (void *)&req, sizeof(req), (void *)&rsp, sizeof(rsp));
+
+	if (ret < 0 || rsp.status < 0)
+	{
+		dprintf(CRITICAL, "Failed to send milestone end command: Error: %x\n", rsp.status);
+		return -1;
+	}
+
+	return 0;
+}
+
+bool is_sec_app_loaded()
+{
+	return lksec_app_loaded;
+}
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
index a1ab6f3..aaf17a8 100644
--- a/platform/msm_shared/ucs.c
+++ b/platform/msm_shared/ucs.c
@@ -429,7 +429,7 @@
 
 	/* Flush cdb to memory. */
 	dsb();
-	arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+	arch_clean_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
 
 	memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
 
@@ -479,7 +479,7 @@
 
 	/* Flush cdb to memory. */
 	dsb();
-	arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+	arch_clean_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
 
 	memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
 
diff --git a/project/msm8952.mk b/project/msm8952.mk
index 23bff86..6a06c96 100644
--- a/project/msm8952.mk
+++ b/project/msm8952.mk
@@ -13,6 +13,8 @@
 endif
 
 EMMC_BOOT := 1
+ENABLE_SECAPP_LOADER := 1
+ENABLE_RPMB_SUPPORT := 1
 
 ENABLE_SMD_SUPPORT := 1
 #ENABLE_PWM_SUPPORT := true
@@ -31,6 +33,7 @@
 
 #Enable the feature of long press power on
 DEFINES += LONG_PRESS_POWER_ON=1
+DEFINES += USE_RPMB_FOR_DEVINFO=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
@@ -41,6 +44,13 @@
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
 
+#enable fbcon display menu
+ENABLE_FBCON_DISPLAY_MSG := 1
+
+ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
+DEFINES += FBCON_DISPLAY_MSG=1
+endif
+
 #enable power on vibrator feature
 ENABLE_HAP_VIB_SUPPORT := true
 
@@ -64,7 +74,7 @@
 
 ifeq ($(ENABLE_MDTP_SUPPORT),1)
 DEFINES += MDTP_SUPPORT=1
-DEFINES += MDTP_EFUSE_ADDRESS=0x0C858250 # QFPROM_RAW_QC_SPARE_REG_LSB_ADDR
+DEFINES += MDTP_EFUSE_ADDRESS=0x0005C250 # QFPROM_CORR_QC_SPARE_REG_LSB_ADDR
 DEFINES += MDTP_EFUSE_START=0
 endif
 
diff --git a/project/msm8994.mk b/project/msm8994.mk
index b6a4539..8016203 100644
--- a/project/msm8994.mk
+++ b/project/msm8994.mk
@@ -15,12 +15,14 @@
 
 EMMC_BOOT := 1
 ENABLE_SDHCI_SUPPORT := 1
+ENABLE_SECAPP_LOADER := 1
 ENABLE_UFS_SUPPORT   := 1
 ENABLE_BOOT_CONFIG_SUPPORT := 1
 ENABLE_USB30_SUPPORT := 1
 USE_DYNAMIC_SMEM := 1
 ENABLE_SMD_SUPPORT := 1
 ENABLE_PWM_SUPPORT := true
+ENABLE_RPMB_SUPPORT := 1
 
 #DEFINES += WITH_DEBUG_DCC=1
 DEFINES += WITH_DEBUG_UART=1
@@ -35,6 +37,7 @@
 
 DEFINES += ENABLE_XPU_VIOLATION=1
 DEFINES += USE_BOOTDEV_CMDLINE=1
+DEFINES += USE_RPMB_FOR_DEVINFO=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
@@ -47,6 +50,13 @@
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
 
+#enable fbcon display menu
+ENABLE_FBCON_DISPLAY_MSG := 1
+
+ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
+DEFINES += FBCON_DISPLAY_MSG=1
+endif
+
 ifeq ($(ENABLE_UFS_SUPPORT),1)
 DEFINES += UFS_SUPPORT=1
 endif
diff --git a/project/msm8996.mk b/project/msm8996.mk
index cc5d818..2dccd59 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -19,6 +19,7 @@
 ENABLE_BOOT_CONFIG_SUPPORT := 1
 ENABLE_USB30_SUPPORT := 1
 ENABLE_QGIC3 := 1
+ENABLE_SECAPP_LOADER := 1
 ENABLE_PARTIAL_GOODS_SUPPORT := 1
 ENABLE_RPMB_SUPPORT := 1
 ENABLE_GLINK_SUPPORT := 1
@@ -44,6 +45,14 @@
 #Disable thumb mode
 ENABLE_THUMB := false
 
+#enable fbcon display menu
+ENABLE_FBCON_DISPLAY_MSG := 0
+
+ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
+DEFINES += FBCON_DISPLAY_MSG=1
+endif
+
+
 ifeq ($(ENABLE_GLINK_SUPPORT),1)
 DEFINES += GLINK_SUPPORT=1
 endif
@@ -87,3 +96,7 @@
 
 #Enable the external reboot functions
 ENABLE_REBOOT_MODULE := 1
+#fuse for Qusb tun2 config
+DEFINES += QFPROM_CORR_CALIB_ROW12_MSB=0x0007424C
+#Use PON register for reboot reason
+DEFINES += USE_PON_REBOOT_REG=1
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index 543951e..de4ef9f 100755
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -134,21 +134,27 @@
 }
 
 /* Return 1 if vol_up pressed */
-static int target_volume_up()
+int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 	struct pm8x41_gpio gpio;
 
-	/* Configure the GPIO */
-	gpio.direction = PM_GPIO_DIR_IN;
-	gpio.function  = 0;
-	gpio.pull      = PM_GPIO_PULL_UP_30;
-	gpio.vin_sel   = 2;
+	if (!first_time) {
+		/* Configure the GPIO */
+		gpio.direction = PM_GPIO_DIR_IN;
+		gpio.function  = 0;
+		gpio.pull      = PM_GPIO_PULL_UP_30;
+		gpio.vin_sel   = 2;
 
-	pm8x41_gpio_config(2, &gpio);
+		pm8x41_gpio_config(2, &gpio);
 
-	/* Wait for the pmic gpio config to take effect */
-	thread_sleep(1);
+		/* Wait for the pmic gpio config to take effect */
+		udelay(10000);
+
+		first_time = 1;
+
+	}
 
 	/* Get status of P_GPIO_2 */
 	pm8x41_gpio_get(2, &status);
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index b115bf8..5db6e08 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -205,14 +205,19 @@
 }
 
 /* Return 1 if vol_up pressed */
-static int target_volume_up()
+int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 
-	gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+	if (!first_time) {
+		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
 
-	/* Wait for the gpio config to take effect - debounce time */
-	thread_sleep(10);
+		/* Wait for the gpio config to take effect - debounce time */
+		udelay(10000);
+
+		first_time = 1;
+	}
 
 	/* Get status of GPIO */
 	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index dba1ed3..7502bc5 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -132,14 +132,19 @@
 }
 
 /* Return 1 if vol_up pressed */
-static int target_volume_up()
+int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 
-	gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+	if (!first_time) {
+		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
 
-	/* Wait for the gpio config to take effect - debounce time */
-	thread_sleep(10);
+		/* Wait for the gpio config to take effect - debounce time */
+		udelay(10000);
+
+		first_time = 1;
+	}
 
 	/* Get status of GPIO */
 	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index 41ff356..7e313ee 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -54,6 +54,9 @@
 #include <spmi.h>
 #include <sdhci_msm.h>
 #include <clock.h>
+#include <boot_device.h>
+#include <secapp_loader.h>
+#include <rpmb.h>
 
 #include "target/display.h"
 
@@ -174,6 +177,7 @@
 /* Return 1 if vol_up pressed */
 int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 	uint32_t vol_up_gpio;
 
@@ -183,10 +187,14 @@
 	else
 		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO;
 
-	gpio_tlmm_config(vol_up_gpio, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+	if (!first_time) {
+		gpio_tlmm_config(vol_up_gpio, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
 
-	/* Wait for the gpio config to take effect - debounce time */
-	thread_sleep(10);
+		/* Wait for the gpio config to take effect - debounce time */
+		udelay(10000);
+
+		first_time = 1;
+	}
 
 	/* Get status of GPIO */
 	status = gpio_status(vol_up_gpio);
@@ -243,6 +251,7 @@
 
 void target_init(void)
 {
+	int ret = 0;
 	dprintf(INFO, "target_init()\n");
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
@@ -268,6 +277,41 @@
 	if (target_use_signed_kernel())
 		target_crypto_init_params();
 
+	clock_ce_enable(CE1_INSTANCE);
+
+	/* Initialize Qseecom */
+	ret = qseecom_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to initialize qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Start Qseecom */
+	ret = qseecom_tz_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/*
+	 * Load the sec app for first time
+	 */
+	if (load_sec_app() < 0)
+	{
+		dprintf(CRITICAL, "Failed to load App for verified\n");
+		ASSERT(0);
+	}
+
+	if (rpmb_init() < 0)
+	{
+		dprintf(CRITICAL, "RPMB init failed\n");
+		ASSERT(0);
+	}
+
 #if SMD_SUPPORT
 	rpm_smd_init();
 #endif
@@ -449,6 +493,23 @@
 	if (target_is_ssd_enabled())
 		clock_ce_disable(CE1_INSTANCE);
 
+
+	if (is_sec_app_loaded())
+	{
+		if (send_milestone_call_to_tz() < 0)
+		{
+			dprintf(CRITICAL, "Failed to unload App for rpmb\n");
+			ASSERT(0);
+		}
+	}
+
+	if (rpmb_uninit() < 0)
+	{
+		dprintf(CRITICAL, "RPMB uninit failed\n");
+		ASSERT(0);
+	}
+
+	clock_ce_disable(CE1_INSTANCE);
 #if SMD_SUPPORT
 	rpm_smd_uninit();
 #endif
diff --git a/target/msm8952/mdtp_ui_defs.c b/target/msm8952/mdtp_ui_defs.c
new file mode 100644
index 0000000..7091f15
--- /dev/null
+++ b/target/msm8952/mdtp_ui_defs.c
@@ -0,0 +1,67 @@
+/* Copyright (c) 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
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "mdtp_ui_defs.h"
+
+struct mdtp_ui_defs mdtp_ui_defs_msm8952 = {
+        // Image dimensions
+        952,      // error_msg_width;
+        143,      // error_msg_height;
+        920,      // main_text_width;
+        194,      // main_text_height;
+        120,      // pin_digit_width;
+        120,      // pin_digit_height;
+        432,      // ok_button_width;
+        106,      // ok_button_height;
+        932,      // digits_instructions_width;
+        112,      // digits_instructions_height;
+        620,      // pin_instructions_width;
+        137,      // pin_instructions_height;
+
+        // Image offsets
+        0x1000,   // error_msg_offset;
+        0x65000,  // initial_delay_offset;
+        0xE8000,  // enter_pin_offset;
+        0x16B000, // invalid_pin_offset;
+        0x1EE000, // pin_digit_0_offset;
+        0xB000,   // pin_digits_offset;
+        0x25C000, // pin_selected_digit_0_offset;
+        0x2CA000, // ok_button_offset;
+        0x2EC000, // selected_ok_button_offset;
+        0x30E000, // digits_instructions_offset;
+        0x35B000, // pin_instructions_offset;
+
+        //Display settings
+        8         // digit_space;
+};
+
+struct mdtp_ui_defs mdtp_get_target_ui_defs()
+{
+    return mdtp_ui_defs_msm8952;
+}
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index d2e05f8..57e069f 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -35,6 +35,7 @@
 #include <board.h>
 #include <qtimer.h>
 #include <mipi_dsi.h>
+#include <mdp5.h>
 #include <target/display.h>
 
 #include "include/panel.h"
@@ -50,6 +51,8 @@
 #include "include/panel_nt35597_wqxga_dualdsi_video.h"
 #include "include/panel_nt35597_wqxga_dualdsi_cmd.h"
 #include "include/panel_hx8399a_1080p_video.h"
+#include "include/panel_nt35597_wqxga_dsc_video.h"
+#include "include/panel_nt35597_wqxga_dsc_cmd.h"
 
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
@@ -62,6 +65,8 @@
 	NT35597_WQXGA_DUALDSI_VIDEO_PANEL,
 	NT35597_WQXGA_DUALDSI_CMD_PANEL,
 	HX8399A_1080P_VIDEO_PANEL,
+	NT35597_WQXGA_DSC_VIDEO_PANEL,
+	NT35597_WQXGA_DSC_CMD_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -81,6 +86,8 @@
 	{"nt35597_wqxga_dualdsi_cmd", NT35597_WQXGA_DUALDSI_CMD_PANEL},
 	{"otm1906c_1080p_cmd", OTM1906C_1080P_CMD_PANEL},
 	{"hx8399a_1080p_video", HX8399A_1080P_VIDEO_PANEL},
+	{"nt35597_wqxga_dsc_video", NT35597_WQXGA_DSC_VIDEO_PANEL},
+	{"nt35597_wqxga_dsc_cmd", NT35597_WQXGA_DSC_CMD_PANEL},
 };
 
 static uint32_t panel_id;
@@ -318,6 +325,84 @@
 			TIMING_SIZE);
 		pinfo->mipi.tx_eot_append = true;
 		break;
+	case NT35597_WQXGA_DSC_VIDEO_PANEL:
+		panelstruct->paneldata    = &nt35597_wqxga_dsc_video_panel_data;
+		panelstruct->paneldata->panel_with_enable_gpio = 0;
+		panelstruct->paneldata->panel_operating_mode = USE_DSI1_PLL_FLAG;
+		panelstruct->panelres     = &nt35597_wqxga_dsc_video_panel_res;
+		panelstruct->color        = &nt35597_wqxga_dsc_video_color;
+		panelstruct->videopanel   = &nt35597_wqxga_dsc_video_video_panel;
+		panelstruct->commandpanel = &nt35597_wqxga_dsc_video_command_panel;
+		panelstruct->state        = &nt35597_wqxga_dsc_video_state;
+		panelstruct->laneconfig   = &nt35597_wqxga_dsc_video_lane_config;
+		panelstruct->paneltiminginfo
+					= &nt35597_wqxga_dsc_video_timing_info;
+		panelstruct->panelresetseq
+					= &nt35597_wqxga_dsc_video_reset_seq;
+		panelstruct->backlightinfo = &nt35597_wqxga_dsc_video_backlight;
+		pinfo->labibb = &nt35597_wqxga_dsc_video_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= nt35597_wqxga_dsc_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= NT35597_WQXGA_DSC_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= nt35597_wqxga_dsc_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= NT35597_WQXGA_DSC_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing, nt35597_wqxga_dsc_video_timings,
+			TIMING_SIZE);
+		/* Clkout timings are different for this panel on 8956 */
+		panelstruct->paneltiminginfo->tclk_post = 0x04;
+		panelstruct->paneltiminginfo->tclk_pre = 0x20;
+		pinfo->mipi.tx_eot_append = true;
+		pinfo->compression_mode = COMPRESSION_DSC;
+		memcpy(&panelstruct->dsc_paras, &nt35597_wqxga_dsc_video_paras,
+				sizeof(struct dsc_parameters));
+		pinfo->dsc.parameter_calc =  mdss_dsc_parameters_calc;
+		pinfo->dsc.dsc2buf = mdss_dsc_to_buf;
+		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
+		pinfo->dsc.mdp_dsc_config = mdss_dsc_mdp_config;
+		break;
+	case NT35597_WQXGA_DSC_CMD_PANEL:
+		panelstruct->paneldata    = &nt35597_wqxga_dsc_cmd_panel_data;
+		panelstruct->paneldata->panel_with_enable_gpio = 0;
+		panelstruct->paneldata->panel_operating_mode = USE_DSI1_PLL_FLAG;
+		panelstruct->panelres     = &nt35597_wqxga_dsc_cmd_panel_res;
+		panelstruct->color        = &nt35597_wqxga_dsc_cmd_color;
+		panelstruct->videopanel   = &nt35597_wqxga_dsc_cmd_video_panel;
+		panelstruct->commandpanel = &nt35597_wqxga_dsc_cmd_command_panel;
+		panelstruct->state        = &nt35597_wqxga_dsc_cmd_state;
+		panelstruct->laneconfig   = &nt35597_wqxga_dsc_cmd_lane_config;
+		panelstruct->paneltiminginfo
+					= &nt35597_wqxga_dsc_cmd_timing_info;
+		panelstruct->panelresetseq
+					= &nt35597_wqxga_dsc_cmd_reset_seq;
+		panelstruct->backlightinfo = &nt35597_wqxga_dsc_cmd_backlight;
+		pinfo->labibb = &nt35597_wqxga_dsc_cmd_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= nt35597_wqxga_dsc_cmd_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= NT35597_WQXGA_DSC_CMD_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= nt35597_wqxga_dsc_cmd_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= NT35597_WQXGA_DSC_CMD_OFF_COMMAND;
+		memcpy(phy_db->timing, nt35597_wqxga_dsc_cmd_timings,
+			TIMING_SIZE);
+		/* Clkout timings are different for this panel on 8956 */
+		panelstruct->paneltiminginfo->tclk_post = 0x04;
+		panelstruct->paneltiminginfo->tclk_pre = 0x20;
+		pinfo->mipi.tx_eot_append = true;
+		pinfo->compression_mode = COMPRESSION_DSC;
+		memcpy(&panelstruct->dsc_paras, &nt35597_wqxga_dsc_cmd_paras,
+				sizeof(struct dsc_parameters));
+		pinfo->dsc.parameter_calc =  mdss_dsc_parameters_calc;
+		pinfo->dsc.dsc2buf = mdss_dsc_to_buf;
+		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
+		pinfo->dsc.mdp_dsc_config = mdss_dsc_mdp_config;
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
diff --git a/target/msm8952/rules.mk b/target/msm8952/rules.mk
index c488c21..fd3a56e 100644
--- a/target/msm8952/rules.mk
+++ b/target/msm8952/rules.mk
@@ -2,6 +2,9 @@
 
 INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
 INCLUDES += -I$(LK_TOP_DIR)/dev/gcdb/display -I$(LK_TOP_DIR)/dev/gcdb/display/include
+ifeq ($(ENABLE_MDTP_SUPPORT),1)
+INCLUDES += -I$(LK_TOP_DIR)/app/aboot
+endif
 
 PLATFORM := msm8952
 
@@ -9,7 +12,7 @@
 MEMSIZE := 0x00300000 # 3MB
 
 BASE_ADDR        := 0x80000000
-SCRATCH_ADDR     := 0x90000000
+SCRATCH_ADDR     := 0x90100000
 
 DEFINES += DISPLAY_SPLASH_SCREEN=1
 DEFINES += DISPLAY_TYPE_MIPI=1
@@ -43,3 +46,7 @@
 OBJS += \
 	$(LOCAL_DIR)/regulator.o
 endif
+ifeq ($(ENABLE_MDTP_SUPPORT),1)
+OBJS += \
+	$(LOCAL_DIR)/mdtp_ui_defs.o
+endif
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index abe8937..f4664ec 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -55,8 +55,8 @@
 #define DSC_VID_PANEL "dsc_vid_panel"
 #define DSC_VID_PANEL_ADV7533_1080P "dsc_vid_panel_adv7533_1080p"
 #define DSC_CMD_PANEL_ADV7533_1080P "dsc_cmd_panel_adv7533_1080p"
-#define DSC_CMD_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_nt35597_dsc_wqxga_cmd"
-#define DSC_VID_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_nt35597_dsc_wqxga_video"
+#define DSC_CMD_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_nt35597_dsc_wqxga_cmd:cfg:single_dsi"
+#define DSC_VID_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_nt35597_dsc_wqxga_video:cfg:single_dsi"
 #define DSC_CMD_PANEL_ADV7533_1080P_STRING "1:dsi:0:qcom,mdss_dsi_adv7533_1080p:1:qcom,mdss_dsi_nt35597_dsc_wqxga_cmd:cfg:dual_dsi"
 #define DSC_VID_PANEL_ADV7533_1080P_STRING "1:dsi:0:qcom,mdss_dsi_adv7533_1080p:1:qcom,mdss_dsi_nt35597_dsc_wqxga_video:cfg:dual_dsi"
 
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index a7e0ca8..35b17bd 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -115,8 +115,9 @@
 }
 
 /* Return 1 if vol_up pressed */
-static int target_volume_up()
+int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 	struct pm8x41_gpio gpio;
 
@@ -127,16 +128,20 @@
 	if (board_hardware_id() == HW_PLATFORM_SURF)
 		return 0;
 
-	/* Configure the GPIO */
-	gpio.direction = PM_GPIO_DIR_IN;
-	gpio.function  = 0;
-	gpio.pull      = PM_GPIO_PULL_UP_30;
-	gpio.vin_sel   = 2;
+	if (!first_time) {
+		/* Configure the GPIO */
+		gpio.direction = PM_GPIO_DIR_IN;
+		gpio.function  = 0;
+		gpio.pull      = PM_GPIO_PULL_UP_30;
+		gpio.vin_sel   = 2;
 
-	pm8x41_gpio_config(5, &gpio);
+		pm8x41_gpio_config(5, &gpio);
 
-	/* Wait for the pmic gpio config to take effect */
-	thread_sleep(1);
+		/* Wait for the pmic gpio config to take effect */
+		udelay(10000);
+
+		first_time = 1;
+	}
 
 	/* Get status of P_GPIO_5 */
 	pm8x41_gpio_get(5, &status);
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 824bdc1..e3b513f 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -60,6 +60,9 @@
 #include <sdhci_msm.h>
 #include <pm8x41_wled.h>
 #include <qpnp_led.h>
+#include <boot_device.h>
+#include <secapp_loader.h>
+#include <rpmb.h>
 
 #include "target/display.h"
 
@@ -107,19 +110,24 @@
 /* Return 1 if vol_up pressed */
 int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 	struct pm8x41_gpio gpio;
 
-	/* Configure the GPIO */
-	gpio.direction = PM_GPIO_DIR_IN;
-	gpio.function  = 0;
-	gpio.pull      = PM_GPIO_PULL_UP_30;
-	gpio.vin_sel   = 2;
+	if (!first_time) {
+		/* Configure the GPIO */
+		gpio.direction = PM_GPIO_DIR_IN;
+		gpio.function  = 0;
+		gpio.pull      = PM_GPIO_PULL_UP_30;
+		gpio.vin_sel   = 2;
 
-	pm8x41_gpio_config(3, &gpio);
+		pm8x41_gpio_config(3, &gpio);
 
-	/* Wait for the pmic gpio config to take effect */
-	thread_sleep(1);
+		/* Wait for the pmic gpio config to take effect */
+		udelay(10000);
+
+		first_time = 1;
+	}
 
 	/* Get status of P_GPIO_5 */
 	pm8x41_gpio_get(3, &status);
@@ -159,6 +167,20 @@
 		clock_ce_disable(CE_INSTANCE);
 	}
 
+	if (is_sec_app_loaded())
+	{
+		if (send_milestone_call_to_tz() < 0)
+		{
+			dprintf(CRITICAL, "Failed to unload App for rpmb\n");
+			ASSERT(0);
+		}
+	}
+
+	if (rpmb_uninit() < 0)
+	{
+		dprintf(CRITICAL, "RPMB uninit failed\n");
+		ASSERT(0);
+	}
 	rpm_smd_uninit();
 }
 
@@ -310,6 +332,7 @@
 
 void target_init(void)
 {
+	int ret = 0;
 	dprintf(INFO, "target_init()\n");
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
@@ -338,6 +361,40 @@
 	/* Storage initialization is complete, read the partition table info */
 	mmc_read_partition_table(0);
 
+	/* Initialize Qseecom */
+	ret = qseecom_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to initialize qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Start Qseecom */
+	ret = qseecom_tz_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/*
+	 * Load the sec app for first time
+	 */
+	if (load_sec_app() < 0)
+	{
+		dprintf(CRITICAL, "Failed to load App for verified\n");
+		ASSERT(0);
+	}
+
+	if (rpmb_init() < 0)
+	{
+		dprintf(CRITICAL, "RPMB init failed\n");
+		ASSERT(0);
+	}
+
+
 	rpm_smd_init();
 
 	/* QPNP LED init for boot process notification */
@@ -456,7 +513,7 @@
 	/* Write the reboot reason */
 	writel(reboot_reason, restart_reason_addr);
 
-	if(reboot_reason == FASTBOOT_MODE)
+	if(reboot_reason == FASTBOOT_MODE || reboot_reason == DLOAD)
 		reset_type = PON_PSHOLD_WARM_RESET;
 	else
 		reset_type = PON_PSHOLD_HARD_RESET;
@@ -578,3 +635,15 @@
 {
 	return DDR_CFG_DLY_VAL;
 }
+
+int set_download_mode(enum dload_mode mode)
+{
+	if (platform_is_msm8994())
+		dload_util_write_cookie(mode == NORMAL_DLOAD ?
+			DLOAD_MODE_ADDR : EMERGENCY_DLOAD_MODE_ADDR, mode);
+	else
+		dload_util_write_cookie(mode == NORMAL_DLOAD ?
+			DLOAD_MODE_ADDR_V2 : EMERGENCY_DLOAD_MODE_ADDR_V2, mode);
+
+	return 0;
+}
diff --git a/target/msm8994/rules.mk b/target/msm8994/rules.mk
index 16fd384..677ce8d 100644
--- a/target/msm8994/rules.mk
+++ b/target/msm8994/rules.mk
@@ -6,11 +6,11 @@
 PLATFORM := msm8994
 
 MEMBASE := 0x0F900000 # SDRAM
-MEMSIZE := 0x00100000 # 1MB
+MEMSIZE := 0x00200000 # 2MB
 
 BASE_ADDR    := 0x0000000
 
-SCRATCH_ADDR := 0x10000000
+SCRATCH_ADDR := 0x10100000
 
 SCRATCH_SIZE := 0x20000000
 
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index e6cfeed..4d1fad1 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -18,7 +18,8 @@
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, nit
+ * PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
@@ -56,6 +57,7 @@
 #include <qmp_phy.h>
 #include <sdhci_msm.h>
 #include <qusb2_phy.h>
+#include <secapp_loader.h>
 #include <rpmb.h>
 #include <rpm-glink.h>
 #if ENABLE_WBC
@@ -63,7 +65,7 @@
 #endif
 
 #define CE_INSTANCE             1
-#define CE_EE                   1
+#define CE_EE                   0
 #define CE_FIFO_SIZE            64
 #define CE_READ_PIPE            3
 #define CE_WRITE_PIPE           2
@@ -97,19 +99,24 @@
 /* Return 1 if vol_up pressed */
 int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 	struct pm8x41_gpio gpio;
 
-	/* Configure the GPIO */
-	gpio.direction = PM_GPIO_DIR_IN;
-	gpio.function  = 0;
-	gpio.pull      = PM_GPIO_PULL_UP_30;
-	gpio.vin_sel   = 2;
+	if (!first_time) {
+		/* Configure the GPIO */
+		gpio.direction = PM_GPIO_DIR_IN;
+		gpio.function  = 0;
+		gpio.pull      = PM_GPIO_PULL_UP_30;
+		gpio.vin_sel   = 2;
 
-	pm8x41_gpio_config(2, &gpio);
+		pm8x41_gpio_config(2, &gpio);
 
-	/* Wait for the pmic gpio config to take effect */
-	thread_sleep(1);
+		/* Wait for the pmic gpio config to take effect */
+		udelay(10000);
+
+		first_time = 1;
+	}
 
 	/* Get status of P_GPIO_5 */
 	pm8x41_gpio_get(2, &status);
@@ -143,7 +150,7 @@
 
 	if (is_sec_app_loaded())
 	{
-		if (unload_sec_app() < 0)
+		if (send_milestone_call_to_tz() < 0)
 		{
 			dprintf(CRITICAL, "Failed to unload App for rpmb\n");
 			ASSERT(0);
@@ -155,6 +162,13 @@
 		pm_appsbl_set_dcin_suspend(1);
 #endif
 
+
+	if (crypto_initialized())
+	{
+		crypto_eng_cleanup();
+		clock_ce_disable(CE_INSTANCE);
+	}
+
 	/* Tear down glink channels */
 	rpm_glink_uninit();
 
@@ -239,6 +253,7 @@
 
 void target_init(void)
 {
+	int ret = 0;
 	dprintf(INFO, "target_init()\n");
 
 	pmic_info_populate();
@@ -282,6 +297,33 @@
 		pm_appsbl_chg_check_weak_battery_status(1);
 #endif
 
+	/* Initialize Qseecom */
+	ret = qseecom_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to initialize qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Start Qseecom */
+	ret = qseecom_tz_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/*
+	 * Load the sec app for first time
+	 */
+	if (load_sec_app() < 0)
+	{
+		dprintf(CRITICAL, "Failed to load App for verified\n");
+		ASSERT(0);
+	}
+
 	if (rpmb_init() < 0)
 	{
 		dprintf(CRITICAL, "RPMB init failed\n");
@@ -405,7 +447,7 @@
 
 crypto_engine_type board_ce_type(void)
 {
-	return CRYPTO_ENGINE_TYPE_SW;
+	return CRYPTO_ENGINE_TYPE_HW;
 }
 
 /* Set up params for h/w CE. */
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index d9349f7..2205f60 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -5,14 +5,13 @@
 
 PLATFORM := msm8996
 
-MEMBASE := 0x90B00000 # SDRAM
+MEMBASE := 0x91000000 # SDRAM
 MEMSIZE := 0x00400000 # 4MB
 
 BASE_ADDR    := 0x0000000
 
-SCRATCH_ADDR := 0x91100000
-SCRATCH_SIZE := 750
-KERNEL_SIZE  := 512
+SCRATCH_ADDR := 0x91600000
+SCRATCH_SIZE := 746
 # LPAE supports only 32 virtual address, L1 pt size is 4
 L1_PT_SZ     := 4
 L2_PT_SZ     := 3
@@ -36,7 +35,6 @@
 	MEMBASE=$(MEMBASE) \
 	BASE_ADDR=$(BASE_ADDR) \
 	TAGS_ADDR=$(TAGS_ADDR) \
-	KERNEL_SIZE=$(KERNEL_SIZE) \
 	RAMDISK_ADDR=$(RAMDISK_ADDR) \
 	SCRATCH_ADDR=$(SCRATCH_ADDR) \
 	SCRATCH_SIZE=$(SCRATCH_SIZE) \
diff --git a/target/msm8996/target_display.c b/target/msm8996/target_display.c
index 839e23e..ebede20 100644
--- a/target/msm8996/target_display.c
+++ b/target/msm8996/target_display.c
@@ -124,7 +124,6 @@
 static int thulium_wled_backlight_ctrl(uint8_t enable)
 {
 	qpnp_wled_enable_backlight(enable);
-	qpnp_ibb_enable(enable);
 	return NO_ERROR;
 }
 
@@ -243,8 +242,6 @@
 			pm_pwm_enable(false);
 			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
 		}
-		/* Need delay before power on regulators */
-		mdelay(20);
 		/* Enable WLED backlight control */
 		ret = thulium_wled_backlight_ctrl(enable);
 		break;
@@ -260,8 +257,6 @@
 		} else {
 			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
 		}
-		/* Need delay before power on regulators */
-		mdelay(20);
 		ret = thulium_pwm_backlight_ctrl(enable);
 		break;
 	default:
@@ -421,7 +416,7 @@
 		mdelay(10);
 		wled_init(pinfo);
 		qpnp_ibb_enable(true);	/* +5V and -5V */
-		mdelay(50);
+		mdelay(20);
 
 		if (pinfo->lcd_reg_en)
 			lcd_reg_enable();