Merge remote-tracking branch 'master' into m_master

* master:
  platform: msm_shared: fix the buffer out of bound access
  target: mdmfermium: fix for device serial number
  project: fsm9010: Disable scm armv8 calls
  target: msm8996: Add panel post on delay for DTP8996

Change-Id: I2e45d687b50c533fb58947b0e63d072b3d77b7be
diff --git a/AndroidBoot.mk b/AndroidBoot.mk
index 1b336e3..713863b 100644
--- a/AndroidBoot.mk
+++ b/AndroidBoot.mk
@@ -1,10 +1,14 @@
 #Android makefile to build lk bootloader as a part of Android Build
 
-ifndef 2ND_TARGET_GCC_VERSION
+ifeq ($(BOOTLOADER_GCC_VERSION),)
+ifndef $(2ND_TARGET_GCC_VERSION)
 CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/arm-eabi-$(TARGET_GCC_VERSION)/bin/arm-eabi-
 else
 CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/arm-eabi-$(2ND_TARGET_GCC_VERSION)/bin/arm-eabi-
 endif
+else # BOOTLOADER_GCC_VERSION defined
+CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/$(BOOTLOADER_GCC_VERSION)/bin/arm-eabi-
+endif
 
 # Set flags if we need to include security libs
 ifeq ($(TARGET_BOOTIMG_SIGNED),true)
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f741419..c25f3b3 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -59,6 +59,7 @@
 #include <image_verify.h>
 #include <decompress.h>
 #include <platform/timer.h>
+#include <sys/types.h>
 #if USE_RPMB_FOR_DEVINFO
 #include <rpmb.h>
 #endif
@@ -88,6 +89,9 @@
 #include "board.h"
 #include "scm.h"
 #include "mdtp.h"
+#include "secapp_loader.h"
+#include <menu_keys_detect.h>
+#include <display_menu.h>
 #include "fastboot_test.h"
 
 extern  bool target_use_signed_kernel(void);
@@ -127,7 +131,7 @@
 
 /* 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
@@ -162,6 +166,27 @@
 static const char *baseband_sglte2  = " androidboot.baseband=sglte2";
 static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+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
+#endif
+
 static unsigned page_size = 0;
 static unsigned page_mask = 0;
 static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
@@ -173,12 +198,29 @@
 
 /* Assuming unauthorized kernel image by default */
 static int auth_kernel_img = 0;
-
+#if VBOOT_MOTA
 static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}, {0},{0}};
+#else
+static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}, {0},{0}, 1};
+#endif
 static bool is_allow_unlock = 0;
 
 static char frp_ptns[2][8] = {"config","frp"};
 
+static const char *critical_flash_allowed_ptn[] = {
+	"aboot",
+	"rpm",
+	"tz",
+	"sbl",
+	"sdi",
+	"sbl1",
+	"xbl",
+	"hyp",
+	"pmic",
+	"bootloader",
+	"devinfo",
+	"partition"};
+
 struct atag_ptbl_entry
 {
 	char name[16];
@@ -216,6 +258,13 @@
 char display_panel_buf[MAX_PANEL_BUF_SIZE];
 char panel_display_mode[MAX_RSP_SIZE];
 
+#if CHECK_BAT_VOLTAGE
+char battery_voltage[MAX_RSP_SIZE];
+char battery_soc_ok [MAX_RSP_SIZE];
+#endif
+
+char get_variant[MAX_RSP_SIZE];
+
 extern int emmc_recovery_init(void);
 
 #if NO_KEYPAD_DRIVER
@@ -248,6 +297,14 @@
 	*ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
 }
 
+#if CHECK_BAT_VOLTAGE
+void update_battery_status(void)
+{
+	snprintf(battery_voltage,MAX_RSP_SIZE, "%d",target_get_battery_voltage());
+	snprintf(battery_soc_ok ,MAX_RSP_SIZE, "%s",target_battery_soc_ok()? "yes":"no");
+}
+#endif
+
 unsigned char *update_cmdline(const char * cmdline)
 {
 	int cmdline_len = 0;
@@ -259,6 +316,12 @@
 	int have_target_boot_params = 0;
 	char *boot_dev_buf = NULL;
     bool is_mdtp_activated = 0;
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+    uint32_t boot_state = boot_verify_get_state();
+#endif
+#endif
+
 #ifdef MDTP_SUPPORT
     mdtp_activated(&is_mdtp_activated);
 #endif /* MDTP_SUPPORT */
@@ -280,6 +343,18 @@
 	cmdline_len += strlen(usb_sn_cmdline);
 	cmdline_len += strlen(sn_buf);
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
+	if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
+	{
+		dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
+		ASSERT(0);
+	}
+	cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
+#endif
+#endif
+
 	if (boot_into_recovery && gpt_exists)
 		cmdline_len += strlen(secondary_gpt_enable);
 
@@ -394,6 +469,29 @@
 #endif
 		}
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+		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++));
+
+		if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
+		{
+			dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
+			ASSERT(0);
+		}
+		src = verity_mode;
+		if(have_cmdline) --dst;
+		while ((*dst++ = *src++));
+		src = vbvm[device.verity_mode].name;
+		if(have_cmdline) -- dst;
+		while ((*dst++ = *src++));
+#endif
+#endif
 		src = usb_sn_cmdline;
 		if (have_cmdline) --dst;
 		have_cmdline = 1;
@@ -789,24 +887,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_bootverify_menu_thread(DISPLAY_MENU_RED);
+			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_bootverify_menu_thread(DISPLAY_MENU_YELLOW);
+			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);
@@ -818,7 +926,7 @@
 		ASSERT(0);
 	#endif
 	}
-
+#endif
 }
 
 static bool check_format_bit()
@@ -1069,6 +1177,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_bootverify_menu_thread(DISPLAY_MENU_ORANGE);
+		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.
@@ -1087,6 +1209,13 @@
 #endif /* MDTP_SUPPORT */
 	}
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	// send root of trust
+	if(!send_rot_command((uint32_t)device.is_unlocked))
+		ASSERT(0);
+#endif
+#endif
 	/*
 	 * Check if the kernel image is a gzip package. If yes, need to decompress it.
 	 * If not, continue booting.
@@ -1780,12 +1909,22 @@
 		if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
 		{
 			memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
-			if (is_secure_boot_enable())
+			if (is_secure_boot_enable()) {
 				info->is_unlocked = 0;
-			else
+#if !VBOOT_MOTA
+				info->is_unlock_critical = 0;
+#endif
+			} else {
 				info->is_unlocked = 1;
+#if !VBOOT_MOTA
+				info->is_unlock_critical = 1;
+#endif
+			}
 			info->is_tampered = 0;
 			info->charger_screen_enabled = 0;
+#if !VBOOT_MOTA
+			info->verity_mode = 1; //enforcing by default
+#endif
 			write_device_info(info);
 		}
 		memcpy(dev, info, sizeof(device_info));
@@ -1811,6 +1950,88 @@
 	write_device_info(&device);
 }
 
+/* set device unlock value
+ * Must check FRP before call this function
+ * Need to wipe data when unlock status changed
+ * type 0: oem unlock
+ * type 1: unlock critical
+ * status 0: unlock as false
+ * status 1: lock as true
+ */
+void set_device_unlock_value(int type, bool status)
+{
+	if (type == UNLOCK)
+		device.is_unlocked = status;
+#if !VBOOT_MOTA
+	else if (type == UNLOCK_CRITICAL)
+		device.is_unlock_critical = status;
+#endif
+	write_device_info(&device);
+}
+
+static void set_device_unlock(int type, bool status)
+{
+	int is_unlocked = -1;
+	char response[MAX_RSP_SIZE];
+
+	/* check device unlock status if it is as expected */
+	if (type == UNLOCK)
+		is_unlocked = device.is_unlocked;
+#if !VBOOT_MOTA
+	else if (type == UNLOCK_CRITICAL)
+		is_unlocked = device.is_unlock_critical;
+#endif
+	if (is_unlocked == status) {
+		snprintf(response, sizeof(response), "\tDevice already : %s", (status ? "unlocked!" : "locked!"));
+		fastboot_info(response);
+		fastboot_okay("");
+		return;
+	}
+
+	/* status is true, it means to unlock device */
+	if (status) {
+		if(!is_allow_unlock) {
+			fastboot_fail("oem unlock is not allowed");
+			return;
+		}
+
+#if FBCON_DISPLAY_MSG
+		display_unlock_menu_thread(type);
+		fastboot_okay("");
+		return;
+#else
+		if (type == UNLOCK) {
+			fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
+			return;
+		}
+#endif
+	}
+
+	set_device_unlock_value(type, status);
+
+	/* wipe data */
+	struct recovery_message msg;
+
+	snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+	write_misc(0, &msg, sizeof(msg));
+
+	fastboot_okay("");
+	reboot_device(RECOVERY_MODE);
+}
+
+static bool critical_flash_allowed(const char * entry)
+{
+	uint32_t i = 0;
+	if (entry == NULL)
+		return false;
+
+	for (i = 0; i < ARRAY_SIZE(critical_flash_allowed_ptn); i++) {
+		if(!strcmp(entry, critical_flash_allowed_ptn[i]))
+			return true;
+	}
+	return false;
+}
+
 #if DEVICE_TREE
 int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
 {
@@ -1959,10 +2180,12 @@
 		return;
 	}
 
+	// Initialize boot state before trying to verify boot.img
+#if VERIFIED_BOOT
+	boot_verifier_init();
 	/* Handle overflow if the input image size is greater than
 	 * boot image buffer can hold
 	 */
-#if VERIFIED_BOOT
 	if ((target_get_max_flash_size() - (image_actual - sig_actual)) < page_size)
 	{
 		fastboot_fail("booimage: size is greater than boot image buffer can hold");
@@ -1973,12 +2196,12 @@
 	/* Verify the boot image
 	 * device & page_size are initialized in aboot_init
 	 */
-	if (target_use_signed_kernel() && (!device.is_unlocked))
+	if (target_use_signed_kernel() && (!device.is_unlocked)) {
 		/* Pass size excluding signature size, otherwise we would try to
 		 * access signature beyond its length
 		 */
 		verify_signed_bootimg((uint32_t)data, (image_actual - sig_actual));
-
+	}
 #ifdef MDTP_SUPPORT
 	else
 	{
@@ -1998,6 +2221,13 @@
 	}
 #endif /* MDTP_SUPPORT */
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	// send root of trust
+	if(!send_rot_command((uint32_t)device.is_unlocked))
+		ASSERT(0);
+#endif
+#endif
 	/*
 	 * Check if the kernel image is a gzip package. If yes, need to decompress it.
 	 * If not, continue booting.
@@ -2173,6 +2403,13 @@
 			return;
 		}
 	}
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	if(!(strncmp(arg, "userdata", 8)))
+		if(send_delete_keys_to_tz())
+			ASSERT(0);
+#endif
+#endif
 	fastboot_okay("");
 }
 
@@ -2181,19 +2418,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
 
@@ -2666,19 +2895,24 @@
 #if VERIFIED_BOOT
 	if (target_build_variant_user())
 	{
-		if(!device.is_unlocked)
-		{
-			fastboot_fail("device is locked. Cannot flash images");
+		/* if device is locked:
+		 * common partition will not allow to be flashed
+		 * critical partition will allow to flash image.
+		 */
+		if(!device.is_unlocked && !critical_flash_allowed(arg)) {
+			fastboot_fail("Partition flashing is not allowed");
 			return;
 		}
-		if(!device.is_unlocked && device.is_verified)
-		{
-			if(!boot_verify_flash_allowed(arg))
-			{
-				fastboot_fail("cannot flash this partition in verified state");
-				return;
-			}
+#if !VBOOT_MOTA
+		/* if device critical is locked:
+		 * common partition will allow to be flashed
+		 * critical partition will not allow to flash image.
+		 */
+		if(!device.is_unlock_critical && critical_flash_allowed(arg)) {
+			fastboot_fail("Critical partition flashing is not allowed");
+			return;
 		}
+#endif
 	}
 #endif
 
@@ -2690,6 +2924,18 @@
 		cmd_flash_meta_img(arg, data, sz);
 	else
 		cmd_flash_mmc_img(arg, data, sz);
+
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	if((!strncmp(arg, "system", 6)) && !device.verity_mode)
+	{
+		// reset dm_verity mode to enforcing
+		device.verity_mode = 1;
+		write_device_info(&device);
+	}
+#endif
+#endif
+
 	return;
 }
 
@@ -2784,6 +3030,9 @@
 
 	if (target_is_emmc_boot())
 	{
+#if FBCON_DISPLAY_MSG
+		keys_detect_init();
+#endif
 		boot_linux_from_mmc();
 	}
 	else
@@ -2822,6 +3071,32 @@
 	fastboot_okay("");
 }
 
+void cmd_oem_off_mode_charger(const char *arg, void *data, unsigned size)
+{
+	char *p = NULL;
+	const char *delim = " \t\n\r";
+
+	if (arg) {
+		p = strtok((char *)arg, delim);
+		if (p) {
+			if (!strncmp(p, "0", 1)) {
+				device.charger_screen_enabled = 0;
+			} else if (!strncmp(p, "1", 1)) {
+				device.charger_screen_enabled = 1;
+			}
+		}
+	}
+
+	/* update charger_screen_enabled value for getvar
+	 * command
+	 */
+	snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
+		device.charger_screen_enabled);
+
+	write_device_info(&device);
+	fastboot_okay("");
+}
+
 void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
 {
 	dprintf(INFO, "Selecting display panel %s\n", arg);
@@ -2834,29 +3109,22 @@
 
 void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
 {
-	if(!is_allow_unlock) {
-		fastboot_fail("oem unlock is not allowed");
-		return;
-	}
-
-	display_fbcon_message("Oem Unlock requested");
-	fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
+	set_device_unlock(UNLOCK, TRUE);
 }
 
 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");
 			return;
 		}
 
-		device.is_unlocked = 1;
-		device.is_verified = 0;
-		write_device_info(&device);
+		set_device_unlock_value(UNLOCK, TRUE);
 
+		/* wipe data */
 		struct recovery_message msg;
+
 		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
 		write_misc(0, &msg, sizeof(msg));
 
@@ -2888,35 +3156,20 @@
 
 void cmd_oem_lock(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 = 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);
-	}
-	fastboot_okay("");
+	set_device_unlock(UNLOCK, FALSE);
 }
 
 void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
 {
-	char response[128];
+	char response[MAX_RSP_SIZE];
 	snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
 	fastboot_info(response);
 	snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
 	fastboot_info(response);
+#if !VBOOT_MOTA
+	snprintf(response, sizeof(response), "\tDevice critical unlocked: %s", (device.is_unlock_critical ? "true" : "false"));
+	fastboot_info(response);
+#endif
 	snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
 	fastboot_info(response);
 	snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
@@ -2924,6 +3177,24 @@
 	fastboot_okay("");
 }
 
+void cmd_flashing_get_unlock_ability(const char *arg, void *data, unsigned sz)
+{
+	char response[MAX_RSP_SIZE];
+	snprintf(response, sizeof(response), "\tget_unlock_ability: %d", is_allow_unlock);
+	fastboot_info(response);
+	fastboot_okay("");
+}
+
+void cmd_flashing_lock_critical(const char *arg, void *data, unsigned sz)
+{
+	set_device_unlock(UNLOCK_CRITICAL, FALSE);
+}
+
+void cmd_flashing_unlock_critical(const char *arg, void *data, unsigned sz)
+{
+	set_device_unlock(UNLOCK_CRITICAL, TRUE);
+}
+
 void cmd_preflash(const char *arg, void *data, unsigned sz)
 {
 	fastboot_okay("");
@@ -3172,39 +3443,68 @@
 	}
 }
 
+void get_product_name(unsigned char *buf)
+{
+	snprintf((char*)buf, MAX_RSP_SIZE, "%s",  TARGET(BOARD));
+	return;
+}
+
+void get_bootloader_version(unsigned char *buf)
+{
+	snprintf((char*)buf, MAX_RSP_SIZE, "%s",  device.bootloader_version);
+	return;
+}
+
+void get_baseband_version(unsigned char *buf)
+{
+	snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.radio_version);
+	return;
+}
+
+bool is_device_locked()
+{
+	return device.is_unlocked ? false:true;
+}
+
 /* register commands and variables for fastboot */
 void aboot_fastboot_register_commands(void)
 {
 	int i;
+	char hw_platform_buf[MAX_RSP_SIZE];
 
 	struct fastboot_cmd_desc cmd_list[] = {
-											/* By default the enabled list is empty. */
-											{"", NULL},
-											/* move commands enclosed within the below ifndef to here
-											 * if they need to be enabled in user build.
-											 */
+						/* By default the enabled list is empty. */
+						{"", NULL},
+						/* move commands enclosed within the below ifndef to here
+						 * if they need to be enabled in user build.
+						 */
 #ifndef DISABLE_FASTBOOT_CMDS
-											/* Register the following commands only for non-user builds */
-											{"flash:", cmd_flash},
-											{"erase:", cmd_erase},
-											{"boot", cmd_boot},
-											{"continue", cmd_continue},
-											{"reboot", cmd_reboot},
-											{"reboot-bootloader", cmd_reboot_bootloader},
-											{"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},
-											{"oem disable-charger-screen", cmd_oem_disable_charger_screen},
-											{"oem select-display-panel", cmd_oem_select_display_panel},
+						/* Register the following commands only for non-user builds */
+						{"flash:", cmd_flash},
+						{"erase:", cmd_erase},
+						{"boot", cmd_boot},
+						{"continue", cmd_continue},
+						{"reboot", cmd_reboot},
+						{"reboot-bootloader", cmd_reboot_bootloader},
+						{"oem unlock", cmd_oem_unlock},
+						{"oem unlock-go", cmd_oem_unlock_go},
+						{"oem lock", cmd_oem_lock},
+						{"flashing unlock", cmd_oem_unlock},
+						{"flashing lock", cmd_oem_lock},
+						{"flashing lock_critical", cmd_flashing_lock_critical},
+						{"flashing unlock_critical", cmd_flashing_unlock_critical},
+						{"flashing get_unlock_ability", cmd_flashing_get_unlock_ability},
+						{"oem device-info", cmd_oem_devinfo},
+						{"preflash", cmd_preflash},
+						{"oem enable-charger-screen", cmd_oem_enable_charger_screen},
+						{"oem disable-charger-screen", cmd_oem_disable_charger_screen},
+						{"oem off-mode-charge", cmd_oem_off_mode_charger},
+						{"oem select-display-panel", cmd_oem_select_display_panel},
 #if UNITTEST_FW_SUPPORT
-											{"oem run-tests", cmd_oem_runtests},
+						{"oem run-tests", cmd_oem_runtests},
 #endif
 #endif
-										  };
+						};
 
 	int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
 	for (i = 1; i < fastboot_cmds_count; i++)
@@ -3233,12 +3533,23 @@
 			device.charger_screen_enabled);
 	fastboot_publish("charger-screen-enabled",
 			(const char *) charger_screen_enabled);
+	fastboot_publish("off-mode-charge", (const char *) charger_screen_enabled);
 	snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
 			device.display_panel);
 	fastboot_publish("display-panel",
 			(const char *) panel_display_mode);
 	fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
 	fastboot_publish("version-baseband", (const char *) device.radio_version);
+	fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
+	smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
+	snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
+		target_is_emmc_boot()? "eMMC":"UFS");
+	fastboot_publish("variant", (const char *) get_variant);
+#if CHECK_BAT_VOLTAGE
+	update_battery_status();
+	fastboot_publish("battery-voltage", (const char *) battery_voltage);
+	fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
+#endif
 }
 
 void aboot_init(const struct app_descriptor *app)
@@ -3341,6 +3652,25 @@
 	{
 		boot_reason_alarm = true;
 	}
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	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);
+	}
+#endif
+#endif
 
 normal_boot:
 	if (!boot_into_fastboot)
@@ -3387,6 +3717,9 @@
 
 	/* initialize and start fastboot */
 	fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
+#if FBCON_DISPLAY_MSG
+	display_fastboot_menu_thread();
+#endif
 }
 
 uint32_t get_page_size()
diff --git a/app/aboot/devinfo.h b/app/aboot/devinfo.h
index 7eee69b..12d0554 100644
--- a/app/aboot/devinfo.h
+++ b/app/aboot/devinfo.h
@@ -37,6 +37,11 @@
 #define MAX_PANEL_ID_LEN 64
 #define MAX_VERSION_LEN  64
 
+enum unlock_type {
+	UNLOCK = 0,
+	UNLOCK_CRITICAL,
+};
+#if VBOOT_MOTA
 struct device_info
 {
 	unsigned char magic[DEVICE_MAGIC_SIZE];
@@ -48,5 +53,18 @@
 	char bootloader_version[MAX_VERSION_LEN];
 	char radio_version[MAX_VERSION_LEN];
 };
-
+#else
+struct device_info
+{
+	unsigned char magic[DEVICE_MAGIC_SIZE];
+	bool is_unlocked;
+	bool is_tampered;
+	bool is_unlock_critical;
+	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
 #endif
diff --git a/app/aboot/fastboot.c b/app/aboot/fastboot.c
index 545a24d..205b74a 100644
--- a/app/aboot/fastboot.c
+++ b/app/aboot/fastboot.c
@@ -448,6 +448,10 @@
 {
 	struct fastboot_var *var;
 
+#if CHECK_BAT_VOLTAGE
+	update_battery_status();
+#endif
+
 	if (!strncmp("all", arg, strlen(arg)))
 	{
 		getvar_all();
@@ -496,6 +500,10 @@
 {
 	struct fastboot_cmd *cmd;
 	int r;
+#if CHECK_BAT_VOLTAGE
+	boolean is_first_erase_flash = false;
+#endif
+
 	dprintf(INFO,"fastboot: processing commands\n");
 
 	uint8_t *buffer = (uint8_t *)memalign(CACHE_LINE, ROUNDUP(4096, CACHE_LINE));
@@ -519,6 +527,24 @@
 		buffer[r] = 0;
 		dprintf(INFO,"fastboot: %s\n", buffer);
 
+#if CHECK_BAT_VOLTAGE
+		/* check battery voltage before erase or flash image */
+		if (!strncmp((const char*) buffer, "getvar:partition-type", 21))
+			is_first_erase_flash = true;
+
+		if (is_first_erase_flash) {
+			if (!strncmp((const char*) buffer, "erase", 5) ||
+				!strncmp((const char*) buffer, "flash", 5)) {
+				if (!target_battery_soc_ok()) {
+					dprintf(INFO,"fastboot: battery voltage: %d\n",
+						target_get_battery_voltage());
+					fastboot_fail("Warning: battery's capacity is very low\n");
+					return;
+				}
+			}
+		}
+#endif
+
 		fastboot_state = STATE_COMMAND;
 
 		for (cmd = cmdlist; cmd; cmd = cmd->next) {
@@ -528,6 +554,15 @@
 				    (void*) download_base, download_size);
 			if (fastboot_state == STATE_COMMAND)
 				fastboot_fail("unknown reason");
+
+#if CHECK_BAT_VOLTAGE
+			if (!strncmp((const char*) buffer, "erase", 5) ||
+				!strncmp((const char*) buffer, "flash", 5)) {
+				if (is_first_erase_flash) {
+					is_first_erase_flash = false;
+				}
+			}
+#endif
 			goto again;
 		}
 
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 01f907a..21abc12 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -443,6 +443,7 @@
 	}
 
 	out:
+	display_image_on_screen();
 	free_mdtp_image();
 }
 
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 643ed73..924c4fe 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -55,6 +55,7 @@
 extern void mdelay(unsigned msecs);
 extern uint32_t target_volume_up();
 extern uint32_t target_volume_down();
+extern int msm_display_on();
 
 struct mdtp_fbimage {
     uint32_t width;
@@ -242,11 +243,7 @@
 	arch_clean_invalidate_cache_range((addr_t) fb_config->base, (fb_config->height * fb_config->width * bytes_per_bpp));
 
 	fbcon_flush();
-
-#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
-	if(is_cmd_mode_enabled())
-        mipi_dsi_cmd_mode_trigger();
-#endif
+	msm_display_on();
 
 #endif
 }
diff --git a/app/rpmbtests/ufs_rpmb.c b/app/rpmbtests/ufs_rpmb.c
index d951933..b84dfe7 100644
--- a/app/rpmbtests/ufs_rpmb.c
+++ b/app/rpmbtests/ufs_rpmb.c
@@ -86,6 +86,44 @@
 	printf("\n");
 }
 
+bool swp_test()
+{
+	int ret = 0;
+	qsee_stor_secure_wp_info_t cb = {0};
+	// Write protect 4 partitions in Lun 0.
+	cb.lun_number = 0;
+	cb.num_entries = 4;
+	cb.wp_entries[0].wp_enable = 0x1;
+	cb.wp_entries[0].wp_type_mask = 0x1;
+	cb.wp_entries[0].addr = 8;
+	cb.wp_entries[0].num_blocks = 8192;
+
+	cb.wp_entries[1].wp_enable = 0x1;
+	cb.wp_entries[1].wp_type_mask = 0x1;
+	cb.wp_entries[1].addr = 74120;
+	cb.wp_entries[1].num_blocks = 32;
+
+	cb.wp_entries[2].wp_enable = 0x1;
+	cb.wp_entries[2].wp_type_mask = 0x1;
+	cb.wp_entries[2].addr = 6;
+	cb.wp_entries[2].num_blocks = 2;
+
+	cb.wp_entries[3].wp_enable = 0x1;
+	cb.wp_entries[3].wp_type_mask = 0x1;
+	cb.wp_entries[3].addr = 73736;
+	cb.wp_entries[3].num_blocks = 256;
+
+	ret = swp_write(cb);
+	if (ret)
+	{
+		dprintf(CRITICAL, "SWP Write Test Failed\n");
+		return false;
+	}
+	else
+		dprintf(CRITICAL, "SWP Write Test Passed\n");
+	return true;
+}
+
 bool rpmb_test(struct ufs_dev *dev, uint16_t address, uint16_t rpmb_num_blocks)
 {
 	struct rpmb_frame data_frame, result_frame[rpmb_num_blocks];
diff --git a/app/rpmbtests/ufs_rpmb.h b/app/rpmbtests/ufs_rpmb.h
index 5d16a7b..06f221e 100644
--- a/app/rpmbtests/ufs_rpmb.h
+++ b/app/rpmbtests/ufs_rpmb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -40,6 +40,7 @@
 	printf("\n");
 }
 
+bool swp_test();
 void rpmb_run_test();
 bool rpmb_test(struct ufs_dev *dev, uint16_t address, uint16_t rpmb_num_blocks);
 void dump_rpmb_data(struct rpmb_frame *result_frame);
diff --git a/dev/fbcon/fbcon.c b/dev/fbcon/fbcon.c
index 885ce87..f2296a4 100644
--- a/dev/fbcon/fbcon.c
+++ b/dev/fbcon/fbcon.c
@@ -47,13 +47,32 @@
 	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 RGB565_GREEN		0x3666
 
 #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 RGB888_GREEN            0x00ff00
 
 #define FONT_WIDTH		5
 #define FONT_HEIGHT		12
@@ -62,26 +81,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_GREEN_MSG] = {RGB565_GREEN, RGB565_BLACK},
+					[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_GREEN_MSG] = {RGB888_GREEN, RGB888_BLACK},
+					[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 +135,7 @@
 				}
 				else
 				{
-					for (j = 0; j < SCALE_FACTOR; j++) {
+					for (j = 0; j < scale_factor; j++) {
 						pixels = pixels + bpp;
 					}
 				}
@@ -105,11 +148,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 +163,7 @@
 				}
 				else
 				{
-					for (j = 0; j < SCALE_FACTOR; j++) {
+					for (j = 0; j < scale_factor; j++) {
 						pixels = pixels + bpp;
 					}
 				}
@@ -132,6 +175,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 +248,51 @@
 	fbcon_flush();
 }
 
-/* TODO: take stride into account */
+void fbcon_draw_line(uint32_t type)
+{
+	char *pixels;
+	uint32_t line_color, tmp_color;
+	int i, j;
+
+	/* set line's color via diffrent type */
+	line_color = fb_color_formats[type].fg;
+
+	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 = line_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 +301,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 +327,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 +357,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_autopll.c b/dev/gcdb/display/gcdb_autopll.c
index b78cecc..562ca0b 100755
--- a/dev/gcdb/display/gcdb_autopll.c
+++ b/dev/gcdb/display/gcdb_autopll.c
@@ -242,10 +242,17 @@
 }
 #endif
 
-static uint32_t calculate_vco_thulium()
+static uint32_t calculate_vco_thulium(uint8_t bpp, uint8_t lanes)
 {
 	uint32_t rate;
 	uint32_t mod;
+	int bpp_lane;
+
+	/* round up the pixel clock to get the correct n2 div */
+	bpp_lane = bpp / lanes;
+	mod = pll_data.bit_clock % bpp_lane;
+	if (mod)
+		pll_data.pixel_clock++;
 
 	pll_data.vco_min = MIN_THULIUM_VCO_RATE;
 	pll_data.vco_max = MAX_THULIUM_VCO_RATE;
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index 6035ec3..753d0ed 100644
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -166,11 +166,12 @@
 
 		err = mdss_dsi_panel_clock(1, pinfo);
 		if (!err) {
+			dprintf(SPEW, "frame_rate=%d, vcorate=%d success!\n",
+					pinfo->mipi.frame_rate,
+					pinfo->mipi.dsi_pll_config->vco_clock);
 			pinfo->dfps.codes_dfps[i].is_valid = 1;
 			pinfo->dfps.codes_dfps[i].frame_rate =
 				pinfo->mipi.frame_rate;
-			pinfo->dfps.codes_dfps[i].frame_rate =
-				pinfo->mipi.frame_rate;
 			pinfo->dfps.codes_dfps[i].clk_rate =
 				pinfo->mipi.dsi_pll_config->vco_clock;
 			pinfo->dfps.codes_dfps[i].pll_codes =
@@ -201,7 +202,7 @@
 	index = partition_get_index("splash");
 	if (index == INVALID_PTN) {
 		dprintf(INFO, "%s: splash partition table not found\n", __func__);
-		ret = NO_ERROR;
+		ret = ERROR;
 		goto splash_err;
 	}
 
@@ -262,7 +263,7 @@
 	index = partition_get_index("splash");
 	if (index == INVALID_PTN) {
 		dprintf(INFO, "%s: splash partition table not found\n", __func__);
-		ret = NO_ERROR;
+		ret = ERROR;
 		goto store_err;
 	}
 
@@ -477,6 +478,36 @@
 			~USE_DSI1_PLL_FLAG;
 }
 
+static int update_dsi_display_config()
+{
+	int ret = NO_ERROR;
+
+	if ((panel.panel_info.lm_split[0] > 0) &&
+	    (panel.panel_info.lm_split[1] > 0))
+		panelstruct.paneldata->panel_operating_mode |= DUAL_PIPE_FLAG;
+
+	if (panelstruct.paneldata->panel_operating_mode & DUAL_PIPE_FLAG) {
+		if ((panel.panel_info.lm_split[0] <= 0) ||
+		    (panel.panel_info.lm_split[1] <= 0)) {
+			panel.panel_info.lm_split[0] =
+				panelstruct.panelres->panel_width / 2;
+			panel.panel_info.lm_split[1] =
+				panel.panel_info.lm_split[0];
+		}
+	}
+
+	if (panelstruct.config && panelstruct.config->use_pingpong_split)
+		panelstruct.paneldata->panel_operating_mode |= DST_SPLIT_FLAG;
+
+	if ((panelstruct.paneldata->panel_operating_mode & DUAL_PIPE_FLAG) &&
+	    (panelstruct.paneldata->panel_operating_mode & DST_SPLIT_FLAG)) {
+		dprintf(CRITICAL, "DUAL_PIPE_FLAG and DST_SPLIT_FLAG cannot be selected togather\n");
+		ret = ERROR;
+	}
+
+	return ret;
+}
+
 int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
 {
 	int ret = NO_ERROR;
@@ -487,6 +518,8 @@
 				 &dsi_video_mode_phy_db);
 
 	if (pan_type == PANEL_TYPE_DSI) {
+		if (update_dsi_display_config())
+			goto error_gcdb_display_init;
 		target_dsi_phy_config(&dsi_video_mode_phy_db);
 		mdss_dsi_check_swap_status();
 		mdss_dsi_set_pll_src();
@@ -510,7 +543,8 @@
 		if (panel.panel_info.dfps.panel_dfps.enabled) {
 			panel.panel_info.dfps.dfps_fb_base = base;
 			base += DFPS_PLL_CODES_SIZE;
-			dprintf(SPEW, "fb_base=0x%p!\n", base);
+			dprintf(SPEW, "dfps base=0x%p,d, fb_base=0x%p!\n",
+					panel.panel_info.dfps.dfps_fb_base, base);
 		}
 
 		panel.fb.base = base;
@@ -530,7 +564,6 @@
 		dprintf(CRITICAL, "Target panel init not found!\n");
 		ret = ERR_NOT_SUPPORTED;
 		goto error_gcdb_display_init;
-
 	}
 
 	panel.fb.base = base;
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index aaed691..a4f1685 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -76,6 +76,8 @@
 	uint32_t sim_mode;
 	char dsi_config[DSI_CFG_SIZE];
 	uint32_t dsi_pll_src;
+	/* If dual-DSI, slave cfg will use 2nd index */
+	int cfg_num[2]; /* -ve number means no overide */
 };
 
 enum {
diff --git a/dev/gcdb/display/gcdb_display_param.c b/dev/gcdb/display/gcdb_display_param.c
index e236fa1..44b3454 100644
--- a/dev/gcdb/display/gcdb_display_param.c
+++ b/dev/gcdb/display/gcdb_display_param.c
@@ -38,7 +38,7 @@
 #include "fastboot_oem_display.h"
 
 struct oem_panel_data oem_data = {{'\0'}, {'\0'}, false, false, false, SIM_NONE,
-	"single_dsi", DSI_PLL_DEFAULT};
+	"single_dsi", DSI_PLL_DEFAULT, {-1, -1}};
 
 static int panel_name_to_dt_string(struct panel_lookup_list supp_panels[],
 			  uint32_t supp_panels_size,
@@ -186,8 +186,20 @@
 		for (i = 0; (ch + i) < ch_tmp; i++)
 			oem_data.sec_panel[i] = *(ch + i);
 		oem_data.sec_panel[i] = '\0';
+
+		/* Topology configuration for secondary panel */
+		ch_tmp = strstr((char *) ch, ":cfg");
+		if (ch_tmp)
+			oem_data.cfg_num[1] = atoi((const char*)(ch_tmp + 4));
+	} else {
+		oem_data.sec_panel[0] = '\0';
 	}
 
+	/* Topology configuration for primary panel */
+	ch_tmp = strstr((char *) panel_name, ":cfg");
+	if (ch_tmp && (!ch || (ch && (ch_tmp < ch))))
+		oem_data.cfg_num[0] = atoi((const char*)(ch_tmp + 4));
+
 	/* Skip LK configuration */
 	ch = strstr((char *) panel_name, ":skip");
 	oem_data.skip = ch ? true : false;
@@ -219,6 +231,9 @@
 	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,
@@ -280,6 +295,8 @@
 	int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG | DST_SPLIT_FLAG;
 	int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
 	char *sctl_string, *pll_src_string = NULL;
+	char prim_cfg_name[10]="\0", slave_cfg_name[10]="\0"; /* config[0-99] */
+	char *display_cmd_line = pbuf;
 
 	panelstruct = mdss_dsi_get_panel_data();
 
@@ -328,7 +345,7 @@
 
 	if (((panel_mode & SPLIT_DISPLAY_FLAG) ||
 	     (panel_mode & DST_SPLIT_FLAG)) && slave_panel_node == NULL) {
-		dprintf(CRITICAL, "slave node not present in dual dsi case\n");
+		dprintf(CRITICAL, "slave node not present in split-dsi case\n");
 		return false;
 	}
 
@@ -409,6 +426,40 @@
 		}
 	}
 
+	dprintf(SPEW, "dsi_cfg:%s mdp_cfg[0]=%d mdp_cfg[1]=%d\n",
+		oem_data.dsi_config, oem_data.cfg_num[0], oem_data.cfg_num[1]);
+
+	if ((oem_data.cfg_num[0] >= 0) && (oem_data.cfg_num[0] < 100)) {
+		snprintf(prim_cfg_name, sizeof(prim_cfg_name),
+			":config%d", oem_data.cfg_num[0]);
+		arg_size += strlen(prim_cfg_name);
+	} else if (panelstruct.config != NULL) {
+		/*
+		 * if oem command wasn't set then take topology config
+		 * used by per target oem panel driver if available.
+		 */
+		snprintf(prim_cfg_name, sizeof(prim_cfg_name),
+			":%s", panelstruct.config->config_name);
+		arg_size += strlen(prim_cfg_name);
+	}
+
+	/* in split-dsi, primary and slave panel share same topology config */
+	if (!strcmp(oem_data.dsi_config, "split_dsi"))
+		snprintf(slave_cfg_name, sizeof(slave_cfg_name),
+			"%s", prim_cfg_name);
+
+	if (!strcmp(oem_data.dsi_config, "dual_dsi")) {
+		if ((oem_data.cfg_num[1] >= 0) && (oem_data.cfg_num[1] < 100)) {
+			snprintf(slave_cfg_name, sizeof(slave_cfg_name),
+				":config%d", oem_data.cfg_num[1]);
+			arg_size += strlen(slave_cfg_name);
+		}
+		/*
+		 * In dual-dsi, secondary or slave panels isn't supported
+		 * in bootloader so "else" case like above is not possible.
+		 */
+	}
+
 	if (buf_size < arg_size) {
 		dprintf(CRITICAL, "display command line buffer is small\n");
 		ret = false;
@@ -429,6 +480,13 @@
 		pbuf += panel_node_len;
 		buf_size -= panel_node_len;
 
+		/* writeout primary topology config */
+		if (strlen(prim_cfg_name) > 0) {
+			strlcpy(pbuf, prim_cfg_name, buf_size);
+			pbuf += strlen(prim_cfg_name);
+			buf_size -= strlen(prim_cfg_name);
+		}
+
 		strlcpy(pbuf, sctl_string, buf_size);
 		pbuf += strlen(sctl_string);
 		buf_size -= strlen(sctl_string);
@@ -437,6 +495,13 @@
 		pbuf += slave_panel_node_len;
 		buf_size -= slave_panel_node_len;
 
+		/* writeout slave panel, split-dsi, or secondary panel, dual-dsi, topology config */
+		if (strlen(slave_cfg_name) > 0) {
+			strlcpy(pbuf, slave_cfg_name, buf_size);
+			pbuf += strlen(slave_cfg_name);
+			buf_size -= strlen(slave_cfg_name);
+		}
+
 		strlcpy(pbuf, DSI_CFG_STRING, buf_size);
 		pbuf += DSI_CFG_STRING_LEN;
 		buf_size -= DSI_CFG_STRING_LEN;
@@ -460,6 +525,9 @@
 			pbuf += strlen(sim_mode_string);
 			buf_size -= strlen(sim_mode_string);
 		}
+
+		dprintf(INFO, "display kernel cmdline:%s\n",
+			display_cmd_line);
 	}
 	return ret;
 }
diff --git a/dev/gcdb/display/include/panel.h b/dev/gcdb/display/include/panel.h
index c9aee8b..11f471c 100755
--- a/dev/gcdb/display/include/panel.h
+++ b/dev/gcdb/display/include/panel.h
@@ -217,9 +217,18 @@
 	uint32_t bpc;		/* target bpc, byte per component */
 	uint32_t slice_per_pkt;
 	uint32_t block_prediction;
-	uint32_t ich_reset_override;
-	uint32_t ich_reset_value;
-	uint32_t data_path_mode;
+};
+
+struct topology_config {
+	char *config_name; /* matches with kernel cmdline */
+	/*
+	 * lm_split: -ve value means that lm_split is not used.
+	 *           If lm_split is used then DUAL_PIPE flag will be added.
+	 */
+	int lm_split[2];
+	int num_dsc_enc; /* how many encoder to use */
+	struct dsc_parameters *dsc;
+	int use_pingpong_split;
 };
 
 #endif /*_PANEL_H_ */
diff --git a/dev/gcdb/display/include/panel_hx8394f_720p_video.h b/dev/gcdb/display/include/panel_hx8394f_720p_video.h
new file mode 100755
index 0000000..c2fc441
--- /dev/null
+++ b/dev/gcdb/display/include/panel_hx8394f_720p_video.h
@@ -0,0 +1,278 @@
+/* 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 _PANEL_HX8394F_720P_VIDEO_H_
+#define _PANEL_HX8394F_720P_VIDEO_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config hx8394f_720p_video_panel_data = {
+	"qcom,mdss_dsi_hx8394f_720p_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution hx8394f_720p_video_panel_res = {
+	720, 1280, 16, 16, 10, 0, 15, 12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info hx8394f_720p_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char hx8394f_720p_video_on_cmd0[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xB9, 0xFF, 0x83, 0x94,
+
+};
+
+static char hx8394f_720p_video_on_cmd1[] = {
+	0x07, 0x00, 0x29, 0xC0,
+	0xBA, 0x63, 0x03, 0x68,
+	0x6b, 0xb2, 0xc0, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd2[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xB1, 0x50, 0x12, 0x72,
+	0x09, 0x32, 0x34, 0x71,
+	0x31, 0x70, 0x2f, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd3[] = {
+	0x07, 0x00, 0x29, 0xC0,
+	0xB2, 0x00, 0x80, 0x64,
+	0x0E, 0x0D, 0x2F, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd4[] = {
+	0x16, 0x00, 0x29, 0xC0,
+	0xB4, 0x6C, 0x6D, 0x6C,
+	0x6D, 0x6C, 0x6D, 0x01,
+	0x01, 0xFF, 0x75, 0x00,
+	0x3f, 0x6C, 0x6D, 0x6C,
+	0x6D, 0x6C, 0x6D, 0x01,
+	0x01, 0xFF, 0xFF, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd5[] = {
+	0x22, 0x00, 0x29, 0xC0,
+	0xD3, 0x00, 0x00, 0x07,
+	0x07, 0x40, 0x07, 0x10,
+	0x00, 0x08, 0x10, 0x08,
+	0x00, 0x08, 0x54, 0x15,
+	0x0E, 0x05, 0x0E, 0x02,
+	0x15, 0x06, 0x05, 0x06,
+	0x47, 0x44, 0x0A, 0x0A,
+	0x4B, 0x10, 0x07, 0x07,
+	0x0e, 0x40, 0xFF, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd6[] = {
+	0x2d, 0x00, 0x29, 0xC0,
+	0xD5, 0x1A, 0x1A, 0x1B,
+	0x1B, 0x00, 0x01, 0x02,
+	0x03, 0x04, 0x05, 0x06,
+	0x07, 0x08, 0x09, 0x0A,
+	0x0B, 0x24, 0x25, 0x18,
+	0x18, 0x26, 0x27, 0x18,
+	0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x20,
+	0x21, 0x18, 0x18, 0x18,
+	0x18, 0xFF, 0xFF, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd7[] = {
+	0x2d, 0x00, 0x29, 0xC0,
+	0xD6, 0x1A, 0x1A, 0x1B,
+	0x1B, 0x0B, 0x0A, 0x09,
+	0x08, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01,
+	0x00, 0x21, 0x20, 0x18,
+	0x18, 0x27, 0x26, 0x18,
+	0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x25,
+	0x24, 0x18, 0x18, 0x18,
+	0x18, 0xFF, 0xFF, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd8[] = {
+	0x3B, 0x00, 0x29, 0xC0,
+	0xE0, 0x00, 0x0C, 0x19,
+	0x20, 0x23, 0x26, 0x29,
+	0x28, 0x51, 0x61, 0x70,
+	0x6F, 0x76, 0x86, 0x89,
+	0x8D, 0x99, 0x9A, 0x95,
+	0xA1, 0xB0, 0x57, 0x55,
+	0x58, 0x5C, 0x5e, 0x64,
+	0x6b, 0x7f, 0x00, 0x0C,
+	0x19, 0x20, 0x23, 0x26,
+	0x29, 0x28, 0x51, 0x61,
+	0x70, 0x6F, 0x76, 0x86,
+	0x89, 0x8D, 0x99, 0x9A,
+	0x95, 0xA1, 0xB0, 0x57,
+	0x55, 0x58, 0x5C, 0x5e,
+	0x64, 0x6b, 0x7f, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd9[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xC0, 0x1f, 0x73, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd10[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xCC, 0x0B, 0xFF, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd11[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xd4, 0x02, 0xFF, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd12[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0xB6, 0x7E, 0x7E, 0xFF,
+};
+
+static char hx8394f_720p_video_on_cmd13[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static char hx8394f_720p_video_on_cmd14[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd hx8394f_720p_video_on_command[] = {
+	{0x8, hx8394f_720p_video_on_cmd0, 0x00},
+	{0xc, hx8394f_720p_video_on_cmd1, 0x00},
+	{0x10, hx8394f_720p_video_on_cmd2, 0x00},
+	{0xc, hx8394f_720p_video_on_cmd3, 0x00},
+	{0x1c, hx8394f_720p_video_on_cmd4, 0x00},
+	{0x28, hx8394f_720p_video_on_cmd5, 0x00},
+	{0x34, hx8394f_720p_video_on_cmd6, 0x00},
+	{0x34, hx8394f_720p_video_on_cmd7, 0x00},
+	{0x40, hx8394f_720p_video_on_cmd8, 0x00},
+	{0x8, hx8394f_720p_video_on_cmd9, 0x00},
+	{0x8, hx8394f_720p_video_on_cmd10, 0x00},
+	{0x8, hx8394f_720p_video_on_cmd11, 0x00},
+	{0x8, hx8394f_720p_video_on_cmd12, 0x00},
+	{0x4, hx8394f_720p_video_on_cmd13, 0x96},
+	{0x4, hx8394f_720p_video_on_cmd14, 0x0a}
+};
+
+#define HX8394F_720P_VIDEO_ON_COMMAND 15
+
+
+static char hx8394f_720p_videooff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char hx8394f_720p_videooff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd hx8394f_720p_video_off_command[] = {
+	{0x4, hx8394f_720p_videooff_cmd0, 0x78},
+	{0x4, hx8394f_720p_videooff_cmd1, 0x96}
+};
+
+#define HX8394F_720P_VIDEO_OFF_COMMAND 2
+
+
+static struct command_state hx8394f_720p_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info hx8394f_720p_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info hx8394f_720p_video_video_panel = {
+	1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+
+static struct lane_configuration hx8394f_720p_video_lane_config = {
+  4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t hx8394f_720p_video_timings[] = {
+	0x72, 0x16, 0x0e, 0x00, 0x38, 0x3c, 0x12, 0x1a, 0x10, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing hx8394f_720p_video_timing_info = {
+	0, 4, 0x04, 0x18
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence hx8394f_720p_video_reset_seq = {
+	{1, 0, 1, }, {20, 2, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight hx8394f_720p_video_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#define HX8394F_720P_VIDEO_SIGNATURE 0xFFFF
+
+#endif /*_PANEL_HX8394F_720P_VIDEO_H_*/
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 b059bb3..f1a39b0 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
@@ -332,8 +332,23 @@
 /*---------------------------------------------------------------------------*/
 /* DSC									     */
 /*---------------------------------------------------------------------------*/
-static const struct dsc_parameters nt35597_wqxga_dsc_cmd_paras = {
-	1, 0, 0, 16, 720, 8, 8, 2, 1, 0, 0, 0
+struct dsc_parameters nt35597_wqxga_dsc_cmd_params0 = {
+	1, 0, 0, 16, 720, 8, 8, 2, 1
+};
+
+/* 1LM + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_cmd_config0 = {
+	"config0", {-1, -1}, 1, &nt35597_wqxga_dsc_cmd_params0, false
+};
+
+/* 2LM + 3D Mux + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_cmd_config1 = {
+	"config1", {720, 720}, 1, &nt35597_wqxga_dsc_cmd_params0, false
+};
+
+/* 2LM + 2 DSC_ENC + DSC_MERGE */
+struct topology_config nt35597_wqxga_dsc_cmd_config2 = {
+	"config2", {720, 720}, 2, &nt35597_wqxga_dsc_cmd_params0, false
 };
 
 #endif
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 382d75c..572d2d5 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
@@ -319,8 +319,23 @@
 /*---------------------------------------------------------------------------*/
 /* DSC									     */
 /*---------------------------------------------------------------------------*/
-static const struct dsc_parameters nt35597_wqxga_dsc_video_paras = {
-	1, 0, 0, 16, 720, 8, 8, 2, 1, 0, 0, 0
+struct dsc_parameters nt35597_wqxga_dsc_video_params0 = {
+	1, 0, 0, 16, 720, 8, 8, 2, 1
+};
+
+/* 1LM + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_video_config0 = {
+	"config0", {-1, -1}, 1, &nt35597_wqxga_dsc_video_params0, false
+};
+
+/* 2LM + 3D Mux + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_video_config1 = {
+	"config1", {720, 720}, 1, &nt35597_wqxga_dsc_video_params0, false
+};
+
+/* 2LM + 2 DSC_ENC + DSC_MERGE */
+struct topology_config nt35597_wqxga_dsc_video_config2 = {
+	"config2", {720, 720}, 2, &nt35597_wqxga_dsc_video_params0, false
 };
 
 #endif
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
index b01752a..17248ba 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
@@ -270,4 +270,14 @@
 	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
 };
 
+/* 2LM + 2CTL */
+struct topology_config nt35597_wqxga_dualdsi_cmd_config0 = {
+	"config0", {720, 720}, 0, NULL, false
+};
+
+/* 1LM + 1CTL + PP_SPLIT */
+struct topology_config nt35597_wqxga_dualdsi_cmd_config1 = {
+	"config1", {-1, -1}, 0, NULL, true
+};
+
 #endif
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
index b5f7cd8..556d657 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
@@ -262,4 +262,14 @@
 	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
 };
 
+/* 2LM + 2CTL */
+struct topology_config nt35597_wqxga_dualdsi_video_config0 = {
+	"config0", {720, 720}, 0, NULL, false
+};
+
+/* 1LM + 1CTL + PP_SPLIT */
+struct topology_config nt35597_wqxga_dualdsi_video_config1 = {
+	"config1", {-1, -1}, 0, NULL, true
+};
+
 #endif
diff --git a/dev/gcdb/display/include/panel_r69006_1080p_cmd.h b/dev/gcdb/display/include/panel_r69006_1080p_cmd.h
new file mode 100755
index 0000000..21bf993
--- /dev/null
+++ b/dev/gcdb/display/include/panel_r69006_1080p_cmd.h
@@ -0,0 +1,319 @@
+/* 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 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+
+#ifndef _PANEL_R69006_1080P_CMD_H_
+#define _PANEL_R69006_1080P_CMD_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config r69006_1080p_cmd_panel_data = {
+	"qcom,mdss_dsi_r69006_1080p_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution r69006_1080p_cmd_panel_res = {
+	1080, 1920, 100, 82, 20, 0, 3, 9, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info r69006_1080p_cmd_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char r69006_1080p_cmd_on_cmd0[] = {
+	0XB0, 0x00, 0x23, 0x80
+};
+
+static char r69006_1080p_cmd_on_cmd1[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0XB3, 0x04, 0x10, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd2[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0XB4, 0x0c, 0x00, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd3[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0XB6, 0x3b, 0xc3, 0x00,
+};
+
+static char r69006_1080p_cmd_on_cmd4[] = {
+	0XC0, 0x00, 0x23, 0x80
+};
+
+static char r69006_1080p_cmd_on_cmd5[] = {
+	0X36, 0x98, 0x15, 0x80
+};
+
+static char r69006_1080p_cmd_on_cmd6[] = {
+	0XCC, 0x04, 0x23, 0x80
+};
+
+static char r69006_1080p_cmd_on_cmd7[] = {
+	0x20, 0x00, 0x29, 0xC0,
+	0xC1, 0x84, 0x00, 0x10,
+	0xEF, 0x8B, 0xF1, 0xFF,
+	0xFF, 0xDF, 0x9C, 0xC5,
+	0x9A, 0x73, 0x8D, 0xAD,
+	0x63, 0xFE, 0xFF, 0xFF,
+	0xCB, 0xF8, 0x01, 0x00,
+	0xAA, 0x40, 0x00, 0xC2,
+	0x01, 0x08, 0x00, 0x01,
+};
+
+static char r69006_1080p_cmd_on_cmd8[] = {
+	0x0A, 0x00, 0x29, 0xC0,
+	0xCB, 0x0D, 0xFE, 0x1F,
+	0x2C, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd9[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xC2, 0x01, 0xF7, 0x80,
+	0x04, 0x63, 0x00, 0x60,
+	0x00, 0x01, 0x30, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd10[] = {
+	0x07, 0x00, 0x29, 0xC0,
+	0XC3, 0x55, 0x01, 0x00,
+	0x01, 0x00, 0x00, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd11[] = {
+	0x12, 0x00, 0x29, 0xC0,
+	0XC4, 0x70, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x02, 0x01,
+	0x00, 0x05, 0x01, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd12[] = {
+	0x0F, 0x00, 0x29, 0xC0,
+	0xC6, 0x59, 0x07, 0x4a,
+	0x07, 0x4a, 0x01, 0x0E,
+	0x01, 0x02, 0x01, 0x02,
+	0x09, 0x15, 0x07, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd13[] = {
+	0x1F, 0x00, 0x29, 0xC0,
+	0XC7, 0x00, 0x30, 0x32,
+	0x34, 0x42, 0x4E, 0x56,
+	0x62, 0x44, 0x4A, 0x54,
+	0x62, 0x6B, 0x73, 0x7F,
+	0x08, 0x30, 0x32, 0x34,
+	0x42, 0x4E, 0x56, 0x62,
+	0x44, 0x4A, 0x54, 0x62,
+	0x6B, 0x73, 0x7F, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd14[] = {
+	0x14, 0x00, 0x29, 0xC0,
+	0xC8, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0xFC, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+};
+
+static char r69006_1080p_cmd_on_cmd15[] = {
+	0x09, 0x00, 0x29, 0xC0,
+	0xC9, 0x1F, 0x68, 0x1F,
+	0x68, 0x4C, 0x4C, 0xC4,
+	0x11, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd16[] = {
+	0x11, 0x00, 0x29, 0xC0,
+	0xD0, 0x33, 0x01, 0x91,
+	0x0B, 0xD9, 0x19, 0x19,
+	0x00, 0x00, 0x00, 0x19,
+	0x99, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd17[] = {
+	0x1D, 0x00, 0x29, 0xC0,
+	0xD3, 0x1B, 0x3B, 0xBB,
+	0xAD, 0xA5, 0x33, 0x33,
+	0x33, 0x00, 0x80, 0xAD,
+	0xA8, 0x6f, 0x6f, 0x33,
+	0x33, 0x33, 0xF7, 0xF2,
+	0x1F, 0x7D, 0x7C, 0xFF,
+	0x0F, 0x99, 0x00, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_cmd_on_cmd18[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xD4, 0x57, 0x33, 0x03,
+};
+
+static char r69006_1080p_cmd_on_cmd19[] = {
+	0x0C, 0x00, 0x29, 0xC0,
+	0XD5, 0x66, 0x00, 0x00,
+	0x01, 0x27, 0x01, 0x27,
+	0x00, 0x6D, 0x00, 0x6D,
+};
+
+static char r69006_1080p_cmd_on_cmd20[] = {
+	0xD6, 0x81, 0x23, 0x80
+};
+
+static char r69006_1080p_cmd_on_cmd21[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static char r69006_1080p_cmd_on_cmd22[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r69006_1080p_cmd_on_command[] = {
+	{0x4, r69006_1080p_cmd_on_cmd0, 0x00},
+	{0xc, r69006_1080p_cmd_on_cmd1, 0x00},
+	{0x8, r69006_1080p_cmd_on_cmd2, 0x00},
+	{0x8, r69006_1080p_cmd_on_cmd3, 0x00},
+	{0x4, r69006_1080p_cmd_on_cmd4, 0x00},
+	{0x4, r69006_1080p_cmd_on_cmd5, 0x00},
+	{0x4, r69006_1080p_cmd_on_cmd6, 0x00},
+	{0x24, r69006_1080p_cmd_on_cmd7, 0x00},
+	{0x10, r69006_1080p_cmd_on_cmd8, 0x00},
+	{0x10, r69006_1080p_cmd_on_cmd9, 0x00},
+	{0xc, r69006_1080p_cmd_on_cmd10, 0x00},
+	{0x18, r69006_1080p_cmd_on_cmd11, 0x00},
+	{0x14, r69006_1080p_cmd_on_cmd12, 0x00},
+	{0x24, r69006_1080p_cmd_on_cmd13, 0x00},
+	{0x18, r69006_1080p_cmd_on_cmd14, 0x00},
+	{0x10, r69006_1080p_cmd_on_cmd15, 0x00},
+	{0x18, r69006_1080p_cmd_on_cmd16, 0x00},
+	{0x24, r69006_1080p_cmd_on_cmd17, 0x00},
+	{0x8, r69006_1080p_cmd_on_cmd18, 0x00},
+	{0x10, r69006_1080p_cmd_on_cmd19, 0x00},
+	{0x4, r69006_1080p_cmd_on_cmd20, 0x00},
+	{0x4, r69006_1080p_cmd_on_cmd21, 0x78},
+	{0x4, r69006_1080p_cmd_on_cmd22, 0x78}
+};
+
+#define R69006_1080P_CMD_ON_COMMAND 23
+
+
+static char r69006_1080p_cmdoff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char r69006_1080p_cmdoff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r69006_1080p_cmd_off_command[] = {
+	{0x4, r69006_1080p_cmdoff_cmd0, 0x78},
+	{0x4, r69006_1080p_cmdoff_cmd1, 0x96}
+};
+
+#define R69006_1080P_CMD_OFF_COMMAND 2
+
+
+static struct command_state r69006_1080p_cmd_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info r69006_1080p_cmd_command_panel = {
+	1, 1, 1, 0, 0, 0x2c, 0, 0, 0, 1, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info r69006_1080p_cmd_video_panel = {
+	1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration r69006_1080p_cmd_lane_config = {
+	4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t r69006_1080p_cmd_timings[] = {
+	0x7d, 0x25, 0x1d, 0x00, 0x37, 0x33, 0x22, 0x27, 0x1e, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing r69006_1080p_cmd_timing_info = {
+	0, 4, 0x20, 0x2c
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence r69006_1080p_cmd_reset_seq = {
+	{1, 0, 1, }, {20, 2, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight r69006_1080p_cmd_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#define R69006_1080P_CMD_SIGNATURE 0xFFFF
+
+#endif /*_PANEL_R69006_1080P_CMD_H_*/
diff --git a/dev/gcdb/display/include/panel_r69006_1080p_video.h b/dev/gcdb/display/include/panel_r69006_1080p_video.h
new file mode 100755
index 0000000..e9c5d26
--- /dev/null
+++ b/dev/gcdb/display/include/panel_r69006_1080p_video.h
@@ -0,0 +1,319 @@
+/* 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 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+
+#ifndef _PANEL_R69006_1080P_VIDEO_H_
+#define _PANEL_R69006_1080P_VIDEO_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config r69006_1080p_video_panel_data = {
+	"qcom,mdss_dsi_r69006_1080p_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution r69006_1080p_video_panel_res = {
+	1080, 1920, 100, 82, 20, 0, 3, 9, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info r69006_1080p_video_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char r69006_1080p_video_on_cmd0[] = {
+	0XB0, 0x00, 0x23, 0x80
+};
+
+static char r69006_1080p_video_on_cmd1[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0XB3, 0x05, 0x10, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd2[] = {
+	0x03, 0x00, 0x29, 0xC0,
+	0XB4, 0x0c, 0x00, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd3[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0XB6, 0x3b, 0xc3, 0x00,
+};
+
+static char r69006_1080p_video_on_cmd4[] = {
+	0XC0, 0x00, 0x23, 0x80
+};
+
+static char r69006_1080p_video_on_cmd5[] = {
+	0X36, 0x98, 0x15, 0x80
+};
+
+static char r69006_1080p_video_on_cmd6[] = {
+	0XCC, 0x04, 0x23, 0x80
+};
+
+static char r69006_1080p_video_on_cmd7[] = {
+	0x20, 0x00, 0x29, 0xC0,
+	0xC1, 0x84, 0x00, 0x10,
+	0xEF, 0x8B, 0xF1, 0xFF,
+	0xFF, 0xDF, 0x9C, 0xC5,
+	0x9A, 0x73, 0x8D, 0xAD,
+	0x63, 0xFE, 0xFF, 0xFF,
+	0xCB, 0xF8, 0x01, 0x00,
+	0xAA, 0x40, 0x00, 0xC2,
+	0x01, 0x08, 0x00, 0x01,
+};
+
+static char r69006_1080p_video_on_cmd8[] = {
+	0x0A, 0x00, 0x29, 0xC0,
+	0xCB, 0x0D, 0xFE, 0x1F,
+	0x2C, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd9[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xC2, 0x01, 0xF7, 0x80,
+	0x04, 0x63, 0x00, 0x60,
+	0x00, 0x01, 0x30, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd10[] = {
+	0x07, 0x00, 0x29, 0xC0,
+	0XC3, 0x55, 0x01, 0x00,
+	0x01, 0x00, 0x00, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd11[] = {
+	0x12, 0x00, 0x29, 0xC0,
+	0XC4, 0x70, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x02, 0x01,
+	0x00, 0x05, 0x01, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd12[] = {
+	0x0F, 0x00, 0x29, 0xC0,
+	0xC6, 0x59, 0x07, 0x4a,
+	0x07, 0x4a, 0x01, 0x0E,
+	0x01, 0x02, 0x01, 0x02,
+	0x09, 0x15, 0x07, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd13[] = {
+	0x1F, 0x00, 0x29, 0xC0,
+	0XC7, 0x00, 0x30, 0x32,
+	0x34, 0x42, 0x4E, 0x56,
+	0x62, 0x44, 0x4A, 0x54,
+	0x62, 0x6B, 0x73, 0x7F,
+	0x08, 0x30, 0x32, 0x34,
+	0x42, 0x4E, 0x56, 0x62,
+	0x44, 0x4A, 0x54, 0x62,
+	0x6B, 0x73, 0x7F, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd14[] = {
+	0x14, 0x00, 0x29, 0xC0,
+	0xC8, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0xFC, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+};
+
+static char r69006_1080p_video_on_cmd15[] = {
+	0x09, 0x00, 0x29, 0xC0,
+	0xC9, 0x1F, 0x68, 0x1F,
+	0x68, 0x4C, 0x4C, 0xC4,
+	0x11, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd16[] = {
+	0x11, 0x00, 0x29, 0xC0,
+	0xD0, 0x33, 0x01, 0x91,
+	0x0B, 0xD9, 0x19, 0x19,
+	0x00, 0x00, 0x00, 0x19,
+	0x99, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd17[] = {
+	0x1D, 0x00, 0x29, 0xC0,
+	0xD3, 0x1B, 0x3B, 0xBB,
+	0xAD, 0xA5, 0x33, 0x33,
+	0x33, 0x00, 0x80, 0xAD,
+	0xA8, 0x6f, 0x6f, 0x33,
+	0x33, 0x33, 0xF7, 0xF2,
+	0x1F, 0x7D, 0x7C, 0xFF,
+	0x0F, 0x99, 0x00, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69006_1080p_video_on_cmd18[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xD4, 0x57, 0x33, 0x03,
+};
+
+static char r69006_1080p_video_on_cmd19[] = {
+	0x0C, 0x00, 0x29, 0xC0,
+	0XD5, 0x66, 0x00, 0x00,
+	0x01, 0x27, 0x01, 0x27,
+	0x00, 0x6D, 0x00, 0x6D,
+};
+
+static char r69006_1080p_video_on_cmd20[] = {
+	0xD6, 0x81, 0x23, 0x80
+};
+
+static char r69006_1080p_video_on_cmd21[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static char r69006_1080p_video_on_cmd22[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r69006_1080p_video_on_command[] = {
+	{0x4, r69006_1080p_video_on_cmd0, 0x00},
+	{0xc, r69006_1080p_video_on_cmd1, 0x00},
+	{0x8, r69006_1080p_video_on_cmd2, 0x00},
+	{0x8, r69006_1080p_video_on_cmd3, 0x00},
+	{0x4, r69006_1080p_video_on_cmd4, 0x00},
+	{0x4, r69006_1080p_video_on_cmd5, 0x00},
+	{0x4, r69006_1080p_video_on_cmd6, 0x00},
+	{0x24, r69006_1080p_video_on_cmd7, 0x00},
+	{0x10, r69006_1080p_video_on_cmd8, 0x00},
+	{0x10, r69006_1080p_video_on_cmd9, 0x00},
+	{0xc, r69006_1080p_video_on_cmd10, 0x00},
+	{0x18, r69006_1080p_video_on_cmd11, 0x00},
+	{0x14, r69006_1080p_video_on_cmd12, 0x00},
+	{0x24, r69006_1080p_video_on_cmd13, 0x00},
+	{0x18, r69006_1080p_video_on_cmd14, 0x00},
+	{0x10, r69006_1080p_video_on_cmd15, 0x00},
+	{0x18, r69006_1080p_video_on_cmd16, 0x00},
+	{0x24, r69006_1080p_video_on_cmd17, 0x00},
+	{0x8, r69006_1080p_video_on_cmd18, 0x00},
+	{0x10, r69006_1080p_video_on_cmd19, 0x00},
+	{0x4, r69006_1080p_video_on_cmd20, 0x00},
+	{0x4, r69006_1080p_video_on_cmd21, 0x78},
+	{0x4, r69006_1080p_video_on_cmd22, 0x78}
+};
+
+#define R69006_1080P_VIDEO_ON_COMMAND 23
+
+
+static char r69006_1080p_videooff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char r69006_1080p_videooff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r69006_1080p_video_off_command[] = {
+	{0x4, r69006_1080p_videooff_cmd0, 0x78},
+	{0x4, r69006_1080p_videooff_cmd1, 0x96}
+};
+
+#define R69006_1080P_VIDEO_OFF_COMMAND 2
+
+
+static struct command_state r69006_1080p_video_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info r69006_1080p_video_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info r69006_1080p_video_video_panel = {
+	1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration r69006_1080p_video_lane_config = {
+	4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t r69006_1080p_video_timings[] = {
+	0x7d, 0x25, 0x1d, 0x00, 0x37, 0x33, 0x22, 0x27, 0x1e, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing r69006_1080p_video_timing_info = {
+	0, 4, 0x20, 0x2c
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence r69006_1080p_video_reset_seq = {
+	{1, 0, 1, }, {20, 2, 20, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight r69006_1080p_video_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#define R69006_1080P_VIDEO_SIGNATURE 0xFFFF
+
+#endif /*_PANEL_R69006_1080P_VIDEO_H_*/
diff --git a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
index ef5bc4c..470ddda 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
@@ -166,6 +166,16 @@
 	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
 };
 
+/* 2LM + 2CTL */
+struct topology_config sharp_wqxga_dualdsi_video_config0 = {
+	"config0", {800, 800}, 0, NULL, false
+};
+
+/* 1LM + 1CTL + PP_SPLIT */
+struct topology_config sharp_wqxga_dualdsi_video_config1 = {
+	"config1", {-1, -1}, 0, NULL, true
+};
+
 #define SHARP_WQXGA_DUALDSI_VIDEO_SIGNATURE 0x210000
 
 #endif /*_PANEL_SHARP_WQXGA_DUALDSI_VIDEO_H_*/
diff --git a/dev/gcdb/display/panel_display.c b/dev/gcdb/display/panel_display.c
index 1c0a82a..6ae60ae 100755
--- a/dev/gcdb/display/panel_display.c
+++ b/dev/gcdb/display/panel_display.c
@@ -148,6 +148,8 @@
 	pinfo->xres += (pinfo->border_left + pinfo->border_right);
 	pinfo->yres += (pinfo->border_top + pinfo->border_bottom);
 
+	dprintf(INFO, "panel_operating_mode=0x%x\n",
+		pstruct->paneldata->panel_operating_mode);
 	if (pstruct->paneldata->panel_operating_mode & DUAL_PIPE_FLAG)
 		pinfo->lcdc.dual_pipe = 1;
 	if (pstruct->paneldata->panel_operating_mode & PIPE_SWAP_FLAG)
@@ -156,6 +158,14 @@
 		pinfo->lcdc.split_display = 1;
 	if (pstruct->paneldata->panel_operating_mode & DST_SPLIT_FLAG)
 		pinfo->lcdc.dst_split = 1;
+	if (pstruct->paneldata->panel_operating_mode & DUAL_DSI_FLAG)
+		pinfo->mipi.dual_dsi = 1;
+	if (pstruct->paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
+		pinfo->mipi.use_dsi1_pll = 1;
+
+	dprintf(SPEW, "dual_pipe=%d pipe_swap=%d split_display=%d dst_split=%d\n",
+		pinfo->lcdc.dual_pipe, pinfo->lcdc.pipe_swap,
+		pinfo->lcdc.split_display, pinfo->lcdc.dst_split);
 
 	/* Color setting*/
 	pinfo->lcdc.border_clr = pstruct->color->border_color;
@@ -194,10 +204,6 @@
 	pinfo->mipi.vc = pstruct->paneldata->dsi_virtualchannel_id;
 	pinfo->mipi.frame_rate = pstruct->paneldata->panel_framerate;
 	pinfo->mipi.stream = pstruct->paneldata->dsi_stream;
-	if (pstruct->paneldata->panel_operating_mode & DUAL_DSI_FLAG)
-		pinfo->mipi.dual_dsi = 1;
-	if (pstruct->paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
-		pinfo->mipi.use_dsi1_pll = 1;
 	pinfo->mipi.mode_gpio_state = pstruct->paneldata->mode_gpio_state;
 	pinfo->mipi.bitclock = pstruct->paneldata->panel_bitclock_freq;
 	if (pinfo->mipi.bitclock) {
@@ -246,28 +252,34 @@
 	pinfo->fbc.comp_ratio = 1;
 
 	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		struct dsc_desc *dsc = NULL;
+		struct dsc_desc *dsc = &pinfo->dsc;
+		struct dsc_parameters *dsc_params = NULL;
 
-		pinfo->dsc.major = pstruct->dsc_paras.major;
-		pinfo->dsc.minor = pstruct->dsc_paras.minor;
-		pinfo->dsc.pps_id = pstruct->dsc_paras.pps_id;
-		pinfo->dsc.slice_height = pstruct->dsc_paras.slice_height;
-		pinfo->dsc.slice_width = pstruct->dsc_paras.slice_width;
-		pinfo->dsc.bpp = pstruct->dsc_paras.bpp;
-		pinfo->dsc.bpc = pstruct->dsc_paras.bpc;
-		pinfo->dsc.slice_per_pkt = pstruct->dsc_paras.slice_per_pkt;
-		pinfo->dsc.ich_reset_value = pstruct->dsc_paras.ich_reset_value;
-		pinfo->dsc.ich_reset_override = pstruct->dsc_paras.ich_reset_override;
-		pinfo->dsc.block_pred_enable = pstruct->dsc_paras.block_prediction;
-		pinfo->dsc.enable_422 = 0;
-		pinfo->dsc.convert_rgb = 1;
-		pinfo->dsc.vbr_enable = 0;
+		if (!pstruct->config) {
+			dprintf(CRITICAL, "ERROR: DSC cannot be used without topology_config\n");
+			return ERR_NOT_ALLOWED;
+		}
+		dsc_params = pstruct->config->dsc;
+		if (!dsc_params) {
+			dprintf(CRITICAL, "ERROR: DSC params are NULL\n");
+			return ERR_INVALID_ARGS;
+		}
 
-		dsc = &pinfo->dsc;
-		if (dsc) {
-			if (dsc->parameter_calc)
-                                dsc->parameter_calc(pinfo);
-                }
+		dsc->major = dsc_params->major;
+		dsc->minor = dsc_params->minor;
+		dsc->pps_id = dsc_params->pps_id;
+		dsc->slice_height = dsc_params->slice_height;
+		dsc->slice_width = dsc_params->slice_width;
+		dsc->bpp = dsc_params->bpp;
+		dsc->bpc = dsc_params->bpc;
+		dsc->slice_per_pkt = dsc_params->slice_per_pkt;
+		dsc->block_pred_enable = dsc_params->block_prediction;
+		dsc->enable_422 = 0;
+		dsc->convert_rgb = 1;
+		dsc->vbr_enable = 0;
+
+		if (dsc->parameter_calc)
+			dsc->parameter_calc(pinfo);
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		pinfo->fbc.enabled = pstruct->fbcinfo.enabled;
 		if (pinfo->fbc.enabled) {
diff --git a/dev/gcdb/display/panel_display.h b/dev/gcdb/display/panel_display.h
index a998fc2..ed99a98 100755
--- a/dev/gcdb/display/panel_display.h
+++ b/dev/gcdb/display/panel_display.h
@@ -53,7 +53,7 @@
 /*---------------------------------------------------------------------------*/
 /* struct definition                                                         */
 /*---------------------------------------------------------------------------*/
-struct panel_struct{
+struct panel_struct {
 	struct panel_config         *paneldata;
 	struct panel_resolution     *panelres;
 	struct color_info           *color;
@@ -65,7 +65,7 @@
 	struct panel_reset_sequence *panelresetseq;
 	struct backlight            *backlightinfo;
 	struct fb_compression	    fbcinfo;
-	struct dsc_parameters	    dsc_paras;
+	struct topology_config	    *config;
 };
 
 struct panel_list {
diff --git a/dev/pmic/pmi8994/include/pm_fg_adc_usr.h b/dev/pmic/pmi8994/include/pm_fg_adc_usr.h
index ebe249c..02ff35f 100644
--- a/dev/pmic/pmi8994/include/pm_fg_adc_usr.h
+++ b/dev/pmic/pmi8994/include/pm_fg_adc_usr.h
@@ -545,5 +545,20 @@
 */
 pm_err_flag_type pm_fg_adc_usr_get_calibrated_vbat(uint32 pmic_device, uint32 *calibrated_vbat);
 
-
+/**
+* @brief This function returns battery ADC Voltage after gain calibration*
+*  This function with fg driver's initialize and battery status checking
+* @details
+*  calibrated_value = raw_data * (1 + gain)
+*
+* @param[in] pmic_device_index  Primary: 0 Secondary: 1
+* @param[out]calibrated_vbat    Calibrated Battery Voltage
+*
+* @return  pm_err_flag_type
+*          PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
+*          version of the PMIC.
+*          PM_ERR_FLAG__SUCCESS               = SUCCESS.
+*
+*/
+pm_err_flag_type pm_fg_usr_get_vbat(uint32 pmic_device, uint32 *calibrated_vbat);
 #endif /* __PM_FG_ADC_USR_H__ */
diff --git a/dev/pmic/pmi8994/pm_fg_adc_usr.c b/dev/pmic/pmi8994/pm_fg_adc_usr.c
index e80faa0..e7f0498 100644
--- a/dev/pmic/pmi8994/pm_fg_adc_usr.c
+++ b/dev/pmic/pmi8994/pm_fg_adc_usr.c
@@ -31,6 +31,9 @@
 #include "pm_smbchg_driver.h"
 #include "pm_err_flags.h"
 #include "pm_comm.h"
+#include "pm_fg_adc_usr.h"
+#include "pm_fg_driver.h"
+#include <platform/timer.h>
 #include <sys/types.h>
 
 /*===========================================================================
@@ -41,6 +44,8 @@
 #define OFFSET_LSB_NUM        12   //Offset LSB Numerator
 #define OFFSET_LSB_DENOM      10   //Offset LSB Denominator
 #define GAIN_LSB_DENOM       400  // Gain LSB is 0.32/128 = 1/400
+#define  PM_MAX_ADC_READY_DELAY     2000
+#define  PM_MIN_ADC_READY_DELAY     1 * 1000  //1ms
 
 /*===========================================================================
                          FUNCTION DEFINITIONS
@@ -1266,3 +1271,47 @@
   return errFlag;
 }
 
+pm_err_flag_type pm_fg_usr_get_vbat(uint32 pmic_device, uint32 *calibrated_vbat)
+{
+	uint16	wait_index = 0;
+	boolean adc_reading_ready = FALSE;
+	boolean enable = FALSE;
+
+	pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
+
+	pm_fg_driver_init(pmic_device);
+
+	err_flag |= pm_fg_adc_usr_get_bcl_monitoring_sts(pmic_device, &enable);
+	if (err_flag != PM_ERR_FLAG__SUCCESS)  {
+		return err_flag;
+	} else {
+		if (enable == FALSE) {
+			err_flag |= pm_fg_adc_usr_enable_bcl_monitoring(pmic_device, TRUE);
+			if (err_flag != PM_ERR_FLAG__SUCCESS)
+				return err_flag;
+		}
+	}
+
+	//Check Vbatt ADC level
+	err_flag |= pm_fg_adc_usr_get_bcl_values(pmic_device, &adc_reading_ready); //Check if Vbatt ADC is ready
+
+	//Check if Vbatt ADC is Ready
+	for (wait_index = 0; wait_index < PM_MAX_ADC_READY_DELAY; wait_index++) {
+		if(adc_reading_ready == FALSE) {
+		udelay(PM_MIN_ADC_READY_DELAY);
+		err_flag |= pm_fg_adc_usr_get_bcl_values(pmic_device, &adc_reading_ready);
+		} else {
+			break;
+		}
+	}
+
+	if ( err_flag != PM_ERR_FLAG__SUCCESS )  {
+		return err_flag;
+	}
+
+	if (adc_reading_ready) {
+		err_flag |= pm_fg_adc_usr_get_calibrated_vbat(pmic_device, calibrated_vbat); //Read calibrated vbatt ADC
+	}
+
+	return err_flag;
+}
diff --git a/include/debug.h b/include/debug.h
index d4bce54..59e7731 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -71,7 +71,7 @@
 
 #define PANIC_UNIMPLEMENTED panic("%s unimplemented\n", __PRETTY_FUNCTION__)
 
-void * __stack_chk_guard;
+uintptr_t __stack_chk_guard;
 
 /*
 * Initialize the stack protector canary value.
diff --git a/include/dev/fbcon.h b/include/dev/fbcon.h
index e96b663..c77f02e 100644
--- a/include/dev/fbcon.h
+++ b/include/dev/fbcon.h
@@ -37,6 +37,23 @@
 #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,
+	FBCON_GREEN_MSG,
+
+	/* 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 +91,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(uint32_t type);
+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..fa606ad
--- /dev/null
+++ b/include/km_main.h
@@ -0,0 +1,208 @@
+/*
+ * 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_SECURE_WRITE_PROTECT			= (KEYMASTER_UTILS_CMD_ID + 6UL),
+
+    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;
+
+typedef enum _secure_write_prot_op_t
+{
+	SWP_READ_CONFIG,
+	SWP_WRITE_CONFIG,
+	SWP_LAST_CMD_ENTRY                    = (int)0xFFFFFFFFULL
+} secure_write_prot_op_t;
+
+/*
+	@brief
+	Data structure
+
+	@param[in]   cmd_id                   Command ID of the request
+	@param[in]   op                       Secure write protect operation (enum from secure_write_prot_op_t)
+	@param[in]   swp_write_data_offset    Offset of data for SWP operation
+	@param[in]   swp_write_data_len       Length of data for SWP operation
+*/
+
+typedef struct _secure_write_prot_req_t
+{
+	uint32 cmd_id;
+	uint32 op;
+	uint32 swp_write_data_offset;
+	uint32 swp_write_data_len;
+}__attribute__((packed)) secure_write_prot_req_t;
+
+/*
+	@brief
+	Data structure
+
+	@param[out]   status                  Status of the request
+	@param[out]   swp_read_data_offset    Offset of data for SWP operation
+	@param[out]   swp_read_data_len       Length of data for SWP operation
+*/
+
+typedef struct _secure_write_prot_rsp_t
+{
+	int status;
+	uint32 swp_read_data_offset;
+	uint32 swp_read_data_len;
+}__attribute__((packed)) secure_write_prot_rsp_t;
+
+#endif /* KM_MAIN_H */
diff --git a/include/platform.h b/include/platform.h
index 156097e..de6e544 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -65,6 +65,7 @@
 int platform_is_msm8939();
 int platform_is_msm8909();
 int platform_is_msm8992();
+int platform_is_msm8937();
 int platform_is_msm8956();
 uint32_t platform_is_msm8976_v_1_1();
 int boot_device_mask(int);
@@ -72,5 +73,10 @@
 uint32_t platform_get_max_periph();
 int platform_is_msm8996();
 bool platform_use_qmp_misc_settings();
+void set_device_unlock_value(int type, bool status);
+void get_product_name(unsigned char *buf);
+void get_bootloader_version(unsigned char *buf);
+void get_baseband_version(unsigned char *buf);
+bool is_device_locked();
 bool platform_is_mdmcalifornium();
 #endif
diff --git a/include/target.h b/include/target.h
index e05613b..1da87f1 100644
--- a/include/target.h
+++ b/include/target.h
@@ -96,4 +96,12 @@
 uint32_t get_vibration_type();
 #endif
 
+#if CHECK_BAT_VOLTAGE
+void update_battery_status(void);
+#endif
+
+uint32_t target_get_battery_voltage();
+bool target_battery_soc_ok();
+bool target_battery_is_present();
+uint32_t target_get_pmic();
 #endif
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index c135f3f..5a92c58 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -103,6 +103,7 @@
 /* GPLL */
 #define GPLL0_STATUS                       (CLK_CTL_BASE + 0x2101C)
 #define GPLL2_STATUS                       (CLK_CTL_BASE + 0x4A01C)
+#define GPLL0_MODE                         (CLK_CTL_BASE + 0x21000)
 #define APCS_GPLL_ENA_VOTE                 (CLK_CTL_BASE + 0x45000)
 #define APCS_CLOCK_BRANCH_ENA_VOTE         (CLK_CTL_BASE + 0x45004)
 #define GPLL4_MODE                         (CLK_CTL_BASE + 0x24000)
@@ -155,6 +156,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
@@ -413,9 +426,15 @@
 #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)
+#ifdef MDP_DSC_0_BASE
+#undef MDP_DSC_0_BASE
+#endif
+#define MDP_DSC_0_BASE              REG_MDP(0x81000)
 
+#ifdef MDP_DSC_1_BASE
+#undef MDP_DSC_1_BASE
+#endif
+#define MDP_DSC_1_BASE              REG_MDP(0x81400)
 
 #define SOFT_RESET                  0x118
 #define CLK_CTRL                    0x11C
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
index 3214895..df6b056 100644
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -630,6 +630,12 @@
 	sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_8976_v_1_1;
 }
 
+void msm8937_clock_override()
+{
+	gpll0_clk_src.status_reg = (void *)GPLL0_MODE;
+	gpll0_clk_src.status_mask = BIT(30);
+}
+
 void platform_clock_init(void)
 {
 	if (platform_is_msm8956()) {
@@ -638,5 +644,9 @@
 			/*freq and GPLL change for 8976 v1.1 */
 			msm8976_v_1_1_sdcc_clock_modify();
 	}
+
+	if (platform_is_msm8937())
+		msm8937_clock_override();
+
 	clk_init(msm_clocks_8952, ARRAY_SIZE(msm_clocks_8952));
 }
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
index 8adaf4c..e3e8948 100644
--- a/platform/msm8952/platform.c
+++ b/platform/msm8952/platform.c
@@ -62,12 +62,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)
@@ -176,6 +177,24 @@
 	return 256;
 }
 
+int platform_is_msm8937()
+{
+	uint32_t platform = board_platform_id();
+	uint32_t ret = 0;
+
+	switch(platform)
+	{
+		case MSM8937:
+		case APQ8037:
+			ret = 1;
+			break;
+		default:
+			ret = 0;
+		};
+
+	return ret;
+}
+
 int platform_is_msm8956()
 {
 	uint32_t platform = board_platform_id();
diff --git a/platform/msm8994/include/platform/iomap.h b/platform/msm8994/include/platform/iomap.h
index 345ce1d..123f140 100644
--- a/platform/msm8994/include/platform/iomap.h
+++ b/platform/msm8994/include/platform/iomap.h
@@ -230,6 +230,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 265d7c7..50d2542 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -220,8 +220,8 @@
 #define DSI0_REGULATOR_BASE         (0x994000)
 #define DSI1_REGULATOR_BASE         (0x996000)
 
-#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE  0x0160
-#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0168
+#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE  0x0D0
+#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0D4
 
 #define MDP_BASE                    (0x900000)
 #define REG_MDP(off)                (MDP_BASE + (off))
@@ -236,8 +236,15 @@
 #endif
 #define MDP_PP_1_BASE               REG_MDP(0x71800)
 
-#define MDP_DSC_0_BASE			REG_MDP(0x81000)
-#define MDP_DSC_1_BASE			REG_MDP(0x81400)
+#ifdef MDP_DSC_0_BASE
+#undef MDP_DSC_0_BASE
+#endif
+#define MDP_DSC_0_BASE              REG_MDP(0x81000)
+
+#ifdef MDP_DSC_1_BASE
+#undef MDP_DSC_1_BASE
+#endif
+#define MDP_DSC_1_BASE              REG_MDP(0x81400)
 
 #ifdef MDP_HW_REV
 #undef MDP_HW_REV
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index b167d70..953e892 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,6 +41,9 @@
 #include <string.h>
 #include <openssl/err.h>
 #include <platform.h>
+#include <qseecom_lk_api.h>
+#include <secapp_loader.h>
+#include <target.h>
 
 #define ASN1_ENCODED_SHA256_SIZE 0x33
 #define ASN1_ENCODED_SHA256_OFFSET 0x13
@@ -48,13 +53,9 @@
 static KEYSTORE *user_keystore;
 static uint32_t dev_boot_state = RED;
 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),
@@ -229,6 +230,7 @@
 	int shift_bytes;
 	RSA *rsa = NULL;
 	bool keystore_verification = false;
+	EVP_PKEY* key = NULL;
 
 	if(!strcmp(pname, "keystore"))
 		keystore_verification = true;
@@ -267,23 +269,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;
 }
 
@@ -335,80 +382,126 @@
 	}
 }
 
-static int read_user_keystore_ptn(uint8_t *keystore_buf)
-{
-	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;
-	}
-
-	if (len > ASN1_SIGNATURE_BUFFER_SZ)
-	{
-		dprintf(CRITICAL, "boot_verifier: user keystore exceeds size signature buffer\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()
 {
-	uint8_t *keystore_buf = NULL;
-
 	/* Read OEM Keystore */
 	read_oem_keystore();
 
-	keystore_buf = memalign(ASN1_SIGNATURE_BUFFER_SZ, CACHE_LINE);
-	ASSERT(keystore_buf);
-
-	/* Read User Keystore */
-	if(!read_user_keystore_ptn(keystore_buf))
-		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 = 0;
@@ -430,7 +523,13 @@
 
 	if(!sig_len)
 	{
-		dprintf(CRITICAL, "boot_verifier: Error while reading singature length.\n");
+		dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
+		ASSERT(0);
+	}
+
+	if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
+	{
+		dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
 		goto verify_image_error;
 	}
 
@@ -444,17 +543,21 @@
 	{
 		dprintf(CRITICAL,
 				"boot_verifier: verification failure due to target name mismatch\n");
-		goto verify_image_error;
+		ASSERT(0);
+	}
+
+	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:
-	free(signature);
 	if(sig != NULL)
 		VERIFIED_BOOT_SIG_free(sig);
-	if(!ret)
-		boot_verify_send_event(BOOT_VERIFICATION_FAIL);
+verify_image_error:
+	free(signature);
 	return ret;
 }
 
@@ -465,11 +568,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;
@@ -545,11 +651,6 @@
 	return false;
 }
 
-bool boot_verify_flash_allowed(const char * entry)
-{
-	return check_list(VERIFIED_FLASH_ALLOWED_PTN, entry);
-}
-
 KEYSTORE *boot_gerity_get_oem_keystore()
 {
 	read_oem_keystore();
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
new file mode 100644
index 0000000..bb988df
--- /dev/null
+++ b/platform/msm_shared/display_menu.c
@@ -0,0 +1,426 @@
+/* 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>
+#include <smem.h>
+#include <target.h>
+#include <sys/types.h>
+#include <../../../app/aboot/devinfo.h>
+
+static const 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";
+
+#define YELLOW_WARNING_MSG	"Your device has loaded a diffrent operating "\
+				"system\n\nTo learn more, visit:\n"
+
+#define ORANGE_WARNING_MSG	"Your device has been unlocker and cann't "\
+				"be trusted\n\nTo learn more, visit:\n"
+
+#define 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;
+
+#if VERIFIED_BOOT
+struct boot_verify_info {
+	int msg_type;
+	const char *warning_msg;
+};
+
+struct boot_verify_info boot_verify_info[] = {
+			[DISPLAY_MENU_RED] = {FBCON_RED_MSG, RED_WARNING_MSG},
+			[DISPLAY_MENU_YELLOW] = {FBCON_YELLOW_MSG, YELLOW_WARNING_MSG},
+			[DISPLAY_MENU_ORANGE] = {FBCON_ORANGE_MSG, ORANGE_WARNING_MSG}};
+#endif
+
+static char *verify_option_menu[] = {
+		[POWEROFF] = "Power off\n",
+		[RESTART] = "Restart\n",
+		[RECOVER] = "Recovery\n",
+		[FASTBOOT] = "Fastboot\n",
+		[BACK] = "Back to previous page\n"};
+
+static char *fastboot_option_menu[] = {
+		[0] = "START\n",
+		[1] = "Restart bootloader\n",
+		[2] = "Recovery mode\n",
+		[3] = "Power off\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, int type)
+{
+	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(FBCON_COMMON_MSG);
+
+	display_fbcon_menu_message((char*)unlock_menu_common_msg,
+		FBCON_COMMON_MSG, common_factor);
+	fbcon_draw_line(FBCON_COMMON_MSG);
+	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(FBCON_COMMON_MSG);
+	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(FBCON_COMMON_MSG);
+
+	if (type == UNLOCK)
+		unlock_msg_info->msg_type = DISPLAY_MENU_UNLOCK;
+	else if (type == UNLOCK_CRITICAL)
+		unlock_msg_info->msg_type = DISPLAY_MENU_UNLOCK_CRITICAL;
+
+	unlock_msg_info->option_num = 2;
+}
+
+#if VERIFIED_BOOT
+void display_boot_verified_menu(struct select_msg_info *msg_info, int type)
+{
+	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));
+
+	/* 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(boot_verify_info[type].warning_msg != NULL)
+		display_fbcon_menu_message((char*)boot_verify_info[type].warning_msg,
+			FBCON_COMMON_MSG, common_factor);
+
+	display_fbcon_menu_message("g.co/placeholder\n",
+		boot_verify_info[type].msg_type, common_factor);
+
+	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);
+	}
+
+	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);
+	}
+}
+#endif
+
+void display_boot_verified_option(struct select_msg_info *msg_info)
+{
+	int i = 0;
+	int len = 0;
+	fbcon_clear();
+	memset(msg_info, 0, sizeof(struct select_msg_info));
+
+	len = ARRAY_SIZE(verify_option_menu);
+	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 < len; i++) {
+		fbcon_draw_line(FBCON_COMMON_MSG);
+		msg_info->option_start[i] = fbcon_get_current_line();
+		display_fbcon_menu_message(verify_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(FBCON_COMMON_MSG);
+	msg_info->msg_type = DISPLAY_MENU_MORE_OPTION;
+	msg_info->option_num = len;
+}
+
+void display_fastboot_menu(struct select_msg_info *fastboot_msg_info,
+	int option_index)
+{
+	int len;
+	int msg_type = FBCON_COMMON_MSG;
+	char msg_buf[64];
+	char msg[128];
+
+	fbcon_clear();
+	memset(fastboot_msg_info, 0, sizeof(struct select_msg_info));
+
+	len = ARRAY_SIZE(fastboot_option_menu);
+	switch(option_index) {
+		case 0:
+			msg_type = FBCON_GREEN_MSG;
+			break;
+		case 1:
+		case 2:
+			msg_type = FBCON_RED_MSG;
+			break;
+		case 3:
+			msg_type = FBCON_COMMON_MSG;
+			break;
+	}
+	fbcon_draw_line(msg_type);
+	display_fbcon_menu_message(fastboot_option_menu[option_index],
+		msg_type, big_factor);
+	fbcon_draw_line(msg_type);
+	display_fbcon_menu_message("\n\nPress volume key to select, and "\
+		"press power key to select\n\n", FBCON_COMMON_MSG, common_factor);
+
+	display_fbcon_menu_message("FASTBOOT MODE\n", FBCON_RED_MSG, common_factor);
+
+	get_product_name((unsigned char *) msg_buf);
+	snprintf(msg, sizeof(msg), "PRODUCT_NAME - %s\n", msg_buf);
+	display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor);
+
+	memset(msg_buf, 0, sizeof(msg_buf));
+	smem_get_hw_platform_name((unsigned char *) msg_buf, sizeof(msg_buf));
+	snprintf(msg, sizeof(msg), "VARIANT - %s %s\n",
+		msg_buf, target_is_emmc_boot()? "eMMC":"UFS");
+	display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor);
+
+	memset(msg_buf, 0, sizeof(msg_buf));
+	get_bootloader_version((unsigned char *) msg_buf);
+	snprintf(msg, sizeof(msg), "BOOTLOADER VERSION - %s\n",
+		msg_buf);
+	display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor);
+
+	memset(msg_buf, 0, sizeof(msg_buf));
+	get_baseband_version((unsigned char *) msg_buf);
+	snprintf(msg, sizeof(msg), "BASEBAND VERSION - %s\n",
+		msg_buf);
+	display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor);
+
+	memset(msg_buf, 0, sizeof(msg_buf));
+	target_serialno((unsigned char *) msg_buf);
+	snprintf(msg, sizeof(msg), "SERIAL NUMBER - %s\n", msg_buf);
+	display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor);
+
+	snprintf(msg, sizeof(msg), "SECURE BOOT - %s\n",
+		is_secure_boot_enable()? "enabled":"disabled");
+	display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor);
+
+	snprintf(msg, sizeof(msg), "DEVICE STATE - %s\n",
+		is_device_locked()? "locked":"unlocked");
+	display_fbcon_menu_message(msg, FBCON_RED_MSG, common_factor);
+
+	fastboot_msg_info->msg_type = DISPLAY_MENU_FASTBOOT;
+	fastboot_msg_info->option_num = len;
+}
+
+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_unlock_menu_thread(int type)
+{
+	struct select_msg_info *unlock_menu_msg_info;
+	unlock_menu_msg_info = &msg_info;
+
+	set_message_factor();
+	display_unlock_menu(unlock_menu_msg_info, type);
+
+	dprintf(INFO, "creating unlock keys detect thread\n");
+	display_menu_thread_start(unlock_menu_msg_info);
+}
+
+void display_fastboot_menu_thread()
+{
+	struct select_msg_info *fastboot_menu_msg_info;
+	fastboot_menu_msg_info = &msg_info;
+
+	set_message_factor();
+	display_fastboot_menu(fastboot_menu_msg_info, 0);
+
+	dprintf(INFO, "creating fastboot menu keys detect thread\n");
+	display_menu_thread_start(fastboot_menu_msg_info);
+}
+
+#if VERIFIED_BOOT
+void display_bootverify_menu_thread(int type)
+{
+	struct select_msg_info *bootverify_menu_msg_info;
+	bootverify_menu_msg_info = &msg_info;
+
+	set_message_factor();
+	display_boot_verified_menu(bootverify_menu_msg_info, type);
+
+	dprintf(INFO, "creating boot verify keys detect thread\n");
+	display_menu_thread_start(bootverify_menu_msg_info);
+}
+#endif
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index 3b6d649..c40a435 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,
 };
 
@@ -156,8 +173,9 @@
 void boot_verify_print_state();
 /* Function to validate keystore */
 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);
 bool boot_verify_compare_sha256(unsigned char *image_ptr,
 		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa);
 KEYSTORE *boot_gerity_get_oem_keystore();
diff --git a/platform/msm_shared/include/display_menu.h b/platform/msm_shared/include/display_menu.h
new file mode 100644
index 0000000..b6167e4
--- /dev/null
+++ b/platform/msm_shared/include/display_menu.h
@@ -0,0 +1,66 @@
+/* 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,
+	DISPLAY_MENU_FASTBOOT,
+	DISPLAY_MENU_UNLOCK_CRITICAL,
+};
+
+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;
+};
+
+void wait_for_users_action(void);
+void display_unlock_menu(struct select_msg_info *msg_info, int type);
+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_fastboot_menu(struct select_msg_info *fastboot_msg_info,
+	int option_index);
+void display_bootverify_menu_thread(int type);
+void display_fastboot_menu_thread();
+void display_unlock_menu_thread(int type);
+#endif				/* __PLATFORM_MSM_SHARED_DISPLAY_MENU_H */
diff --git a/platform/msm_shared/include/mdp5.h b/platform/msm_shared/include/mdp5.h
index 9253548..5a61f17 100644
--- a/platform/msm_shared/include/mdp5.h
+++ b/platform/msm_shared/include/mdp5.h
@@ -118,6 +118,9 @@
 #define MDP_PP_0_BASE                           REG_MDP(0x12D00)
 #define MDP_PP_1_BASE                           REG_MDP(0x12E00)
 
+#define MDP_DSC_0_BASE                          REG_MDP(0x81000)
+#define MDP_DSC_1_BASE                          REG_MDP(0x81400)
+
 #define CTL_LAYER_0                             0x00
 #define CTL_LAYER_1                             0x04
 #define CTL_TOP                                 0x14
@@ -251,6 +254,8 @@
 void mdss_dsc_parameters_calc(struct msm_panel_info *pinfo);
 int mdss_dsc_to_buf(struct msm_panel_info *pinfo);
 void mdss_dsc_dsi_config(uint32_t ctl_base, int mode, struct dsc_desc *dsc);
-void mdss_dsc_mdp_config(struct msm_panel_info *pinfo);
+void mdss_dsc_mdp_config(struct msm_panel_info *pinfo,
+	unsigned int pp_base, unsigned int dsc_base,
+	bool mux, bool split_mode);
 
 #endif
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..85bd44e
--- /dev/null
+++ b/platform/msm_shared/include/menu_keys_detect.h
@@ -0,0 +1,57 @@
+/* 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,
+	FASTBOOT_PAGE,
+};
+
+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/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index f918876..7066311 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <stdint.h>
 #include <dev/fbcon.h>
+#include <sys/types.h>
 
 #define DFPS_MAX_FRAME_RATE 10
 #define DFPS_PLL_CODES_SIZE 0x1000 /* One page */
@@ -132,9 +133,6 @@
 struct msm_panel_info;
 
 struct dsc_desc {
-	int data_path_model;            /* multiplex + split_panel */
-	int ich_reset_value;
-	int ich_reset_override;
 	int initial_lines;
 	int slice_last_group_size;
 	int bpp;        /* target bit per pixel */
@@ -197,8 +195,9 @@
 	void (*parameter_calc) (struct msm_panel_info *pinfo);
 	int (*dsc2buf) (struct msm_panel_info *pinfo);
 	void (*dsi_dsc_config) (uint32_t base, int mode, struct dsc_desc *dsc);
-	void (*mdp_dsc_config) (struct msm_panel_info *pinfo);
-
+	void (*mdp_dsc_config) (struct msm_panel_info *pinfo,
+		unsigned int pp_base, unsigned int dsc_base,
+		bool mux, bool split_mode);
 };
 
 struct fbc_panel_info {
@@ -395,6 +394,9 @@
 	uint32_t border_left;
 	uint32_t border_right;
 
+	int lm_split[2];
+	int num_dsc_enc;
+
 	struct lcd_panel_info lcd;
 	struct lcdc_panel_info lcdc;
 	struct fbc_panel_info fbc;
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index f954dfb..265a0d6 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,
@@ -119,6 +97,23 @@
 	uint32_t dev_type;
 };
 
+/* Secure Write Protect Info Entry structure */
+typedef struct
+{
+	uint8_t  wp_enable;    /* UFS: WPF (Write Protect Flag), eMMC: SECURE_WP_MODE_ENABLE */
+	uint8_t  wp_type_mask; /* UFS: WPT (Write Protect Type), eMMC: SECURE_WP_MODE_CONFIG */
+	uint64_t addr;         /* UFS: LBA, eMMC: 0x1/0x2 (address of the device config register) */
+	uint32_t num_blocks;   /* UFS: Num LBA, eMMC: Set to 0 */
+} __attribute__ ((packed)) qsee_stor_secure_wp_info_entry_t;
+
+/* Secure Write Protect Info structure */
+typedef struct
+{
+	uint8_t                          lun_number;    /* UFS: LUN #, eMMC: Set to 0 */
+	uint8_t                          num_entries;   /* Number of Secure wp entries */
+	qsee_stor_secure_wp_info_entry_t wp_entries[4]; /* Max 4 entries total */
+} __attribute__ ((packed)) qsee_stor_secure_wp_info_t;
+
 /* dump a given RPMB frame */
 static inline void dump_rpmb_frame(uint8_t *frame, const char *frame_type)
 {
@@ -158,8 +153,6 @@
 int rpmb_write(uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len);
 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();
+/* RPMB API to set secure write protect configuration block */
+int swp_write(qsee_stor_secure_wp_info_t swp_cb);
 #endif
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index 0bd7eda..2d454ed 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -400,7 +400,7 @@
 int restore_secure_cfg(uint32_t id);
 
 void scm_elexec_call(paddr_t kernel_entry, paddr_t dtb_offset);
-void *get_canary();
+uintptr_t get_canary();
 /* API to configure XPU violations as fatal */
 int scm_xpu_err_fatal_init();
 
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/mdp5.c b/platform/msm_shared/mdp5.c
index 901f42e..19317ac 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -93,10 +93,12 @@
 
 	/* return MMSS_MDP_PPB0_CONFIG offset from MDSS base */
 	if ((mdss_mdp_rev == MDSS_MDP_HW_REV_108) ||
-		(mdss_mdp_rev == MDSS_MDP_HW_REV_111))
+	    (mdss_mdp_rev == MDSS_MDP_HW_REV_111))
 		mdss_mdp_ppb_off = 0x1420;
 	else if (mdss_mdp_rev == MDSS_MDP_HW_REV_110)
 		mdss_mdp_ppb_off = 0x1334;
+	else if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
+		mdss_mdp_ppb_off = 0x1330;
 	else
 		dprintf(CRITICAL,"Invalid PPB0_CONFIG offset\n");
 
@@ -219,7 +221,7 @@
 static void mdss_source_pipe_config(struct fbcon_config *fb, struct msm_panel_info
 		*pinfo, uint32_t pipe_base)
 {
-	uint32_t src_size, out_size, stride;
+	uint32_t img_size, out_size, stride;
 	uint32_t fb_off = 0;
 	uint32_t flip_bits = 0;
 	uint32_t src_xy = 0, dst_xy = 0;
@@ -229,14 +231,17 @@
 	width = fb->width - pinfo->border_left - pinfo->border_right;
 
 	/* write active region size*/
-	src_size = (height << 16) + width;
-	out_size = src_size;
+	img_size = (height << 16) | width;
+	out_size = img_size;
 	if (pinfo->lcdc.dual_pipe) {
-		out_size = (height << 16) + (width / 2);
 		if ((pipe_base == MDP_VP_0_RGB_1_BASE) ||
-			(pipe_base == MDP_VP_0_DMA_1_BASE) ||
-			(pipe_base == MDP_VP_0_VIG_1_BASE))
+		    (pipe_base == MDP_VP_0_DMA_1_BASE) ||
+		    (pipe_base == MDP_VP_0_VIG_1_BASE)) {
 			fb_off = (pinfo->xres / 2);
+			out_size = (height << 16) + (pinfo->lm_split[1]);
+		} else {
+			out_size = (height << 16) + (pinfo->lm_split[0]);
+		}
 	}
 
 	stride = (fb->stride * fb->bpp/8);
@@ -253,7 +258,7 @@
 			 __func__, out_size, fb_off, src_xy, dst_xy);
 	writel((uint32_t) fb->base, pipe_base + PIPE_SSPP_SRC0_ADDR);
 	writel(stride, pipe_base + PIPE_SSPP_SRC_YSTRIDE);
-	writel(src_size, pipe_base + PIPE_SSPP_SRC_IMG_SIZE);
+	writel(img_size, pipe_base + PIPE_SSPP_SRC_IMG_SIZE);
 	writel(out_size, pipe_base + PIPE_SSPP_SRC_SIZE);
 	writel(out_size, pipe_base + PIPE_SSPP_SRC_OUT_SIZE);
 	writel(src_xy, pipe_base + PIPE_SSPP_SRC_XY);
@@ -443,7 +448,7 @@
 
 	/* Each pipe driving half the screen */
 	if (pinfo->lcdc.dual_pipe)
-		xres /= 2;
+		xres = pinfo->lm_split[0];
 
 	/* bpp = bytes per pixel of input image */
 	smp_cnt = (xres * bpp * 2) + smp_size - 1;
@@ -460,6 +465,11 @@
 	writel(smp_cnt * 0xc0, left_pipe + REQPRIORITY_FIFO_WATERMARK2);
 
 	if (pinfo->lcdc.dual_pipe) {
+		xres = pinfo->lm_split[1];
+
+		smp_cnt = (xres * bpp * 2) + smp_size - 1;
+		smp_cnt /= smp_size;
+
 		writel(smp_cnt * 0x40, right_pipe + REQPRIORITY_FIFO_WATERMARK0);
 		writel(smp_cnt * 0x80, right_pipe + REQPRIORITY_FIFO_WATERMARK1);
 		writel(smp_cnt * 0xc0, right_pipe + REQPRIORITY_FIFO_WATERMARK2);
@@ -479,7 +489,6 @@
 	uint32_t display_hctl, hsync_ctl, display_vstart, display_vend;
 	uint32_t adjust_xres = 0;
 	uint32_t upper = 0, lower = 0;
-	struct dsc_desc *dsc = NULL;
 
 	struct lcdc_panel_info *lcdc = NULL;
 	struct intf_timing_params itp = {0};
@@ -493,7 +502,15 @@
 
 	adjust_xres = pinfo->xres;
 	if (pinfo->lcdc.split_display) {
-		adjust_xres /= 2;
+		if (pinfo->lcdc.dst_split) {
+			adjust_xres /= 2;
+		} else if(pinfo->lcdc.dual_pipe) {
+			if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))
+				adjust_xres = pinfo->lm_split[0];
+			else
+				adjust_xres = pinfo->lm_split[1];
+		}
+
 		if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) {
 			if (pinfo->lcdc.pipe_swap) {
 				lower |= BIT(4);
@@ -508,26 +525,23 @@
 		}
 	}
 
-	if (pinfo->lcdc.dst_split &&  (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))) {
+	if (pinfo->lcdc.dst_split && (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))) {
 		uint32_t ppb_offset = mdss_mdp_get_ppb_offset();
-		writel(BIT(16), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CNTL */
-		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CONFIG */
+		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CNTL */
+		writel(BIT(16) | (0x3 << 20), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CONFIG */
 	}
 
-	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		dsc = &pinfo->dsc;
-	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
+	if (pinfo->compression_mode == COMPRESSION_FBC)
 		if (!pinfo->fbc.enabled || !pinfo->fbc.comp_ratio)
 			pinfo->fbc.comp_ratio = 1;
-	}
 
 	itp.xres = (adjust_xres / pinfo->fbc.comp_ratio);
 	itp.yres = pinfo->yres;
 	itp.width =((adjust_xres + pinfo->lcdc.xres_pad) / pinfo->fbc.comp_ratio);
 
-	if (dsc) {
-		itp.xres = dsc->pclk_per_line;
-		itp.width = dsc->pclk_per_line;
+	if (pinfo->compression_mode == COMPRESSION_DSC) {
+		itp.xres = pinfo->dsc.pclk_per_line;
+		itp.width = pinfo->dsc.pclk_per_line;
 	}
 
 	itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
@@ -604,7 +618,6 @@
 	uint32_t prefetch_avail, prefetch_needed;
 	uint32_t adjust_xres = 0;
 	uint32_t fetch_enable = BIT(31);
-	struct dsc_desc *dsc;
 
 	struct lcdc_panel_info *lcdc = NULL;
 
@@ -626,12 +639,19 @@
 		return;
 
 	adjust_xres = pinfo->xres;
-	if (pinfo->lcdc.split_display)
-		adjust_xres /= 2;
+	if (pinfo->lcdc.split_display) {
+		if (pinfo->lcdc.dst_split) {
+			adjust_xres /= 2;
+		} else if(pinfo->lcdc.dual_pipe) {
+			if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))
+				adjust_xres = pinfo->lm_split[0];
+			else
+				adjust_xres = pinfo->lm_split[1];
+		}
+	}
 
 	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		dsc = &pinfo->dsc;
-		adjust_xres = dsc->pclk_per_line;
+		adjust_xres = pinfo->dsc.pclk_per_line;
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		if (pinfo->fbc.enabled && pinfo->fbc.comp_ratio)
 			adjust_xres /= pinfo->fbc.comp_ratio;
@@ -678,7 +698,7 @@
 	width = fb->width;
 
 	if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split)
-		width /= 2;
+		width = pinfo->lm_split[0];
 
 	/* write active region size*/
 	mdp_rgb_size = (height << 16) | width;
@@ -721,6 +741,9 @@
 	writel(left_staging_level, MDP_CTL_0_BASE + CTL_LAYER_0);
 
 	if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split) {
+		/* write active region size*/
+		mdp_rgb_size = (height << 16) | pinfo->lm_split[1];
+
 		writel(mdp_rgb_size, MDP_VP_0_MIXER_1_BASE + LAYER_0_OUT_SIZE);
 		writel(0x00, MDP_VP_0_MIXER_1_BASE + LAYER_0_OP_MODE);
 		writel(0x100, MDP_VP_0_MIXER_1_BASE + LAYER_0_BLEND_OP);
@@ -965,28 +988,39 @@
 
 	/* enable 3D mux for dual_pipe but single interface config */
 	if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
-		!pinfo->lcdc.split_display)
-		reg |= BIT(19) | BIT(20);
+		!pinfo->lcdc.split_display) {
+
+		if (pinfo->num_dsc_enc != 2)
+			reg |= BIT(19) | BIT(20);
+	}
 
 	writel(reg, MDP_CTL_0_BASE + CTL_TOP);
 
-	/*If dst_split is enabled only intf 2 needs to be enabled.
-	CTL_1 path should not be set since CTL_0 itself is going
-	to split after DSPP block*/
+	if ((pinfo->compression_mode == COMPRESSION_DSC) &&
+	    pinfo->dsc.mdp_dsc_config) {
+		struct dsc_desc *dsc = &pinfo->dsc;
 
-	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		struct dsc_desc *dsc = NULL;
+		if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
+		    !pinfo->lcdc.split_display && (pinfo->num_dsc_enc == 2)) {
 
-		dsc = &pinfo->dsc;
-		if (dsc) {
-			if (dsc->mdp_dsc_config)
-				dsc->mdp_dsc_config(pinfo);
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, true, true);
+			dsc->mdp_dsc_config(pinfo, MDP_PP_1_BASE,
+				MDP_DSC_1_BASE, true, true);
+		} else {
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, false, false);
 		}
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		if (pinfo->fbc.enabled)
 			mdss_fbc_cfg(pinfo);
 	}
 
+	/*
+	 * if dst_split is enabled, intf 1 & 2 needs to be enabled but
+	 * CTL_1 path should not be set since CTL_0 itself is going
+	 * to split after DSPP block and drive both intf.
+	 */
 	if (pinfo->mipi.dual_dsi) {
 		if (!pinfo->lcdc.dst_split) {
 			reg = 0x1f00 | mdss_mdp_ctl_out_sel(pinfo,0);
@@ -1108,8 +1142,8 @@
 
 	if (pinfo->lcdc.dst_split) {
 		uint32_t ppb_offset = mdss_mdp_get_ppb_offset();
-		writel(BIT(16) | BIT(20) | BIT(21), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CNTL */
-		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CONFIG */
+		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CNTL */
+		writel(BIT(16) | (0x3 << 20), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CONFIG */
 	}
 
 	mdp_clk_gating_ctrl();
@@ -1134,15 +1168,31 @@
 
 	writel(0x213F, MDP_PANEL_FORMAT + intf_base);
 	reg = 0x21f00 | mdss_mdp_ctl_out_sel(pinfo, 1);
+
+	/* enable 3D mux for dual_pipe but single interface config */
+	if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
+		!pinfo->lcdc.split_display) {
+
+		if (pinfo->num_dsc_enc != 2)
+			reg |= BIT(19) | BIT(20);
+	}
+
 	writel(reg, MDP_CTL_0_BASE + CTL_TOP);
 
-	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		struct dsc_desc *dsc = NULL;
+	if ((pinfo->compression_mode == COMPRESSION_DSC) &&
+	    pinfo->dsc.mdp_dsc_config) {
+		struct dsc_desc *dsc = &pinfo->dsc;
 
-		dsc = &pinfo->dsc;
-		if (dsc) {
-			if (dsc->mdp_dsc_config)
-				dsc->mdp_dsc_config(pinfo);
+		if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
+		    !pinfo->lcdc.split_display && (pinfo->num_dsc_enc == 2)) {
+
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, true, true);
+			dsc->mdp_dsc_config(pinfo, MDP_PP_1_BASE,
+				MDP_DSC_1_BASE, true, true);
+		} else {
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, false, false);
 		}
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		if (pinfo->fbc.enabled)
diff --git a/platform/msm_shared/menu_keys_detect.c b/platform/msm_shared/menu_keys_detect.c
new file mode 100644
index 0000000..28766a7
--- /dev/null
+++ b/platform/msm_shared/menu_keys_detect.c
@@ -0,0 +1,389 @@
+/* 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 <reboot.h>
+#include <../../../app/aboot/recovery.h>
+#include <../../../app/aboot/devinfo.h>
+
+#define KEY_DETECT_FREQUENCY		50
+#define KEY_PRESS_TIMEOUT		5000
+
+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, int type)
+{
+	if (reason == RECOVER) {
+		if (type == DISPLAY_MENU_UNLOCK) {
+			set_device_unlock_value(UNLOCK, TRUE);
+		} else if (type == DISPLAY_MENU_UNLOCK_CRITICAL) {
+			set_device_unlock_value(UNLOCK_CRITICAL, TRUE);
+		}
+
+		if (type == DISPLAY_MENU_UNLOCK ||
+			type == DISPLAY_MENU_UNLOCK_CRITICAL) {
+			/* 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, msg_info->msg_type);
+	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){
+	msg_info->msg_power_key_pressed = true;
+	update_device_status(CONTINUE, msg_info->msg_type);
+	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, msg_info->msg_type);
+	}
+	return option_index;
+}
+
+static uint32_t fastboot_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--;
+	}
+
+	display_fastboot_menu(msg_info, option_index);
+
+	return option_index;
+}
+
+static uint32_t fastboot_volume_down_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	option_index++;
+	if (option_index > msg_info->option_num)
+		option_index = 1;
+	if (option_index == msg_info->option_num)
+		option_index = 0;
+
+	display_fastboot_menu(msg_info, option_index);
+
+	return option_index;
+}
+
+/* update device's status via select option */
+static uint32_t fastboot_power_key_func (struct select_msg_info* msg_info,
+	uint32_t option_index)
+{
+	int device_state[] = {RESTART, FASTBOOT, RECOVER, POWEROFF};
+
+	if(option_index < sizeof(device_state)) {
+		update_device_status(device_state[option_index], msg_info->msg_type);
+	} else {
+		dprintf(CRITICAL, "ERRPR: option index is overflow!!!\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+/* 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,
+	},
+	[FASTBOOT_PAGE] = {
+		fastboot_volume_up_func,
+		fastboot_volume_down_func,
+		fastboot_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:
+		case DISPLAY_MENU_UNLOCK_CRITICAL:
+			current_page_index = UNLOCK_PAGE;
+			break;
+		case DISPLAY_MENU_MORE_OPTION:
+			current_page_index = BOOT_VERIFY_PAGE2;
+			break;
+		case DISPLAY_MENU_FASTBOOT:
+			current_page_index = FASTBOOT_PAGE;
+			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_dsc.c b/platform/msm_shared/mipi_dsc.c
index 33821c0..a4ee313 100644
--- a/platform/msm_shared/mipi_dsc.c
+++ b/platform/msm_shared/mipi_dsc.c
@@ -346,7 +346,9 @@
 		dsc->scale_decrement_interval);
 }
 
-void mdss_dsc_mdp_config(struct msm_panel_info *pinfo)
+void mdss_dsc_mdp_config(struct msm_panel_info *pinfo,
+	unsigned int pp_base, unsigned int dsc_base,
+	bool mux, bool split_mode)
 {
 	unsigned int data;
 	unsigned int offset, off;
@@ -359,24 +361,27 @@
 	writel(0x0, MDSS_MDP_REG_DCE_SEL);
 
 	/* dsc enable */
-	writel(1, MDP_PP_0_BASE + MDSS_MDP_PP_DSC_MODE);
+	writel(1, pp_base + MDSS_MDP_PP_DSC_MODE);
 
-	data = readl(MDP_PP_0_BASE + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
+	data = readl(pp_base + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
 	data |= BIT(18);	/* endian flip */
-	writel(data, MDP_PP_0_BASE + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
+	writel(data, pp_base + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
 
-	offset = MDP_DSC_0_BASE;
+	offset = dsc_base;
 
 	data = 0;
 	dsc = &pinfo->dsc;
 	if (pinfo->type == MIPI_VIDEO_PANEL)
 		data = BIT(2);	/* video mode */
 
+	if (split_mode)
+		data |= BIT(0);
+	if (mux)
+		data |= BIT(1);
+
 	writel(data, offset + MDSS_MDP_DSC_COMMON_MODE);
 
-	data = dsc->ich_reset_value | dsc->ich_reset_override;
-	data <<= 28;
-	data |= (dsc->initial_lines << 20);
+	data = (dsc->initial_lines << 20);
 	data |= ((dsc->slice_last_group_size - 1) << 18);
 
 	/* bpp is 6.4 format, 4 LSBs bits are for fractional part */
@@ -392,8 +397,8 @@
 	data |= (dsc->convert_rgb << 1);
 	data |= dsc->input_10_bits;
 
-	dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d %d %d, data=%x\n",
-		__func__, dsc->ich_reset_value, dsc->ich_reset_override,
+	dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d, data=%x\n",
+		__func__,
 		dsc->initial_lines , dsc->slice_last_group_size,
 		dsc->bpp, dsc->block_pred_enable, dsc->line_buf_depth,
 		dsc->enable_422, dsc->convert_rgb, dsc->input_10_bits, data);
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index 4d69497..12fb661 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -769,10 +769,12 @@
 
 	uint32_t value = ((drv_type << 4) | MMC_HS200_TIMING);
 
-	if (card->ext_csd[MMC_EXT_MMC_DRV_STRENGTH] & (1 << drv_type))
-		ret = mmc_switch_cmd(host, card, MMC_ACCESS_WRITE, MMC_EXT_MMC_HS_TIMING, value);
-	if (!ret)
-		drv_type_changed = true;
+	if (MMC_CARD_MMC(card)) {
+		if (card->ext_csd[MMC_EXT_MMC_DRV_STRENGTH] & (1 << drv_type))
+			ret = mmc_switch_cmd(host, card, MMC_ACCESS_WRITE, MMC_EXT_MMC_HS_TIMING, value);
+		if (!ret)
+			drv_type_changed = true;
+	}
 	return drv_type_changed;
 }
 /*
@@ -807,8 +809,12 @@
  */
 static uint8_t mmc_card_supports_hs400_mode(struct mmc_card *card)
 {
-	if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS400_MODE)
-		return 1;
+	if (MMC_CARD_MMC(card)) {
+		if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS400_MODE)
+			return 1;
+		else
+			return 0;
+	}
 	else
 		return 0;
 }
@@ -821,8 +827,12 @@
  */
 static uint8_t mmc_card_supports_hs200_mode(struct mmc_card *card)
 {
-	if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS200_MODE)
-		return 1;
+	if (MMC_CARD_MMC(card)) {
+		if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS200_MODE)
+			return 1;
+		else
+			return 0;
+	}
 	else
 		return 0;
 }
@@ -835,8 +845,12 @@
  */
 static uint8_t mmc_card_supports_ddr_mode(struct mmc_card *card)
 {
-	if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_DDR_MODE)
-		return 1;
+	if (MMC_CARD_MMC(card)) {
+		if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_DDR_MODE)
+			return 1;
+		else
+			return 0;
+	}
 	else
 		return 0;
 }
@@ -2189,9 +2203,9 @@
 	 * erase_timeout = 300ms * ERASE_TIMEOUT_MULT * num_erase_grps
 	 */
 	if (MMC_CARD_MMC(card))
-		erase_timeout = ((uint64_t)300 * 1000 * card->ext_csd[MMC_ERASE_TIMEOUT_MULT] * num_erase_grps);
+		erase_timeout = (300 * 1000 * card->ext_csd[MMC_ERASE_TIMEOUT_MULT] * num_erase_grps);
 	else
-		erase_timeout = ((uint64_t)300 * 1000 * num_erase_grps);
+		erase_timeout = (300 * 1000 * num_erase_grps);
 
 	/* Send CMD38 to perform erase */
 	if (mmc_send_erase(dev, erase_timeout))
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
index 8543e97..445904a 100644
--- a/platform/msm_shared/qseecom_lk.c
+++ b/platform/msm_shared/qseecom_lk.c
@@ -103,7 +103,7 @@
 	uint32_t               id;
 };
 
-static struct qseecom_reg_log_buf_ireq logbuf_req;
+static struct qseecom_reg_log_buf_ireq logbuf_req = {0};
 static struct qseecom_control qseecom;
 static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
           struct qseecom_client_listener_data_irsp *send_data_rsp);
@@ -434,6 +434,9 @@
 	struct qseecom_client_listener_data_irsp send_data_rsp = {0};
 	int ret = GENERIC_ERROR;
 	uint32_t qseos_cmd_id = 0;
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
 
 	if ((!cmd_buf) || (!resp_buf))
 			return GENERIC_ERROR;
@@ -449,7 +452,22 @@
 			ret = scm_call(svc_id, tz_cmd_id, req, cmd_len,
 					resp_buf, resp_len);
 		} else {
+			if(logbuf_req.phy_addr)
+			{
+				log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+				arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+				QseeLogStart = (uint32_t) log->log_pos.offset;
+			}
+
 			ret = qseecom_scm_call2(svc_id, tz_cmd_id, req, resp);
+			if(logbuf_req.phy_addr)
+			{
+				arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+				QseeLogNewStart = (uint32_t) log->log_pos.offset;
+				_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr,
+					QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+					QseeLogStart, QseeLogNewStart);
+			}
 		}
 
 		if (ret) {
@@ -465,8 +483,7 @@
 		switch (resp->result) {
 			case QSEOS_RESULT_SUCCESS:
 				if(((resp->resp_type != QSEOS_APP_ID) || (resp->data <= 0)) &&
-					((qseos_cmd_id == QSEE_CLIENT_SEND_DATA_COMMAND) ||
-							(qseos_cmd_id == QSEE_LISTENER_DATA_RSP_COMMAND)))
+					(qseos_cmd_id == QSEE_CLIENT_SEND_DATA_COMMAND))
 				{
 					dprintf(CRITICAL, "ERROR: Resp type %d or Resp Data %d incorrect\n",
 							resp->resp_type, resp->data);
@@ -542,9 +559,6 @@
 	void *req = NULL;
 	struct qseecom_load_app_ireq load_req = {0};
 	struct qseecom_command_scm_resp resp;
-	struct tzdbg_log_t *log = NULL;
-	uint32_t QseeLogStart = 0;
-	uint32_t QseeLogNewStart = 0;
 
 	int ret = GENERIC_ERROR;
 	uint8_t lun = 0;
@@ -591,10 +605,6 @@
 	memscpy(&load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
 	req = (void *)&load_req;
 
-	log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
-	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
-	QseeLogStart = (uint32_t) log->log_pos.offset;
-
 	arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
 	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
 				sizeof(struct qseecom_load_lib_image_ireq),
@@ -603,11 +613,6 @@
 		*app_id = resp.data;
 	else
 		*app_id = 0;
-	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
-	QseeLogNewStart = (uint32_t) log->log_pos.offset;
-
-	_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
-			QseeLogStart, QseeLogNewStart);
 err:
 	if (buf)
 		free(buf);
@@ -946,11 +951,11 @@
 		mutex_release(&qseecom.global_data_lock);
 		return ret;
 	}
+	mutex_release(&qseecom.global_data_lock);
 	/* Load commonlib image*/
 	if (!qseecom.cmnlib_loaded) {
 		ret = qseecom_load_commonlib_image("cmnlib");
 		if (ret) {
-			mutex_release(&qseecom.global_data_lock);
 			dprintf(CRITICAL, "%s qseecom_load_commonlib_image failed with status:%d\n",
 					__func__, ret);
 			goto err;
@@ -972,7 +977,7 @@
 	 * call into TZ to load it, add to list and then return
 	 * handle.
 	 */
-
+	mutex_acquire(&qseecom.global_data_lock);
 	entry = __qseecom_check_app_exists(app_name);
 	if (!entry) {
 		mutex_release(&qseecom.global_data_lock);
@@ -1027,9 +1032,6 @@
 	int ret = GENERIC_ERROR;
 	int ref_cnt = 0;
 	struct qseecom_registered_app_list *entry = NULL;
-	struct tzdbg_log_t *log = NULL;
-	uint32_t QseeLogStart = 0;
-	uint32_t QseeLogNewStart = 0;
 
 	if (handle <= 0) {
 		dprintf(CRITICAL, "%s: Invalid Handle %d\n", __func__, handle);
@@ -1063,16 +1065,7 @@
 	ref_cnt = entry->ref_cnt;
 	mutex_release(&qseecom.global_data_lock);
 	if (ref_cnt == 0) {
-		log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
-		arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
-		QseeLogStart = (uint32_t) log->log_pos.offset;
-
 		ret = qseecom_unload_app(entry->app_id);
-		arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
-		QseeLogNewStart = (uint32_t) log->log_pos.offset;
-
-		_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
-				QseeLogStart, QseeLogNewStart);
 		if(ret) {
 			dprintf(CRITICAL, "%s: qseecom_unload_app failed with err:%d for handle:%d\n",
 					__func__, ret, handle);
@@ -1122,9 +1115,6 @@
 	uint32_t app_id = 0;
 	struct qseecom_registered_app_list *entry = NULL;
 	struct qseecom_send_cmd_req req = {0, 0, 0, 0};
-	struct tzdbg_log_t *log = NULL;
-	uint32_t QseeLogStart = 0;
-	uint32_t QseeLogNewStart = 0;
 
 	if (handle <= 0) {
 		dprintf(CRITICAL, "%s Handle is Invalid\n", __func__);
@@ -1161,21 +1151,13 @@
 	req.cmd_req_buf = send_buf;
 	req.resp_buf = resp_buf;
 
-	log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
-	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
-	QseeLogStart = (uint32_t) log->log_pos.offset;
-
 	ret = __qseecom_send_cmd(app_id, &req);
 	if (ret) {
 		dprintf(CRITICAL, "%s __qseecom_send_cmd failed with err:%d for handle:%d\n",
 				__func__, ret, handle);
 		goto err;
 	}
-	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
-	QseeLogNewStart = (uint32_t) log->log_pos.offset;
 
-	_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
-			QseeLogStart, QseeLogNewStart);
 	ret = 0;
 	dprintf(SPEW, "sending cmd_req->rsp size: %u, ptr: 0x%p\n",
 			req.resp_len, req.resp_buf);
diff --git a/platform/msm_shared/reboot.c b/platform/msm_shared/reboot.c
index 6d97b0c..4c21d11 100644
--- a/platform/msm_shared/reboot.c
+++ b/platform/msm_shared/reboot.c
@@ -77,7 +77,7 @@
 	REG_WRITE(PON_SOFT_RB_SPARE, hard_restart_reason & 0x03);
 
 	/* Extract the bits 5 to 7 and return */
-	return hard_restart_reason & 0xFC;
+	return (hard_restart_reason & 0xFC) >> 2;
 }
 
 /* Return true if it is triggered by alarm. */
@@ -111,7 +111,7 @@
 
 #if USE_PON_REBOOT_REG
 	value = REG_READ(PON_SOFT_RB_SPARE);
-	value |= reboot_reason;
+	value |= (reboot_reason << 2);
 	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 bf39988..4773255 100644
--- a/platform/msm_shared/reboot.h
+++ b/platform/msm_shared/reboot.h
@@ -26,14 +26,22 @@
  * 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 RECOVERY_MODE     0x01
+#define FASTBOOT_MODE     0x02
+#define ALARM_BOOT        0x03
+#define DM_VERITY_LOGGING   0x04
+#define DM_VERITY_ENFORCING 0x05
+#define DM_VERITY_KEYSCLEAR 0x06
 #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
@@ -52,3 +60,5 @@
 
 void reboot_device(unsigned reboot_reason);
 void shutdown_device();
+
+#endif
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
index f6cb3e3..3c85b8d 100644
--- a/platform/msm_shared/rpmb/rpmb.c
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -25,18 +25,20 @@
  * 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 <platform.h>
 #include <rpmb.h>
+#include <km_main.h>
 #include <rpmb_listener.h>
 #include <mmc_sdhci.h>
 #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;
 struct rpmb_init_info info;
 
 int rpmb_init()
@@ -76,6 +78,7 @@
 		}
 		info.dev_type  = EMMC_RPMB;
 	}
+#ifdef UFS_SUPPORT
 	else
 	{
 		struct ufs_dev *ufs_dev = (struct ufs_dev *) dev;
@@ -84,15 +87,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();
@@ -102,15 +97,6 @@
 		goto err;
 	}
 
-	/* Start Qseecom */
-	ret = qseecom_tz_init();
-
-	if (ret < 0)
-	{
-		dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
-		goto err;
-	}
-
 err:
 	return ret;
 }
@@ -122,18 +108,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,26 +137,13 @@
 	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;
 
 	/* Read the device info */
 	arch_clean_invalidate_cache_range((addr_t) info, sz);
-	ret = qseecom_send_command(app_handle, (void*) &read_req, sizeof(read_req), (void*) &read_rsp, sizeof(read_rsp));
+	ret = qseecom_send_command(get_secapp_handle(), (void*) &read_req, sizeof(read_req), (void*) &read_rsp, sizeof(read_rsp));
 	arch_invalidate_cache_range((addr_t) info, sz);
 
 	if (ret < 0 || read_rsp.status < 0)
@@ -181,13 +162,13 @@
 	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;
 
 	/* Write the device info */
 	arch_clean_invalidate_cache_range((addr_t) info, sz);
-	ret = qseecom_send_command(app_handle, (void *)&write_req, sizeof(write_req), (void *)&write_rsp, sizeof(write_rsp));
+	ret = qseecom_send_command(get_secapp_handle(), (void *)&write_req, sizeof(write_req), (void *)&write_rsp, sizeof(write_rsp));
 	arch_invalidate_cache_range((addr_t) info, sz);
 
 	if (ret < 0 || write_rsp.status < 0)
@@ -199,9 +180,33 @@
 	return 0;
 }
 
-int rpmb_get_app_handle()
+/*
+ * SWP Write function is used to send a configuration block to rpmb
+ * for enabling a secure write protect based on LBAs. This function
+ * should is enabled by the keymaster secure app and this function
+ * can only be called before we send the milestone call to keymaster.
+ */
+int swp_write(qsee_stor_secure_wp_info_t swp_cb)
 {
-	return app_handle;
+	secure_write_prot_req_t *req;
+	secure_write_prot_rsp_t rsp;
+	int ret = 0;
+	uint32_t tlen = sizeof(secure_write_prot_req_t) + sizeof(swp_cb);
+	if(!(req = (secure_write_prot_req_t *) malloc(tlen)))
+		ASSERT(0);
+	void *cpy_ptr = (uint8_t *) req + sizeof(secure_write_prot_req_t);
+	req->cmd_id = KEYMASTER_SECURE_WRITE_PROTECT;
+	req->op = SWP_WRITE_CONFIG;
+	req->swp_write_data_offset = sizeof(secure_write_prot_req_t);
+	req->swp_write_data_len = sizeof(swp_cb);
+	memcpy(cpy_ptr, (void *)&swp_cb, sizeof(swp_cb));
+	ret = qseecom_send_command(get_secapp_handle(), (void *)req, tlen, (void *)&rsp, sizeof(rsp));
+	if(ret < 0 || rsp.status < 0)
+	{
+		dprintf(CRITICAL, "Setting secure write protect configuration failed\n");
+		return -1;
+	}
+	return 0;
 }
 
 int rpmb_uninit()
@@ -225,50 +230,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 b6647d8..385bc66 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 \
@@ -467,6 +477,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 \
@@ -587,6 +598,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 \
@@ -618,6 +630,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
 endif
@@ -639,7 +652,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 055030b..f9a7377 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -36,6 +36,7 @@
 #include <image_verify.h>
 #include <dload_util.h>
 #include <platform/iomap.h>
+#include <board.h>
 #include "scm.h"
 
 #pragma GCC optimize ("O0")
@@ -1071,13 +1072,13 @@
 }
 
 /* SCM Random Command */
-int scm_random(uint32_t * rbuf, uint32_t  r_len)
+int scm_random(uintptr_t * rbuf, uint32_t  r_len)
 {
 	int ret;
 	struct tz_prng_data data;
 	scmcall_arg scm_arg = {0};
 	// Memory passed to TZ should be algined to cache line
-	BUF_DMA_ALIGN(rand_buf, uint32_t);
+	BUF_DMA_ALIGN(rand_buf, sizeof(uintptr_t));
 
 	if (!is_scm_armv8_support())
 	{
@@ -1109,19 +1110,19 @@
 	}
 
 	//Copy back into the return buffer
-	memcpy(rbuf, rand_buf, r_len);
+	*rbuf = *rand_buf;
 	return ret;
 }
 
-void * get_canary()
+uintptr_t get_canary()
 {
-	void * canary;
-	if(scm_random((uint32_t *)&canary, sizeof(canary))) {
+	uintptr_t canary;
+	if(scm_random(&canary, sizeof(canary))) {
 		dprintf(CRITICAL,"scm_call for random failed !!!");
 		/*
 		* fall back to use lib rand API if scm call failed.
 		*/
-		canary =  (void *)rand();
+		canary =  rand();
 	}
 
 	return canary;
@@ -1373,6 +1374,7 @@
 bool scm_device_enter_dload()
 {
 	uint32_t ret = 0;
+	uint32_t dload_mode = 0;
 
 	scmcall_arg scm_arg = {0};
 	scmcall_ret scm_ret = {0};
@@ -1382,7 +1384,14 @@
 	if (ret)
 		dprintf(CRITICAL, "SCM call to check dload mode failed: %x\n", ret);
 
-	if (!ret && (scm_io_read(TCSR_BOOT_MISC_DETECT) == SCM_DLOAD_MODE))
+	if (!ret)
+	{
+		dload_mode = scm_io_read(TCSR_BOOT_MISC_DETECT);
+		if (board_soc_version() < 0x30000)
+			dload_mode = (dload_mode >> 16) & 0xFFFF;
+	}
+
+	if (dload_mode == SCM_DLOAD_MODE)
 		return true;
 
 	return false;
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/smem.c b/platform/msm_shared/smem.c
index 0dc3c24..9ef0c18 100644
--- a/platform/msm_shared/smem.c
+++ b/platform/msm_shared/smem.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,11 +32,30 @@
 #include <reg.h>
 #include <sys/types.h>
 #include <platform/iomap.h>
+#include <board.h>
 
 #include "smem.h"
 
 static struct smem *smem;
 
+const char *hw_platform[] = {
+	[HW_PLATFORM_UNKNOWN] = "Unknown",
+	[HW_PLATFORM_SURF] = "Surf",
+	[HW_PLATFORM_FFA] = "FFA",
+	[HW_PLATFORM_FLUID] = "Fluid",
+	[HW_PLATFORM_SVLTE] = "SVLTE",
+	[HW_PLATFORM_MTP_MDM] = "MDM_MTP_NO_DISPLAY",
+	[HW_PLATFORM_MTP] = "MTP",
+	[HW_PLATFORM_RCM] = "RCM",
+	[HW_PLATFORM_LIQUID] = "Liquid",
+	[HW_PLATFORM_DRAGON] = "Dragon",
+	[HW_PLATFORM_QRD] = "QRD",
+	[HW_PLATFORM_HRD] = "HRD",
+	[HW_PLATFORM_DTV] = "DTV",
+	[HW_PLATFORM_STP] = "STP",
+	[HW_PLATFORM_SBC] = "SBC",
+};
+
 /* DYNAMIC SMEM REGION feature enables LK to dynamically
  * read the SMEM addr info from TCSR register or IMEM location.
  * The first word read, if indicates a MAGIC number, then
@@ -170,3 +189,20 @@
 
 	return 0;
 }
+
+size_t smem_get_hw_platform_name(void *buf, uint32 buf_size)
+{
+	uint32 hw_id;
+
+	if (buf == NULL) {
+		dprintf(CRITICAL, "ERROR: buf is NULL\n");
+		return 1;
+	}
+
+	hw_id = board_hardware_id();
+	if (buf_size < strlen(hw_platform[hw_id]) + 1)
+		return 1;
+
+	return snprintf(buf, strlen(hw_platform[hw_id]) + 1,
+		"%s\n", hw_platform[hw_id]);
+}
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 312a33d..fe89eea 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -136,6 +136,9 @@
 	PMIC_IS_PM8019    = 3,
 	PMIC_IS_PM8026    = 4,
 	PMIC_IS_PM8110    = 5,
+	PMIC_IS_PM8916    = 11,
+	PMIC_IS_PM8909    = 13,
+	PMIC_IS_PMI8950   = 17,
 	PMIC_IS_PMI8994   = 10,
 	PMIC_IS_PMI8996   = 19,
 } pm_model_type_bfly;
@@ -442,6 +445,8 @@
 	MDMFERMIUM5  = 299,
 	APQ8096  = 291,
 	MSMTITANIUM  = 293,
+	MSM8937 = 294,
+	APQ8037 = 295,
 };
 
 enum platform {
@@ -667,4 +672,5 @@
 void* smem_get_alloc_entry(smem_mem_type_t type, uint32_t* size);
 uint32_t get_ddr_start();
 uint64_t smem_get_ddr_size();
+size_t smem_get_hw_platform_name(void *buf, uint32 buf_size);
 #endif				/* __PLATFORM_MSM_SHARED_SMEM_H */
diff --git a/platform/msmtitanium/include/platform/iomap.h b/platform/msmtitanium/include/platform/iomap.h
index c429f35..833520a 100755
--- a/platform/msmtitanium/include/platform/iomap.h
+++ b/platform/msmtitanium/include/platform/iomap.h
@@ -43,6 +43,7 @@
 #define RESTART_REASON_ADDR                (MSM_SHARED_IMEM_BASE + 0x65C)
 
 #define APPS_SS_BASE                       0x0B000000
+#define APPS_SS_END                        0x0B200000
 
 #define MSM_GIC_DIST_BASE                  APPS_SS_BASE
 #define MSM_GIC_CPU_BASE                   (APPS_SS_BASE + 0x2000)
@@ -143,6 +144,17 @@
 #define MSM_USB30_BASE               0x7000000
 #define USB2_PHY_SEL                0x01937000
 
+/* 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
+
 #define TCSR_TZ_WONCE               0x193D000
 #define TCSR_BOOT_MISC_DETECT       0x193D100
 
diff --git a/platform/msmtitanium/platform.c b/platform/msmtitanium/platform.c
index 6e851b1..2168570 100755
--- a/platform/msmtitanium/platform.c
+++ b/platform/msmtitanium/platform.c
@@ -40,6 +40,34 @@
 #include <boot_stats.h>
 #include <platform.h>
 
+
+#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
+#define APPS_SS_SIZE   ((APPS_SS_END - APPS_SS_BASE)/MB)
+
+/* LK memory - cacheable, write through */
+#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)
+
+/* IMEM memory - cacheable, write through */
+#define COMMON_MEMORY     (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+				MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+#define SCRATCH_MEMORY    (MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE | \
+				MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+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},
+};
+
 void platform_early_init(void)
 {
 	board_init();
@@ -72,5 +100,71 @@
 int platform_use_identity_mmu_mappings(void)
 {
 	/* Use only the mappings specified in this file. */
-	return 1;
+	return 0;
+}
+
+/* Setup MMU mapping for this platform */
+void platform_init_mmu_mappings(void)
+{
+	uint32_t i;
+	uint32_t sections;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t ddr_start = get_ddr_start();
+	uint32_t smem_addr = platform_get_smem_base_addr();
+
+	/*Mapping the ddr start address for loading the kernel about 90 MB*/
+	sections = 90;
+	while(sections--)
+	{
+		arm_mmu_map_section(ddr_start + sections * MB, ddr_start + sections* MB, COMMON_MEMORY);
+	}
+
+
+	/* Mapping the SMEM addr */
+	arm_mmu_map_section(smem_addr, smem_addr, COMMON_MEMORY);
+
+	/* Configure the MMU page entries for memory read from the
+	   mmu_section_table */
+	for (i = 0; i < table_size; i++)
+	{
+		sections = mmu_section_table[i].num_of_sections;
+
+		while (sections--)
+		{
+			arm_mmu_map_section(mmu_section_table[i].paddress +
+								sections * MB,
+								mmu_section_table[i].vaddress +
+								sections * MB,
+								mmu_section_table[i].flags);
+		}
+	}
+}
+
+addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
+{
+	/* Using 1-1 mapping on this platform. */
+	return virt_addr;
+}
+
+addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr)
+{
+	/* Using 1-1 mapping on this platform. */
+	return phys_addr;
+}
+
+/* DYNAMIC SMEM REGION feature enables LK to dynamically
+ * read the SMEM addr info from TCSR_TZ_WONCE register.
+ * The first word read, if indicates a MAGIC number, then
+ * Dynamic SMEM is assumed to be enabled. Read the remaining
+ * SMEM info for SMEM Size and Phy_addr from the other bytes.
+ */
+uint32_t platform_get_smem_base_addr()
+{
+	struct smem_addr_info *smem_info = NULL;
+
+	smem_info = (struct smem_addr_info *)readl(TCSR_TZ_WONCE);
+	if(smem_info && (smem_info->identifier == SMEM_TARGET_INFO_IDENTIFIER))
+		return smem_info->phy_addr;
+	else
+		return MSM_SHARED_BASE;
 }
diff --git a/platform/msmtitanium/rules.mk b/platform/msmtitanium/rules.mk
index 2734fb6..96b14d5 100755
--- a/platform/msmtitanium/rules.mk
+++ b/platform/msmtitanium/rules.mk
@@ -7,9 +7,11 @@
 
 DEFINES += ARM_CPU_CORE_A7
 DEFINES += ARM_CORE_V8
+MMC_SLOT         := 1
 
 DEFINES += PERIPH_BLK_BLSP=1
-DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0
+DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
+           MMC_SLOT=$(MMC_SLOT) SSD_ENABLE
 
 INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include
 
diff --git a/project/msm8909.mk b/project/msm8909.mk
index b7094e6..cb08003 100644
--- a/project/msm8909.mk
+++ b/project/msm8909.mk
@@ -74,3 +74,6 @@
 ENABLE_REBOOT_MODULE := 1
 #Use PON register for reboot reason
 DEFINES += USE_PON_REBOOT_REG=1
+
+#enable battery voltage check
+DEFINES += CHECK_BAT_VOLTAGE=1
diff --git a/project/msm8916.mk b/project/msm8916.mk
index 0edff28..2ac68fb 100644
--- a/project/msm8916.mk
+++ b/project/msm8916.mk
@@ -60,3 +60,6 @@
 ENABLE_REBOOT_MODULE := 1
 #Use PON register for reboot reason
 DEFINES += USE_PON_REBOOT_REG=1
+
+#enable battery voltage check
+DEFINES += CHECK_BAT_VOLTAGE=1
diff --git a/project/msm8952.mk b/project/msm8952.mk
index 7fbfae6..bb2ef5d 100644
--- a/project/msm8952.mk
+++ b/project/msm8952.mk
@@ -14,6 +14,21 @@
 
 EMMC_BOOT := 1
 
+
+ifeq ($(VERIFIED_BOOT),1)
+ENABLE_MDTP_SUPPORT := 1
+ifeq ($(ENABLE_VBOOT_MOTA_SUPPORT),1)
+DEFINES += VBOOT_MOTA=1
+else
+ENABLE_SECAPP_LOADER := 1
+ENABLE_RPMB_SUPPORT := 1
+#enable fbcon display menu
+ENABLE_FBCON_DISPLAY_MSG := 1
+endif
+endif
+
+
+
 ENABLE_SMD_SUPPORT := 1
 #ENABLE_PWM_SUPPORT := true
 
@@ -32,6 +47,10 @@
 #Enable the feature of long press power on
 DEFINES += LONG_PRESS_POWER_ON=1
 
+ifeq ($(ENABLE_RPMB_SUPPORT),1)
+DEFINES += USE_RPMB_FOR_DEVINFO=1
+endif
+
 #Disable thumb mode
 ENABLE_THUMB := false
 
@@ -41,6 +60,12 @@
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
 
+
+
+ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
+DEFINES += FBCON_DISPLAY_MSG=1
+endif
+
 #enable power on vibrator feature
 ENABLE_HAP_VIB_SUPPORT := true
 
@@ -60,7 +85,6 @@
 DEFINES += SMD_SUPPORT=1
 endif
 
-ENABLE_MDTP_SUPPORT := 1
 
 ifeq ($(ENABLE_MDTP_SUPPORT),1)
 DEFINES += MDTP_SUPPORT=1
@@ -77,3 +101,6 @@
 CFLAGS += -Werror
 
 DEFINES += USE_TARGET_HS200_DELAY=1
+
+#enable battery voltage check
+DEFINES += CHECK_BAT_VOLTAGE=1
diff --git a/project/msm8994.mk b/project/msm8994.mk
index 89a9a65..6a586b7 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
@@ -69,3 +79,6 @@
 
 # Turn on Werror
 CFLAGS += -Werror
+
+#enable battery voltage check
+DEFINES += CHECK_BAT_VOLTAGE=1
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 368dc99..dae1bc9 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
@@ -56,6 +57,13 @@
 #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_HAP_VIB_SUPPORT),true)
 DEFINES += PON_VIB_SUPPORT=1
 endif
@@ -84,6 +92,8 @@
 DEFINES += ENABLE_PARTIAL_GOODS_SUPPORT=1
 endif
 
+ENABLE_MDTP_SUPPORT := 1
+
 ifeq ($(ENABLE_MDTP_SUPPORT),1)
 DEFINES += MDTP_SUPPORT=1
 endif
@@ -94,6 +104,9 @@
 
 CFLAGS += -Werror
 
+#enable user force reset feature
+DEFINES += USER_FORCE_RESET_SUPPORT=1
+
 #SCM call before entering DLOAD mode
 DEFINES += PLATFORM_USE_SCM_DLOAD=1
 
@@ -105,9 +118,11 @@
 DEFINES += PLATFORM_USE_QMP_MISC=1
 #Use PON register for reboot reason
 DEFINES += USE_PON_REBOOT_REG=1
+
+#enable battery voltage check
+DEFINES += CHECK_BAT_VOLTAGE=1
 # Enable unit test FW
 ENABLE_UNITTEST_FW=1
 ifeq ($(ENABLE_UNITTEST_FW),1)
 DEFINES += UNITTEST_FW_SUPPORT=1
 endif
-
diff --git a/project/msmtitanium.mk b/project/msmtitanium.mk
index fd4c29b..d1449a5 100755
--- a/project/msmtitanium.mk
+++ b/project/msmtitanium.mk
@@ -13,6 +13,7 @@
 endif
 
 EMMC_BOOT := 1
+ENABLE_SECAPP_LOADER := 1
 
 ENABLE_SMD_SUPPORT := 1
 #ENABLE_PWM_SUPPORT := true
@@ -69,4 +70,4 @@
 DEFINES += USE_TARGET_HS200_DELAY=1
 
 #Enable the external reboot functions
-#ENABLE_REBOOT_MODULE := 1
+ENABLE_REBOOT_MODULE := 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/init.c b/target/init.c
index 6eba00e..1d67c69 100644
--- a/target/init.c
+++ b/target/init.c
@@ -34,8 +34,21 @@
 #include <board.h>
 #endif
 
+#include <smem.h>
+#include <pm8x41_adc.h>
+#include <pm8x41_hw.h>
+
+#if CHECK_BAT_VOLTAGE
+#include <pm_fg_adc_usr.h>
+#endif
+
 #define EXPAND(NAME) #NAME
 #define TARGET(NAME) EXPAND(NAME)
+
+#define BATTERY_MIN_VOLTAGE		3200000  //uv
+#define PMIC_SLAVE_ID                   0x20000
+#define BAT_IF_BAT_PRES_STATUS		0x1208
+
 /*
  * default implementations of these routines, if the target code
  * chooses not to implement.
@@ -268,3 +281,91 @@
 	return false;
 #endif
 }
+
+__WEAK uint32_t target_get_pmic()
+{
+	return PMIC_IS_UNKNOWN;
+}
+
+/* Check battery if it's exist */
+bool target_battery_is_present()
+{
+	bool batt_is_exist;
+	uint8_t value = 0;
+	uint32_t pmic;
+
+	pmic = target_get_pmic();
+
+	switch(pmic)
+	{
+		case PMIC_IS_PM8909:
+		case PMIC_IS_PM8916:
+		case PMIC_IS_PM8941:
+			value = REG_READ(BAT_IF_BAT_PRES_STATUS);
+			break;
+		case PMIC_IS_PMI8950:
+		case PMIC_IS_PMI8994:
+		case PMIC_IS_PMI8996:
+			value = REG_READ(PMIC_SLAVE_ID|
+			BAT_IF_BAT_PRES_STATUS);
+			break;
+		default:
+			dprintf(CRITICAL, "ERROR: Couldn't get the pmic type\n");
+			break;
+	}
+
+	batt_is_exist = value >> 7;
+
+	return batt_is_exist;
+
+}
+
+#if CHECK_BAT_VOLTAGE
+/* Return battery voltage */
+uint32_t target_get_battery_voltage()
+{
+	uint32_t pmic;
+	uint32_t vbat = 0;
+
+	pmic = target_get_pmic();
+
+	switch(pmic)
+	{
+		case PMIC_IS_PM8909:
+		case PMIC_IS_PM8916:
+		case PMIC_IS_PM8941:
+			vbat = pm8x41_get_batt_voltage(); //uv
+			break;
+		case PMIC_IS_PMI8950:
+		case PMIC_IS_PMI8994:
+		case PMIC_IS_PMI8996:
+			if (!pm_fg_usr_get_vbat(1, &vbat)) {
+				vbat = vbat*1000; //uv
+			} else {
+				dprintf(CRITICAL, "ERROR: Get battery voltage failed!!!\n");
+			}
+			break;
+		default:
+			dprintf(CRITICAL, "ERROR: Couldn't get the pmic type\n");
+			break;
+	}
+
+	return vbat;
+}
+
+/* Add safeguards such as refusing to flash if minimum battery levels
+ * are not present or be bypass if the device doesn't have a battery
+ */
+bool target_battery_soc_ok()
+{
+	if (!target_battery_is_present()) {
+		dprintf(INFO, "battery is not present\n");
+		return true;
+	}
+
+	if (target_get_battery_voltage() >= BATTERY_MIN_VOLTAGE)
+		return true;
+
+	return false;
+}
+#endif
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index 166cec4..e439c04 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -49,6 +49,7 @@
 #include <gpio.h>
 #include <rpm-smd.h>
 #include <qpic_nand.h>
+#include <smem.h>
 
 #if LONG_PRESS_POWER_ON
 #include <shutdown_detect.h>
@@ -205,14 +206,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);
@@ -702,3 +708,8 @@
 {
 	pm8x41_reset_configure(reset_type);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PM8909;
+}
diff --git a/target/msm8909/rules.mk b/target/msm8909/rules.mk
index b3e2059..508609f 100644
--- a/target/msm8909/rules.mk
+++ b/target/msm8909/rules.mk
@@ -22,6 +22,7 @@
 	lib/ptable \
 	dev/gcdb/display \
 	dev/pmic/pm8x41 \
+	dev/pmic/pmi8994 \
 	lib/libfdt
 
 DEFINES += \
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index dba1ed3..693db04 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -48,6 +48,7 @@
 #include <crypto5_wrapper.h>
 #include <partition_parser.h>
 #include <stdlib.h>
+#include <smem.h>
 
 #if LONG_PRESS_POWER_ON
 #include <shutdown_detect.h>
@@ -132,14 +133,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);
@@ -498,3 +504,8 @@
 {
 	pm8x41_reset_configure(reset_type);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PM8916;
+}
diff --git a/target/msm8916/rules.mk b/target/msm8916/rules.mk
index 6acddef..1533102 100644
--- a/target/msm8916/rules.mk
+++ b/target/msm8916/rules.mk
@@ -21,6 +21,7 @@
 	lib/ptable \
 	dev/pmic/pm8x41 \
 	lib/libfdt \
+	dev/pmic/pmi8994 \
 	dev/gcdb/display
 
 DEFINES += \
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index bc6f813..013700c 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -54,6 +54,10 @@
 #include <spmi.h>
 #include <sdhci_msm.h>
 #include <clock.h>
+#include <boot_device.h>
+#include <secapp_loader.h>
+#include <rpmb.h>
+#include <smem.h>
 
 #include "target/display.h"
 
@@ -73,6 +77,7 @@
 #define PMIC_ARB_OWNER_ID       0
 #define TLMM_VOL_UP_BTN_GPIO    85
 #define TLMM_VOL_UP_BTN_GPIO_8956 113
+#define TLMM_VOL_UP_BTN_GPIO_8937 91
 
 #define FASTBOOT_MODE           0x77665500
 #define RECOVERY_MODE           0x77665502
@@ -174,19 +179,25 @@
 /* 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;
 
 	if(platform_is_msm8956())
 		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8956;
-
+	else if(platform_is_msm8937())
+		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8937;
 	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 +254,12 @@
 
 void target_init(void)
 {
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	int ret = 0;
+#endif
+#endif
+
 	dprintf(INFO, "target_init()\n");
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
@@ -268,6 +285,45 @@
 	if (target_use_signed_kernel())
 		target_crypto_init_params();
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	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);
+	}
+
+	if (rpmb_init() < 0)
+	{
+		dprintf(CRITICAL, "RPMB init failed\n");
+		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);
+	}
+#endif
+#endif
+
 #if SMD_SUPPORT
 	rpm_smd_init();
 #endif
@@ -304,11 +360,13 @@
 	case MSM8952:
 	case MSM8956:
 	case MSM8976:
+	case MSM8937:
 		board->baseband = BASEBAND_MSM;
 		break;
 	case APQ8052:
 	case APQ8056:
 	case APQ8076:
+	case APQ8037:
 		board->baseband = BASEBAND_APQ;
 		break;
 	default:
@@ -449,6 +507,27 @@
 	if (target_is_ssd_enabled())
 		clock_ce_disable(CE1_INSTANCE);
 
+#if VERIFIED_BOOT
+#if !VBOOT_MOTA
+	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);
+#endif
+#endif
+
 #if SMD_SUPPORT
 	rpm_smd_uninit();
 #endif
@@ -607,3 +686,8 @@
 
 	crypto_init_params(&ce_params);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PMI8950;
+}
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index 5b2d59d..bbb3a1f 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -38,6 +38,7 @@
 #include <mdp5.h>
 #include <target/display.h>
 
+#include "gcdb_display.h"
 #include "include/panel.h"
 #include "panel_display.h"
 
@@ -135,6 +136,7 @@
 			struct mdss_dsi_phy_ctrl *phy_db)
 {
 	int pan_type = PANEL_TYPE_DSI;
+	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
 
 	switch (panel_id) {
 	case TRULY_1080P_VIDEO_PANEL:
@@ -362,9 +364,27 @@
 		panelstruct->paneltiminginfo->tclk_post = 0x04;
 		panelstruct->paneltiminginfo->tclk_pre = 0x20;
 		pinfo->mipi.tx_eot_append = true;
+
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_video_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config0;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_video_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
 		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;
@@ -401,9 +421,27 @@
 		panelstruct->paneltiminginfo->tclk_post = 0x04;
 		panelstruct->paneltiminginfo->tclk_pre = 0x20;
 		pinfo->mipi.tx_eot_append = true;
+
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_cmd_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config0;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_cmd_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
 		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;
@@ -474,6 +512,11 @@
 		pan_type = PANEL_TYPE_UNKNOWN;
 		break;
 	}
+
+	dprintf(SPEW, "lm_split[0]=%d lm_split[1]=%d mode=0x%x\n",
+		pinfo->lm_split[0], pinfo->lm_split[1],
+		panelstruct->paneldata->panel_operating_mode);
+
 	return pan_type;
 }
 
diff --git a/target/msm8952/rules.mk b/target/msm8952/rules.mk
index 045275e..3eaf841 100644
--- a/target/msm8952/rules.mk
+++ b/target/msm8952/rules.mk
@@ -12,9 +12,8 @@
 MEMSIZE := 0x00300000 # 3MB
 
 BASE_ADDR        := 0x80000000
-SCRATCH_ADDR     := 0x90000000
+SCRATCH_ADDR     := 0x90100000
 
-DEFINES += DISPLAY_SPLASH_SCREEN=1
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
 
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index a7e0ca8..266e091 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);
@@ -821,3 +826,8 @@
 		tcsr_hs_phy_mux_configure();
 	}
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PM8941;
+}
\ No newline at end of file
diff --git a/target/msm8974/rules.mk b/target/msm8974/rules.mk
index b5b1218..f95a816 100644
--- a/target/msm8974/rules.mk
+++ b/target/msm8974/rules.mk
@@ -23,6 +23,7 @@
 	dev/keys \
 	dev/pmic/pm8x41 \
 	dev/gcdb/display \
+	dev/pmic/pmi8994 \
     lib/ptable \
     lib/libfdt
 
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 9d8c4e5..066b50f 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 */
@@ -590,3 +647,8 @@
 
 	return 0;
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PMI8994;
+}
diff --git a/target/msm8994/rules.mk b/target/msm8994/rules.mk
index 4ac3ff1..1f99dce 100644
--- a/target/msm8994/rules.mk
+++ b/target/msm8994/rules.mk
@@ -9,11 +9,11 @@
 PLATFORM := msm8994
 
 MEMBASE := 0x0F900000 # SDRAM
-MEMSIZE := 0x00100000 # 1MB
+MEMSIZE := 0x00200000 # 2MB
 
 BASE_ADDR    := 0x0000000
 
-SCRATCH_ADDR := 0x10000000
+SCRATCH_ADDR := 0x10100000
 
 SCRATCH_SIZE := 0x20000000
 
@@ -30,6 +30,7 @@
 	dev/qpnp_led \
     lib/ptable \
 	dev/gcdb/display \
+	dev/pmic/pmi8994 \
     lib/libfdt
 
 DEFINES += \
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 07295f1..b84bb91 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
@@ -106,19 +108,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);
@@ -152,7 +159,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);
@@ -265,6 +272,7 @@
 
 void target_init(void)
 {
+	int ret = 0;
 	dprintf(INFO, "target_init()\n");
 
 	pmic_info_populate();
@@ -322,6 +330,7 @@
 	{
 		case HW_PLATFORM_MTP:
 		case HW_PLATFORM_FLUID:
+		case HW_PLATFORM_QRD:
 			pm_appsbl_chg_check_weak_battery_status(1);
 			break;
 		default:
@@ -330,11 +339,38 @@
 	};
 #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);
+	}
+
 	if (rpmb_init() < 0)
 	{
 		dprintf(CRITICAL, "RPMB init failed\n");
 		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);
+	}
 }
 
 unsigned board_machtype(void)
@@ -360,6 +396,7 @@
 			case HW_PLATFORM_MTP:
 			case HW_PLATFORM_FLUID:
 			case HW_PLATFORM_QRD:
+			case HW_PLATFORM_LIQUID:
 				dprintf(SPEW, "Target_cont_splash=1\n");
 				splash_screen = 1;
 				break;
@@ -520,3 +557,8 @@
 {
 	pm8994_reset_configure(reset_type);
 }
+
+uint32_t target_get_pmic()
+{
+	return PMIC_IS_PMI8996;
+}
diff --git a/target/msm8996/oem_panel.c b/target/msm8996/oem_panel.c
index b2896cd..b1fc1a1 100644
--- a/target/msm8996/oem_panel.c
+++ b/target/msm8996/oem_panel.c
@@ -37,6 +37,7 @@
 #include <qtimer.h>
 #include <platform.h>
 
+#include "gcdb_display.h"
 #include "include/panel.h"
 #include "target/display.h"
 #include "panel_display.h"
@@ -54,6 +55,7 @@
 #include "include/panel_jdi_qhd_dualdsi_video.h"
 #include "include/panel_jdi_qhd_dualdsi_cmd.h"
 #include "include/panel_r69007_wqxga_cmd.h"
+#include "include/panel_jdi_4k_dualdsi_video_nofbc.h"
 
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
@@ -67,6 +69,7 @@
 	JDI_QHD_DUALDSI_VIDEO_PANEL,
 	JDI_QHD_DUALDSI_CMD_PANEL,
 	R69007_WQXGA_CMD_PANEL,
+	JDI_4K_DUALDSI_VIDEO_NOFBC_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -83,6 +86,7 @@
 	{"jdi_qhd_dualdsi_video", JDI_QHD_DUALDSI_VIDEO_PANEL},
 	{"jdi_qhd_dualdsi_cmd", JDI_QHD_DUALDSI_CMD_PANEL},
 	{"r69007_wqxga_cmd", R69007_WQXGA_CMD_PANEL},
+	{"jdi_4k_dualdsi_video_nofbc", JDI_4K_DUALDSI_VIDEO_NOFBC_PANEL},
 };
 
 static uint32_t panel_id;
@@ -115,6 +119,7 @@
 			struct mdss_dsi_phy_ctrl *phy_db)
 {
 	int pan_type;
+	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
 
 	switch (panel_id) {
 	case SHARP_WQXGA_DUALDSI_VIDEO_PANEL:
@@ -149,7 +154,34 @@
 		memcpy(phy_db->timing,
 			sharp_wqxga_dualdsi_thulium_video_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		pinfo->dfps.panel_dfps = sharp_wqxga_dualdsi_video_dfps;
 		pinfo->mipi.tx_eot_append = true;
+
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &sharp_wqxga_dualdsi_video_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&sharp_wqxga_dualdsi_video_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&sharp_wqxga_dualdsi_video_config1;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &sharp_wqxga_dualdsi_video_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
 		break;
 	case NT35597_WQXGA_DUALDSI_VIDEO_PANEL:
 		pan_type = PANEL_TYPE_DSI;
@@ -181,6 +213,32 @@
 			nt35597_wqxga_dualdsi_thulium_video_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
+
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dualdsi_video_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_video_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_video_config1;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dualdsi_video_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
 		break;
 	case NT35597_WQXGA_DUALDSI_CMD_PANEL:
 		pan_type = PANEL_TYPE_DSI;
@@ -212,6 +270,32 @@
 			nt35597_wqxga_dualdsi_thulium_cmd_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
+
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dualdsi_cmd_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_cmd_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_cmd_config1;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dualdsi_cmd_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
 		break;
 	case NT35597_WQXGA_DSC_VIDEO_PANEL:
 		pan_type = PANEL_TYPE_DSI;
@@ -244,9 +328,38 @@
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
 
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_video_config2;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config1;
+				break;
+			case 2:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config2;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config2\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_video_config2;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
+
 		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;
@@ -283,9 +396,39 @@
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
 
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_cmd_config2;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config1;
+				break;
+			case -1: /* default */
+			case 2:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config2;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config2\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_cmd_config2;
+			}
+		}
+
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
+
 		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;
@@ -377,11 +520,50 @@
 			r69007_wqxga_thulium_cmd_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		break;
+	case JDI_4K_DUALDSI_VIDEO_NOFBC_PANEL:
+		pan_type = PANEL_TYPE_DSI;
+		/*
+		 * send on_cmds at HS mode by setting cmds_post_tg so that
+		 * on_cmds are sent after timing generator on
+		 */
+		pinfo->mipi.cmds_post_tg = 1;
+		panelstruct->paneldata    = &jdi_4k_dualdsi_video_nofbc_panel_data;
+
+		panelstruct->panelres     = &jdi_4k_dualdsi_video_nofbc_panel_res;
+		panelstruct->color        = &jdi_4k_dualdsi_video_nofbc_color;
+		panelstruct->videopanel   = &jdi_4k_dualdsi_video_nofbc_video_panel;
+		panelstruct->commandpanel = &jdi_4k_dualdsi_video_nofbc_command_panel;
+		panelstruct->state        = &jdi_4k_dualdsi_video_nofbc_state;
+		panelstruct->laneconfig   = &jdi_4k_dualdsi_video_nofbc_lane_config;
+		panelstruct->paneltiminginfo
+			= &jdi_4k_dualdsi_video_nofbc_timing_info;
+		panelstruct->panelresetseq
+				 = &jdi_4k_dualdsi_video_nofbc_reset_seq;
+		panelstruct->backlightinfo = &jdi_4k_dualdsi_video_nofbc_backlight;
+		pinfo->labibb = &jdi_4k_dualdsi_video_nofbc_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= jdi_4k_dualdsi_video_nofbc_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= JDI_4K_DUALDSI_VIDEO_NOFBC_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= jdi_4k_dualdsi_video_nofbc_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= JDI_4K_DUALDSI_VIDEO_NOFBC_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			jdi_4k_dualdsi_thulium_video_nofbc_timings,
+			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		break;
 	default:
 	case UNKNOWN_PANEL:
 		pan_type = PANEL_TYPE_UNKNOWN;
 		break;
 	}
+
+	dprintf(SPEW, "lm_split[0]=%d lm_split[1]=%d mode=0x%x\n",
+		pinfo->lm_split[0], pinfo->lm_split[1],
+		panelstruct->paneldata->panel_operating_mode);
+
 	return pan_type;
 }
 
@@ -420,6 +602,9 @@
 	case HW_PLATFORM_QRD:
 		panel_id = R69007_WQXGA_CMD_PANEL;
 		break;
+	case HW_PLATFORM_LIQUID:
+		panel_id = JDI_4K_DUALDSI_VIDEO_NOFBC_PANEL;
+		break;
 	default:
 		dprintf(CRITICAL, "Display not enabled for %d HW type\n"
 					, hw_id);
diff --git a/target/msm8996/target_display.c b/target/msm8996/target_display.c
index ebede20..439ec14 100644
--- a/target/msm8996/target_display.c
+++ b/target/msm8996/target_display.c
@@ -106,6 +106,7 @@
 {
 	uint32_t pll_locked;
 
+	writel(0x10, phy_base + 0x45c);
 	writel(0x01, phy_base + 0x48);
 	dmb();
 
@@ -273,6 +274,7 @@
 	uint32_t flags, dsi_phy_pll_out;
 	uint32_t ret = NO_ERROR;
 	uint32_t board_version = board_soc_version();
+	struct dfps_pll_codes *pll_codes = &pinfo->mipi.pll_codes;
 
 	if (pinfo->dest == DISPLAY_2) {
 		flags = MMSS_DSI_CLKS_FLAG_DSI1;
@@ -307,6 +309,13 @@
 		goto clks_disable;
 	}
 
+	pll_codes->codes[0] = readl_relaxed(pinfo->mipi.pll_base +
+			        MMSS_DSI_PHY_PLL_CORE_KVCO_CODE);
+	pll_codes->codes[1] = readl_relaxed(pinfo->mipi.pll_base +
+			        MMSS_DSI_PHY_PLL_CORE_VCO_TUNE);
+	dprintf(SPEW, "codes %d %d\n", pll_codes->codes[0],
+			        pll_codes->codes[1]);
+
 	if (pinfo->mipi.use_dsi1_pll)
 		dsi_phy_pll_out = DSI1_PHY_PLL_OUT;
 	else
diff --git a/target/msmtitanium/init.c b/target/msmtitanium/init.c
old mode 100644
new mode 100755
index 5f76517..8a80a8c
--- a/target/msmtitanium/init.c
+++ b/target/msmtitanium/init.c
@@ -37,17 +37,21 @@
 #include <dev/keys.h>
 #include <spmi_v2.h>
 #include <pm8x41.h>
+#include <pm8x41_hw.h>
 #include <board.h>
 #include <baseband.h>
 #include <hsusb.h>
 #include <scm.h>
-#include <platform/gpio.h>
-#include <platform/gpio.h>
 #include <platform/irqs.h>
 #include <platform/clock.h>
+#include <platform/timer.h>
 #include <crypto5_wrapper.h>
 #include <partition_parser.h>
 #include <stdlib.h>
+#include <rpm-smd.h>
+#include <spmi.h>
+#include <sdhci_msm.h>
+#include <clock.h>
 
 #if LONG_PRESS_POWER_ON
 #include <shutdown_detect.h>
@@ -60,9 +64,16 @@
 #define FASTBOOT_MODE           0x77665500
 #define PON_SOFT_RB_SPARE       0x88F
 
-static uint32_t mmc_sdc_base[] =
+struct mmc_device *dev;
+
+static uint32_t mmc_pwrctl_base[] =
 	{ MSM_SDC1_BASE, MSM_SDC2_BASE };
 
+static uint32_t mmc_sdhci_base[] =
+	{ MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
+
+static uint32_t  mmc_sdc_pwrctl_irq[] =
+	{ SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
 
 void target_early_init(void)
 {
@@ -71,12 +82,68 @@
 #endif
 }
 
-void target_mmc_caps(struct mmc_host *host)
+static void set_sdc_power_ctrl()
 {
-	host->caps.ddr_mode = 0;
-	host->caps.hs200_mode = 0;
-	host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
-	host->caps.hs_clk_rate = MMC_CLK_50MHZ;
+	/* Drive strength configs for sdc pins */
+	struct tlmm_cfgs sdc1_hdrv_cfg[] =
+	{
+		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, 0},
+		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, 0},
+		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK , 0},
+	};
+
+	/* Pull configs for sdc pins */
+	struct tlmm_cfgs sdc1_pull_cfg[] =
+	{
+		{ SDC1_CLK_PULL_CTL_OFF,  TLMM_NO_PULL, TLMM_PULL_MASK, 0},
+		{ SDC1_CMD_PULL_CTL_OFF,  TLMM_PULL_UP, TLMM_PULL_MASK, 0},
+		{ SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK, 0},
+	};
+
+	struct tlmm_cfgs sdc1_rclk_cfg[] =
+	{
+		{ SDC1_RCLK_PULL_CTL_OFF, TLMM_PULL_DOWN, TLMM_PULL_MASK, 0},
+	};
+
+	/* Set the drive strength & pull control values */
+	tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
+	tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
+	tlmm_set_pull_ctrl(sdc1_rclk_cfg, ARRAY_SIZE(sdc1_rclk_cfg));
+}
+
+void target_sdc_init()
+{
+	struct mmc_config_data config;
+
+	/* Set drive strength & pull ctrl values */
+	set_sdc_power_ctrl();
+
+	config.slot          = MMC_SLOT;
+	config.bus_width     = DATA_BUS_WIDTH_8BIT;
+	config.max_clk_rate  = MMC_CLK_192MHZ;
+	config.sdhc_base     = mmc_sdhci_base[config.slot - 1];
+	config.pwrctl_base   = mmc_pwrctl_base[config.slot - 1];
+	config.pwr_irq       = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 1;
+
+	if (!(dev = mmc_init(&config))) {
+	/* Try different config. values */
+		config.max_clk_rate  = MMC_CLK_200MHZ;
+		config.sdhc_base     = mmc_sdhci_base[config.slot - 1];
+		config.pwrctl_base   = mmc_pwrctl_base[config.slot - 1];
+		config.pwr_irq       = mmc_sdc_pwrctl_irq[config.slot - 1];
+		config.hs400_support = 0;
+
+		if (!(dev = mmc_init(&config))) {
+			dprintf(CRITICAL, "mmc init failed!");
+			ASSERT(0);
+		}
+	}
+}
+
+void *target_mmc_device()
+{
+	return (void *) dev;
 }
 
 /* Return 1 if vol_up pressed */
@@ -114,48 +181,21 @@
 		keys_post_event(KEY_VOLUMEUP, 1);
 }
 
-/* Configure PMIC and Drop PS_HOLD for shutdown */
-void shutdown_device()
-{
-	dprintf(CRITICAL, "Going down for shutdown.\n");
-
-	/* Configure PMIC for shutdown */
-	pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
-
-	/* Drop PS_HOLD for MSM */
-	writel(0x00, MPM2_MPM_PS_HOLD);
-
-	mdelay(5000);
-
-	dprintf(CRITICAL, "shutdown failed\n");
-
-	ASSERT(0);
-}
-
-
 void target_init(void)
 {
-	uint32_t base_addr;
-	uint8_t slot;
-
 	dprintf(INFO, "target_init()\n");
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
 
 	target_keystatus();
 
-	/* Trying Slot 1*/
-	slot = 1;
-	base_addr = mmc_sdc_base[slot - 1];
-	if (mmc_boot_main(slot, base_addr)) {
-		/* Trying Slot 2 next */
-		slot = 2;
-		base_addr = mmc_sdc_base[slot - 1];
-		if (mmc_boot_main(slot, base_addr)) {
-			dprintf(CRITICAL, "mmc init failed!");
-			ASSERT(0);
-		}
+	target_sdc_init();
+	if (partition_read_table())
+	{
+		dprintf(CRITICAL, "Error reading the partition table info\n");
+		ASSERT(0);
 	}
+
 #if LONG_PRESS_POWER_ON
 	shutdown_detect();
 #endif
@@ -172,6 +212,29 @@
 
 unsigned board_machtype(void)
 {
+	return LINUX_MACHTYPE_UNKNOWN;
+}
+
+/* Detect the target type */
+void target_detect(struct board_data *board)
+{
+	/* This is already filled as part of board.c */
+}
+
+void target_baseband_detect(struct board_data *board)
+{
+	uint32_t platform;
+
+	platform = board->platform;
+
+	switch(platform) {
+	case MSMTITANIUM:
+		board->baseband = BASEBAND_MSM;
+		break;
+	default:
+		dprintf(CRITICAL, "Platform type: %u is not supported\n",platform);
+		ASSERT(0);
+	};
 }
 
 int set_download_mode(enum dload_mode mode)
@@ -250,3 +313,15 @@
 {
 	return "dwc";
 }
+
+
+crypto_engine_type board_ce_type(void)
+{
+	return CRYPTO_ENGINE_TYPE_HW;
+}
+
+
+void pmic_reset_configure(uint8_t reset_type)
+{
+	pm8x41_reset_configure(reset_type);
+}