Merge "Revert "Revert "target: msm8994: add support for 90 phase DSI PLL VCO frequency"""
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 78164e5..f3b63b7 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -106,6 +106,10 @@
 
 #define MAX_TAGS_SIZE   1024
 
+#define RECOVERY_HARD_RESET_MODE   0x01
+#define FASTBOOT_HARD_RESET_MODE   0x02
+#define RTC_HARD_RESET_MODE        0x03
+
 #define RECOVERY_MODE   0x77665502
 #define FASTBOOT_MODE   0x77665500
 #define ALARM_BOOT      0x77665503
@@ -123,7 +127,7 @@
 
 #define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
 
-#if UFS_SUPPORT || USE_BOOTDEV_CMDLINE
+#if USE_BOOTDEV_CMDLINE
 static const char *emmc_cmdline = " androidboot.bootdevice=";
 #else
 static const char *emmc_cmdline = " androidboot.emmc=true";
@@ -246,7 +250,7 @@
 	}
 	if (target_is_emmc_boot()) {
 		cmdline_len += strlen(emmc_cmdline);
-#if UFS_SUPPORT || USE_BOOTDEV_CMDLINE
+#if USE_BOOTDEV_CMDLINE
 		boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
 		ASSERT(boot_dev_buf);
 		platform_boot_dev_cmdline(boot_dev_buf);
@@ -361,7 +365,7 @@
 			if (have_cmdline) --dst;
 			have_cmdline = 1;
 			while ((*dst++ = *src++));
-#if UFS_SUPPORT  || USE_BOOTDEV_CMDLINE
+#if USE_BOOTDEV_CMDLINE
 			src = boot_dev_buf;
 			if (have_cmdline) --dst;
 			while ((*dst++ = *src++));
@@ -897,6 +901,8 @@
                     return -1;
 		}
 	}
+	/* Set Lun for boot & recovery partitions */
+	mmc_set_lun(partition_get_lun(index));
 
 	if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
 		dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
@@ -2724,6 +2730,7 @@
 void aboot_init(const struct app_descriptor *app)
 {
 	unsigned reboot_mode = 0;
+	unsigned hard_reboot_mode = 0;
 	bool boot_into_fastboot = false;
 
 	/* Setup page size information for nv storage */
@@ -2791,11 +2798,15 @@
 	#endif
 
 	reboot_mode = check_reboot_mode();
-	if (reboot_mode == RECOVERY_MODE) {
+	hard_reboot_mode = check_hard_reboot_mode();
+	if (reboot_mode == RECOVERY_MODE ||
+		hard_reboot_mode == RECOVERY_HARD_RESET_MODE) {
 		boot_into_recovery = 1;
-	} else if(reboot_mode == FASTBOOT_MODE) {
+	} else if(reboot_mode == FASTBOOT_MODE ||
+		hard_reboot_mode == FASTBOOT_HARD_RESET_MODE) {
 		boot_into_fastboot = true;
-	} else if(reboot_mode == ALARM_BOOT) {
+	} else if(reboot_mode == ALARM_BOOT ||
+		hard_reboot_mode == RTC_HARD_RESET_MODE) {
 		boot_reason_alarm = true;
 	}
 
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index 7d97842..8e521b1 100755
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -39,6 +39,7 @@
 #include <qtimer.h>
 #include <platform/gpio.h>
 #include <mipi_dsi.h>
+#include <partition_parser.h>
 
 #include "include/display_resource.h"
 #include "include/panel.h"
@@ -82,12 +83,10 @@
 	uint32_t ret = NO_ERROR;
 
 	ret = calculate_clock_config(pinfo);
-	if (ret) {
-		dprintf(CRITICAL, "Clock calculation failed \n");
-		/* should it stop here ? check with display team */
-	}
-
-	ret = target_panel_clock(enable, pinfo);
+	if (ret)
+		dprintf(CRITICAL, "Clock calculation failed\n");
+	else
+		ret = target_panel_clock(enable, pinfo);
 
 	return ret;
 }
@@ -151,6 +150,168 @@
 	return ret;
 }
 
+static int mdss_dsi_dfps_get_pll_codes_cal(struct msm_panel_info *pinfo)
+{
+	int ret = NO_ERROR;
+	uint32_t fps_bak;
+	uint32_t i;
+
+	fps_bak = pinfo->mipi.frame_rate;
+
+	for (i = 0; i < pinfo->dfps.panel_dfps.frame_rate_cnt; i++) {
+		int err;
+		pinfo->mipi.frame_rate = pinfo->dfps.panel_dfps.frame_rate[i];
+
+		err = mdss_dsi_panel_clock(1, pinfo);
+		if (!err) {
+			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 =
+				pinfo->mipi.pll_codes;
+
+			mdss_dsi_panel_clock(0, pinfo);
+		} else {
+			ret = err;
+			pinfo->dfps.codes_dfps[i].is_valid = 0;
+			dprintf(CRITICAL, "frame_rate=%d failed!\n",
+				pinfo->mipi.frame_rate);
+		}
+	}
+
+	pinfo->mipi.frame_rate = fps_bak;
+
+	return ret;
+}
+
+static int mdss_dsi_dfps_get_stored_pll_codes(struct msm_panel_info *pinfo)
+{
+	int ret = NO_ERROR;
+	int index;
+	unsigned long long ptn;
+	uint32_t blocksize;
+	struct dfps_info *dfps;
+
+	index = partition_get_index("splash");
+	if (index == 0) {
+		dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
+		ret = ERROR;
+		goto splash_err;
+	}
+
+	ptn = partition_get_offset(index);
+	if (ptn == 0) {
+		dprintf(CRITICAL, "ERROR: splash Partition invalid offset\n");
+		ret = ERROR;
+		goto splash_err;
+	}
+
+	blocksize = mmc_get_device_blocksize();
+	if (blocksize == 0) {
+		dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
+		ret = ERROR;
+		goto splash_err;
+	}
+
+	dfps = (struct dfps_info *)memalign(CACHE_LINE, ROUNDUP(PAGE_SIZE,
+			CACHE_LINE));
+	if (!dfps) {
+		dprintf(CRITICAL, "ERROR:splash Partition invalid memory\n");
+		ret = ERROR;
+		goto splash_err;
+	}
+
+	if (mmc_read(ptn, (uint32_t *) dfps, blocksize)) {
+		dprintf(CRITICAL, "mmc read splash failure%d\n", PAGE_SIZE);
+		ret = ERROR;
+		free(dfps);
+		goto splash_err;
+	}
+
+	dprintf(SPEW, "enable=%d cnt=%d\n", dfps->panel_dfps.enabled,
+		dfps->panel_dfps.frame_rate_cnt);
+
+	if (!dfps->panel_dfps.enabled || dfps->panel_dfps.frame_rate_cnt >
+		DFPS_MAX_FRAME_RATE) {
+		ret = ERROR;
+		free(dfps);
+		goto splash_err;
+	}
+
+	pinfo->dfps = *dfps;
+	free(dfps);
+
+splash_err:
+	return ret;
+}
+
+static int mdss_dsi_dfps_store_pll_codes(struct msm_panel_info *pinfo)
+{
+	int ret = NO_ERROR;
+	int index;
+	unsigned long long ptn;
+
+	index = partition_get_index("splash");
+	if (index == 0) {
+		dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
+		ret = ERROR;
+		goto store_err;
+	}
+
+	ptn = partition_get_offset(index);
+	if (ptn == 0) {
+		dprintf(CRITICAL, "ERROR: splash Partition invalid offset\n");
+		ret = ERROR;
+		goto store_err;
+	}
+
+	ret = mmc_write(ptn, sizeof(uint32_t), &pinfo->dfps);
+	if (ret)
+		dprintf(CRITICAL, "mmc write failed!\n");
+
+store_err:
+	return ret;
+}
+
+static int mdss_dsi_mipi_dfps_config(struct msm_panel_info *pinfo)
+{
+	int ret = NO_ERROR;
+
+	if (!pinfo)
+		return ERROR;
+
+	if (!pinfo->dfps.panel_dfps.enabled)
+		goto dfps_done;
+
+	if (!mdss_dsi_dfps_get_stored_pll_codes(pinfo)) {
+		dprintf(SPEW, "Found stored PLL codes!\n");
+		goto dfps_cal_done;
+	}
+
+	ret = mdss_dsi_dfps_get_pll_codes_cal(pinfo);
+	if (ret) {
+		dprintf(CRITICAL, "Cannot cal pll codes!\n");
+		goto dfps_done;
+	} else {
+		dprintf(SPEW, "Calibrate all pll codes!\n");
+	}
+
+	ret = mdss_dsi_dfps_store_pll_codes(pinfo);
+	if (ret)
+		dprintf(CRITICAL, "Cannot store pll codes!\n");
+
+dfps_cal_done:
+	if (pinfo->dfps.dfps_fb_base)
+		memcpy(pinfo->dfps.dfps_fb_base, &pinfo->dfps,
+			sizeof(struct dfps_info));
+dfps_done:
+	return ret;
+}
+
 static int mdss_dsi_bl_enable(uint8_t enable)
 {
 	int ret = NO_ERROR;
@@ -393,9 +554,20 @@
 
 		panel.panel_info.mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db;
 		panel.pll_clk_func = mdss_dsi_panel_clock;
+		panel.dfps_func = mdss_dsi_mipi_dfps_config;
 		panel.power_func = mdss_dsi_panel_power;
 		panel.pre_init_func = mdss_dsi_panel_pre_init;
 		panel.bl_func = mdss_dsi_bl_enable;
+		/*
+		 * If dfps enabled, reserve fb memory to store pll
+		 * codes and pass pll codes values to kernel.
+		 */
+		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);
+		}
+
 		panel.fb.base = base;
 		panel.fb.width =  panel.panel_info.xres;
 		panel.fb.height =  panel.panel_info.yres;
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 68a277d..312b939 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.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
@@ -151,6 +151,13 @@
 	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
 };
 
+/*---------------------------------------------------------------------------*/
+/* Dynamic fps supported frequencies by panel                                */
+/*---------------------------------------------------------------------------*/
+static const struct dfps_panel_info sharp_wqxga_dualdsi_video_dfps = {
+	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
+};
+
 #define SHARP_WQXGA_DUALDSI_VIDEO_SIGNATURE 0x210000
 
 #endif /*_PANEL_SHARP_WQXGA_DUALDSI_VIDEO_H_*/
diff --git a/include/platform.h b/include/platform.h
index b65395e..e71c407 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -53,6 +53,7 @@
 unsigned board_machtype(void);
 unsigned board_platform_id(void);
 unsigned check_reboot_mode(void);
+unsigned check_hard_reboot_mode(void);
 void platform_uninit_timer(void);
 void reboot_device(unsigned);
 int set_download_mode(enum dload_mode mode);
diff --git a/platform/msm8994/include/platform/iomap.h b/platform/msm8994/include/platform/iomap.h
index 0bcae0a..28ae75a 100644
--- a/platform/msm8994/include/platform/iomap.h
+++ b/platform/msm8994/include/platform/iomap.h
@@ -243,6 +243,9 @@
 #define DSI0_REGULATOR_BASE         (0xFD998780)
 #define DSI1_REGULATOR_BASE         (0xFD9A0780)
 
+#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE  0x0160
+#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0168
+
 #define MDP_BASE                    (0xfd900000)
 
 
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
index ce49916..ecffcc4 100644
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -283,6 +283,9 @@
 	if (ret)
 		goto msm_display_init_out;
 
+	if (pdata->dfps_func)
+		ret = pdata->dfps_func(&(panel->panel_info));
+
 	/* Enable clock */
 	if (pdata->clk_func)
 		ret = pdata->clk_func(1, &(panel->panel_info));
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index 41a6f26..4b09f69 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -36,6 +36,9 @@
 #define TRUE	1
 #define FALSE	0
 
+#define DFPS_MAX_FRAME_RATE 10
+#define DFPS_PLL_CODES_SIZE 0x1000 /* One page */
+
 /* panel type list */
 #define NO_PANEL		0xffff	/* No Panel */
 #define MDDI_PANEL		1	/* MDDI */
@@ -143,6 +146,30 @@
 	uint32_t max_pred_err;
 };
 
+
+struct dfps_panel_info {
+	uint32_t enabled;
+	uint32_t frame_rate_cnt;
+	uint32_t frame_rate[DFPS_MAX_FRAME_RATE];
+};
+
+struct dfps_pll_codes {
+	uint32_t codes[2];
+};
+
+struct dfps_codes_info {
+	uint32_t is_valid;
+	uint32_t frame_rate;
+	uint32_t clk_rate;
+	struct dfps_pll_codes pll_codes;
+};
+
+struct dfps_info {
+	struct dfps_panel_info panel_dfps;
+	struct dfps_codes_info codes_dfps[DFPS_MAX_FRAME_RATE];
+	void *dfps_fb_base;
+};
+
 /* intf timing settings */
 struct intf_timing_params {
 	uint32_t width;
@@ -230,6 +257,8 @@
 	uint32_t sreg_base;
 	uint32_t pll_0_base;
 	uint32_t pll_1_base;
+
+	struct dfps_pll_codes pll_codes;
 };
 
 struct edp_panel_info {
@@ -286,6 +315,8 @@
 	struct hdmi_panel_info hdmi;
 	struct edp_panel_info edp;
 
+	struct dfps_info dfps;
+
 	struct labibb_desc *labibb;
 
 	int (*on) (void);
@@ -309,6 +340,7 @@
 	uint32_t (*clk_func) (uint8_t enable, struct msm_panel_info *pinfo);
 	int (*bl_func) (uint8_t enable);
 	uint32_t (*pll_clk_func) (uint8_t enable, struct msm_panel_info *);
+	int (*dfps_func)(struct msm_panel_info *);
 	int (*post_power_func)(int enable);
 	int (*pre_init_func)(void);
 };
diff --git a/platform/msm_shared/include/qmp_phy.h b/platform/msm_shared/include/qmp_phy.h
index ab669d7..4558abe 100644
--- a/platform/msm_shared/include/qmp_phy.h
+++ b/platform/msm_shared/include/qmp_phy.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
@@ -87,5 +87,6 @@
 
 void usb30_qmp_phy_reset(void);
 void usb30_qmp_phy_init(void);
+bool use_hsonly_mode();
 
 #endif
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index 025a038..283f1cc 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -258,7 +258,7 @@
 #define IS_CALL_AVAIL_CMD           0x01
 
 /* Download Mode specific arguments to be passed to TZ */
-#define SCM_EDLOAD_MODE 0x02
+#define SCM_EDLOAD_MODE 0x01
 #define SCM_DLOAD_MODE  0x10
 
 /* SSD parsing status messages from TZ */
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index 99c5a25..ddda7ee 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -540,6 +540,7 @@
 	uint32_t mdp_hw_rev = readl(MDP_HW_REV);
 	uint32_t v_total, h_total, fetch_start, vfp_start, fetch_lines;
 	uint32_t adjust_xres = 0;
+	uint32_t fetch_enable = BIT(31);
 
 	struct lcdc_panel_info *lcdc = NULL;
 
@@ -584,8 +585,11 @@
 
 	fetch_start = (v_total - fetch_lines) * h_total + 1;
 
-	writel(fetch_start, MDP_PROG_FETCH_START + intf_base);
-	writel(BIT(31), MDP_INTF_CONFIG + intf_base);
+	if (pinfo->dfps.panel_dfps.enabled)
+		fetch_enable |= BIT(23);
+
+	writel_relaxed(fetch_start, MDP_PROG_FETCH_START + intf_base);
+	writel_relaxed(fetch_enable, MDP_INTF_CONFIG + intf_base);
 }
 
 void mdss_layer_mixer_setup(struct fbcon_config *fb, struct msm_panel_info
diff --git a/platform/msm_shared/qmp_usb30_phy.c b/platform/msm_shared/qmp_usb30_phy.c
index 821c0b2..a2c21cf 100644
--- a/platform/msm_shared/qmp_usb30_phy.c
+++ b/platform/msm_shared/qmp_usb30_phy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -45,6 +45,8 @@
 #define QMP_PHY_MAX_TIMEOUT            1000
 #define PHYSTATUS                      BIT(6)
 
+static bool hsonly_mode;
+
 struct qmp_reg qmp_settings[] =
 {
 	{0xAC, 0x14}, /* QSERDES_COM_SYSCLK_EN_SEL */
@@ -301,8 +303,6 @@
 		writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START);
 	}
 
-	clock_bumpup_pipe3_clk();
-
 	if (rev_id >= 0x20000000)
 		phy_status = 0x77c;
 	else
@@ -314,8 +314,16 @@
 		timeout--;
 		if (!timeout)
 		{
-			dprintf(CRITICAL, "QMP phy initialization failed\n");
+			dprintf(CRITICAL, "QMP phy initialization failed, fallback to HighSpeed only mode\n");
+			hsonly_mode = true;
 			return;
 		}
 	}
+
+	clock_bumpup_pipe3_clk();
+}
+
+bool use_hsonly_mode()
+{
+	return hsonly_mode;
 }
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 05ce959..2040e16 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -241,12 +241,6 @@
             $(LOCAL_DIR)/dev_tree.o \
             $(LOCAL_DIR)/gpio.o \
             $(LOCAL_DIR)/scm.o \
-			$(LOCAL_DIR)/ufs.o \
-			$(LOCAL_DIR)/utp.o \
-			$(LOCAL_DIR)/uic.o \
-			$(LOCAL_DIR)/ucs.o \
-			$(LOCAL_DIR)/ufs_hci.o \
-			$(LOCAL_DIR)/dme.o \
 			$(LOCAL_DIR)/certificate.o \
 			$(LOCAL_DIR)/image_verify.o \
 			$(LOCAL_DIR)/crypto_hash.o \
@@ -439,12 +433,6 @@
 			$(LOCAL_DIR)/dev_tree.o \
 			$(LOCAL_DIR)/gpio.o \
 			$(LOCAL_DIR)/scm.o \
-			$(LOCAL_DIR)/ufs.o \
-			$(LOCAL_DIR)/utp.o \
-			$(LOCAL_DIR)/uic.o \
-			$(LOCAL_DIR)/ucs.o \
-			$(LOCAL_DIR)/ufs_hci.o \
-			$(LOCAL_DIR)/dme.o \
 			$(LOCAL_DIR)/qmp_usb30_phy.o \
 			$(LOCAL_DIR)/certificate.o \
 			$(LOCAL_DIR)/image_verify.o \
@@ -507,12 +495,6 @@
 			$(LOCAL_DIR)/dev_tree.o \
 			$(LOCAL_DIR)/gpio.o \
 			$(LOCAL_DIR)/scm.o \
-			$(LOCAL_DIR)/ufs.o \
-			$(LOCAL_DIR)/utp.o \
-			$(LOCAL_DIR)/uic.o \
-			$(LOCAL_DIR)/ucs.o \
-			$(LOCAL_DIR)/ufs_hci.o \
-			$(LOCAL_DIR)/dme.o \
 			$(LOCAL_DIR)/qmp_usb30_phy.o \
 			$(LOCAL_DIR)/qusb2_phy.o \
 			$(LOCAL_DIR)/certificate.o \
@@ -522,6 +504,16 @@
 			$(LOCAL_DIR)/crypto5_wrapper.o
 endif
 
+ifeq ($(ENABLE_UFS_SUPPORT), 1)
+	OBJS += \
+			$(LOCAL_DIR)/ufs.o \
+			$(LOCAL_DIR)/utp.o \
+			$(LOCAL_DIR)/uic.o \
+			$(LOCAL_DIR)/ucs.o \
+			$(LOCAL_DIR)/ufs_hci.o \
+			$(LOCAL_DIR)/dme.o
+endif
+
 ifeq ($(ENABLE_BOOT_CONFIG_SUPPORT), 1)
 	OBJS += \
 		$(LOCAL_DIR)/boot_device.o
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index f944d74..8ca12e2 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -402,6 +402,7 @@
 	APQ8009  = 265,
 	MSMTELLURIUM  = 264,
 	MSMTERBIUM    = 266,
+	FSM9916  = 276,
 };
 
 enum platform {
diff --git a/platform/msm_shared/usb30_dwc_hw.c b/platform/msm_shared/usb30_dwc_hw.c
index 3327bca..7b69bbb 100644
--- a/platform/msm_shared/usb30_dwc_hw.c
+++ b/platform/msm_shared/usb30_dwc_hw.c
@@ -41,6 +41,7 @@
 #include <usb30_dwc_hw.h>
 #include <smem.h>
 #include <board.h>
+#include <qmp_phy.h>
 
 extern char* ss_link_state_lookup[20];
 extern char* hs_link_state_lookup[20];
@@ -512,17 +513,15 @@
 void dwc_phy_digital_reset(dwc_dev_t *dev)
 {
 	REG_WRITE_FIELDI(dev, GUSB2PHYCFG,  0, PHYSOFTRST, 1);
-#ifndef USE_HSONLY_MODE
-	REG_WRITE_FIELDI(dev, GUSB3PIPECTL, 0, PHYSOFTRST, 1);
-#endif
+	if (!use_hsonly_mode())
+		REG_WRITE_FIELDI(dev, GUSB3PIPECTL, 0, PHYSOFTRST, 1);
 
 	/* per HPG */
 	udelay(100);
 
 	REG_WRITE_FIELDI(dev, GUSB2PHYCFG,  0, PHYSOFTRST, 0);
-#ifndef USE_HSONLY_MODE
-	REG_WRITE_FIELDI(dev, GUSB3PIPECTL, 0, PHYSOFTRST, 0);
-#endif
+	if (!use_hsonly_mode())
+		REG_WRITE_FIELDI(dev, GUSB3PIPECTL, 0, PHYSOFTRST, 0);
 
 	/* per HPG */
 	udelay(100);
diff --git a/platform/msm_shared/usb30_udc.c b/platform/msm_shared/usb30_udc.c
index 0e47c81..0e5e1b0 100644
--- a/platform/msm_shared/usb30_udc.c
+++ b/platform/msm_shared/usb30_udc.c
@@ -46,6 +46,7 @@
 #include <smem.h>
 #include <board.h>
 #include <platform/timer.h>
+#include <qmp_phy.h>
 
 //#define DEBUG_USB
 
@@ -232,10 +233,6 @@
 	/* 2. Put controller in reset */
 	dwc_reset(dwc, 1);
 
-	/* HS only mode support */
-#ifdef USE_HSONLY_MODE
-	usb_wrapper_hsonly_mode(wrapper);
-#endif
 
 	/* Steps 3 - 7 must be done while dwc is in reset condition */
 
@@ -243,9 +240,8 @@
 	phy_reset(wrapper, dev_info);
 
 	/* 4. SS phy config */
-#ifndef USE_HSONLY_MODE
-	usb_wrapper_ss_phy_configure(wrapper);
-#endif
+	if (!use_hsonly_mode())
+		usb_wrapper_ss_phy_configure(wrapper);
 
 	/* 5. HS phy init */
 	usb_wrapper_hs_phy_init(wrapper);
@@ -266,6 +262,10 @@
 	if (dev_info->t_usb_if->phy_init)
 		dev_info->t_usb_if->phy_init();
 
+	/* HS only mode support */
+	if (use_hsonly_mode())
+		usb_wrapper_hsonly_mode(wrapper);
+
 	/* 10. */
 	usb_wrapper_workaround_10(wrapper);
 
diff --git a/platform/msm_shared/usb30_wrapper.c b/platform/msm_shared/usb30_wrapper.c
index 6cec193..b6ca7ea 100644
--- a/platform/msm_shared/usb30_wrapper.c
+++ b/platform/msm_shared/usb30_wrapper.c
@@ -49,6 +49,7 @@
 #include <platform/clock.h>
 #include <usb30_wrapper.h>
 #include <usb30_wrapper_hwio.h>
+#include <qmp_phy.h>
 
 
 /* Configure DBM mode: by-pass or DBM */
@@ -166,9 +167,8 @@
 	REG_WRITE_FIELD(dev, HS_PHY_CTRL, SW_SESSVLD_SEL, 0x1);
 
 	/* Indicate power present to SS phy */
-#ifndef USE_HSONLY_MODE
-	REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 0x1);
-#endif
+	if (!use_hsonly_mode())
+		REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 0x1);
 }
 
 /* API to read SS PHY registers */
diff --git a/platform/thulium/acpuclock.c b/platform/thulium/acpuclock.c
index 03e1490..e2ee7d5 100644
--- a/platform/thulium/acpuclock.c
+++ b/platform/thulium/acpuclock.c
@@ -172,13 +172,20 @@
 
 	clock_usb30_gdsc_enable();
 
-	ret = clk_get_set_enable("usb30_master_clk", 125000000, true);
+	ret = clk_get_set_enable("usb30_master_clk", 150000000, true);
 	if(ret)
 	{
 		dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
 		ASSERT(0);
 	}
 
+	ret = clk_get_set_enable("gcc_aggre2_usb3_axi_clk", 150000000, true);
+	if (ret)
+	{
+		dprintf(CRITICAL, "failed to set aggre2_usb3_axi_clk, ret = %d\n", ret);
+		ASSERT(0);
+	}
+
 	ret = clk_get_set_enable("usb30_phy_aux_clk", 1200000, true);
 	if(ret)
 	{
diff --git a/platform/thulium/include/platform/iomap.h b/platform/thulium/include/platform/iomap.h
index 7f0cec5..276841d 100644
--- a/platform/thulium/include/platform/iomap.h
+++ b/platform/thulium/include/platform/iomap.h
@@ -104,26 +104,27 @@
 
 /* USB3 clocks */
 #define USB_30_BCR                  (CLK_CTL_BASE + 0xF000)
+#define GCC_USB30_GDSCR             (CLK_CTL_BASE + 0xF004)
 #define USB30_MASTER_CBCR           (CLK_CTL_BASE + 0xF008)
+#define USB30_SLEEP_CBCR            (CLK_CTL_BASE + 0xF00C)
+#define USB30_MOCK_UTMI_CBCR        (CLK_CTL_BASE + 0xF010)
 #define USB30_MASTER_CMD_RCGR       (CLK_CTL_BASE + 0xF014)
 #define USB30_MASTER_CFG_RCGR       (CLK_CTL_BASE + 0xF018)
 #define USB30_MASTER_M              (CLK_CTL_BASE + 0xF01C)
 #define USB30_MASTER_N              (CLK_CTL_BASE + 0xF020)
 #define USB30_MASTER_D              (CLK_CTL_BASE + 0xF024)
+#define USB30_MOCK_UTMI_CMD_RCGR    (CLK_CTL_BASE + 0xF028)
+#define USB30_MOCK_UTMI_CFG_RCGR    (CLK_CTL_BASE + 0xF02C)
 #define SYS_NOC_USB3_AXI_CBCR       (CLK_CTL_BASE + 0xF03C)
 
-#define USB30_MOCK_UTMI_CMD_RCGR    (CLK_CTL_BASE + 0xF014)
-#define USB30_MOCK_UTMI_CFG_RCGR    (CLK_CTL_BASE + 0xF018)
-#define USB30_MOCK_UTMI_CBCR        (CLK_CTL_BASE + 0xF010)
-#define USB30_SLEEP_CBCR            (CLK_CTL_BASE + 0xF00C)
 #define USB30_PHY_AUX_CMD_RCGR      (CLK_CTL_BASE + 0x5000C)
 #define USB30_PHY_AUX_CFG_RCGR      (CLK_CTL_BASE + 0x50010)
 #define USB30_PHY_AUX_CBCR          (CLK_CTL_BASE + 0x50000)
 #define USB30_PHY_PIPE_CBCR         (CLK_CTL_BASE + 0x50004)
 #define USB30_PHY_BCR               (CLK_CTL_BASE + 0x50020)
 #define USB30PHY_PHY_BCR            (CLK_CTL_BASE + 0x50024)
-#define GCC_USB30_GDSCR             (CLK_CTL_BASE + 0xF004)
 #define USB_PHY_CFG_AHB2PHY_CBCR    (CLK_CTL_BASE + 0x6A004)
+#define GCC_AGGRE2_USB3_AXI_CBCR    (CLK_CTL_BASE + 0x83018)
 
 /* SDCC */
 #define SDCC1_BCR                   (CLK_CTL_BASE + 0x13000) /* block reset */
diff --git a/platform/thulium/thulium-clock.c b/platform/thulium/thulium-clock.c
index c759df1..d0a23ed 100644
--- a/platform/thulium/thulium-clock.c
+++ b/platform/thulium/thulium-clock.c
@@ -261,8 +261,8 @@
 };
 
 static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
-	F(  19200000, gpll0,    1,    0,    0),
-	F( 125000000, gpll0,    5,    0,    0),
+	F(  19200000, cxo,    1,    0,    0),
+	F( 120000000, gpll0,    5,    0,    0),
 	F( 150000000, gpll0,    4,    0,    0),
 	F_END
 };
@@ -295,6 +295,16 @@
 	},
 };
 
+static struct branch_clk gcc_aggre2_usb3_axi_clk = {
+	.cbcr_reg     = (uint32_t *) GCC_AGGRE2_USB3_AXI_CBCR,
+	.parent       = &usb30_master_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_aggre2_usb3_axi_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src[] = {
 	F(  60000000, gpll0,   10,    0,     0),
 	F_END
@@ -405,6 +415,7 @@
 
 	/* USB30 clocks */
 	CLK_LOOKUP("usb30_master_clk",    gcc_usb30_master_clk.c),
+	CLK_LOOKUP("gcc_aggre2_usb3_axi_clk", gcc_aggre2_usb3_axi_clk.c),
 	CLK_LOOKUP("usb30_iface_clk",     gcc_sys_noc_usb30_axi_clk.c),
 	CLK_LOOKUP("usb30_mock_utmi_clk", gcc_usb30_mock_utmi_clk.c),
 	CLK_LOOKUP("usb30_sleep_clk",     gcc_usb30_sleep_clk.c),
diff --git a/project/apq8084.mk b/project/apq8084.mk
index fb61eea..4ca01bd 100644
--- a/project/apq8084.mk
+++ b/project/apq8084.mk
@@ -32,6 +32,8 @@
 DEFINES += ABOOT_FORCE_TAGS_ADDR=0x01e00000
 DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x00080000
 
+DEFINES += USE_BOOTDEV_CMDLINE=1
+
 ifeq ($(EMMC_BOOT),1)
 DEFINES += _EMMC_BOOT=1
 endif
diff --git a/project/msm8994.mk b/project/msm8994.mk
index f70dbe9..f797e77 100644
--- a/project/msm8994.mk
+++ b/project/msm8994.mk
@@ -34,6 +34,7 @@
 DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x00080000
 
 DEFINES += ENABLE_XPU_VIOLATION=1
+DEFINES += USE_BOOTDEV_CMDLINE=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
diff --git a/project/thulium.mk b/project/thulium.mk
index 8738086..05e764f 100644
--- a/project/thulium.mk
+++ b/project/thulium.mk
@@ -35,6 +35,7 @@
 DEFINES += ABOOT_FORCE_TAGS_ADDR=0x82000000
 DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x80080000
 DEFINES += USB_RESET_FROM_CLK=1
+DEFINES += USE_BOOTDEV_CMDLINE=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index 6aa3b33..543951e 100755
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -285,13 +285,17 @@
 
 	platform_read_boot_config();
 
+#ifdef MMC_SDHCI_SUPPORT
 	if (platform_boot_dev_isemmc())
 		target_sdc_init();
-	else
+#endif
+#ifdef UFS_SUPPORT
+	if(!platform_boot_dev_isemmc())
 	{
 		ufs_device.base = UFS_BASE;
 		ufs_init(&ufs_device);
 	}
+#endif
 
 	/* Storage initialization is complete, read the partition table info */
 	if (partition_read_table())
diff --git a/target/fsm9900/init.c b/target/fsm9900/init.c
index aff6aa6..cc06e0e 100644
--- a/target/fsm9900/init.c
+++ b/target/fsm9900/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -342,6 +342,7 @@
 	case FSM9915:
 	case FSM9950:
 	case FSM9955:
+	case FSM9916:
 		board->baseband = BASEBAND_MSM;
 		break;
 	default:
@@ -369,7 +370,7 @@
 	uint32_t restart_reason = 0;
 	uint32_t restart_reason_addr;
 
-	restart_reason_addr = RESTART_REASON_ADDR;
+	restart_reason_addr = RESTART_REASON_ADDR_V2;
 
 	/* Read reboot reason and scrub it */
 	restart_reason = readl(restart_reason_addr);
@@ -381,7 +382,7 @@
 void reboot_device(unsigned reboot_reason)
 {
 	/* Write the reboot reason */
-	writel(reboot_reason, RESTART_REASON_ADDR);
+	writel(reboot_reason, RESTART_REASON_ADDR_V2);
 
 	/* Disable Watchdog Debug.
 	 * Required becuase of a H/W bug which causes the system to
diff --git a/target/init.c b/target/init.c
index 79e0466..c866187 100644
--- a/target/init.c
+++ b/target/init.c
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
  *
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
  * (the "Software"), to deal in the Software without restriction,
@@ -66,6 +68,11 @@
     return 0;
 }
 
+__WEAK unsigned check_hard_reboot_mode(void)
+{
+    return 0;
+}
+
 __WEAK void reboot_device(unsigned reboot_reason)
 {
 }
diff --git a/target/msm8916/init.c b/target/msm8916/init.c
index 0289973..4b1f26b 100644
--- a/target/msm8916/init.c
+++ b/target/msm8916/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -66,6 +66,7 @@
 #endif
 
 #define FASTBOOT_MODE           0x77665500
+#define PON_SOFT_RB_SPARE       0x88F
 
 #define CE1_INSTANCE            1
 #define CE_EE                   1
@@ -241,6 +242,21 @@
 	return restart_reason;
 }
 
+unsigned check_hard_reboot_mode(void)
+{
+	uint8_t hard_restart_reason = 0;
+	uint8_t value = 0;
+
+	/* Read reboot reason and scrub it
+	  * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
+	  */
+	value = pm8x41_reg_read(PON_SOFT_RB_SPARE);
+	hard_restart_reason = value >> 5;
+	pm8x41_reg_write(PON_SOFT_RB_SPARE, value & 0x1f);
+
+	return hard_restart_reason;
+}
+
 static int scm_dload_mode(int mode)
 {
 	int ret = 0;
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 8c9cdaf..4e2e160 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -322,16 +322,19 @@
 
 	platform_read_boot_config();
 
+#ifdef MMC_SDHCI_SUPPORT
 	if (platform_boot_dev_isemmc())
 	{
 		target_sdc_init();
 	}
-	else
+#endif
+#ifdef UFS_SUPPORT
+	if(!platform_boot_dev_isemmc())
 	{
 		ufs_device.base = UFS_BASE;
 		ufs_init(&ufs_device);
 	}
-
+#endif
 	/* Storage initialization is complete, read the partition table info */
 	mmc_read_partition_table(0);
 
diff --git a/target/msm8994/oem_panel.c b/target/msm8994/oem_panel.c
index 7601c61..de292b5 100644
--- a/target/msm8994/oem_panel.c
+++ b/target/msm8994/oem_panel.c
@@ -157,6 +157,7 @@
 			= SHARP_WQXGA_DUALDSI_VIDEO_OFF_COMMAND;
 		memcpy(phy_db->timing,
 			sharp_wqxga_dualdsi_video_timings, TIMING_SIZE);
+		pinfo->dfps.panel_dfps = sharp_wqxga_dualdsi_video_dfps;
 		break;
 	case JDI_QHD_DUALDSI_VIDEO_PANEL:
 		pan_type = PANEL_TYPE_DSI;
diff --git a/target/msm8994/target_display.c b/target/msm8994/target_display.c
index c347d9f..d8f4bc2 100644
--- a/target/msm8994/target_display.c
+++ b/target/msm8994/target_display.c
@@ -256,9 +256,10 @@
 
 int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
 {
-	uint32_t ret;
+	uint32_t ret = NO_ERROR;
 	struct mdss_dsi_pll_config *pll_data;
 	uint32_t flags;
+	struct dfps_pll_codes *pll_codes = &pinfo->mipi.pll_codes;
 
 	if (pinfo->dest == DISPLAY_2) {
 		flags = MMSS_DSI_CLKS_FLAG_DSI1;
@@ -271,36 +272,53 @@
 	}
 
 	pll_data = pinfo->mipi.dsi_pll_config;
-	if (enable) {
-		mdp_gdsc_ctrl(enable);
-		mmss_bus_clock_enable();
-		mdp_clock_enable();
-		ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
-		if (ret) {
-			dprintf(CRITICAL,
-				"%s: Failed to restore MDP security configs",
-				__func__);
-			mdp_clock_disable();
-			mmss_bus_clock_disable();
-			mdp_gdsc_ctrl(0);
-			return ret;
-		}
-		mdss_dsi_auto_pll_20nm_config(pinfo->mipi.pll_0_base,
-				pinfo->mipi.pll_1_base, pll_data);
-		dsi_pll_20nm_enable_seq(pinfo->mipi.pll_0_base);
-		mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, flags,
-					pll_data->pclk_m,
-					pll_data->pclk_n,
-					pll_data->pclk_d);
-	} else if(!target_cont_splash_screen()) {
-		/* Disable clocks if continuous splash off */
+
+	if (!enable) {
 		mmss_dsi_clock_disable(flags);
-		mdp_clock_disable();
-		mmss_bus_clock_disable();
-		mdp_gdsc_ctrl(enable);
+		goto clks_disable;
 	}
 
+	mdp_gdsc_ctrl(enable);
+	mmss_bus_clock_enable();
+	mdp_clock_enable();
+
+	ret = restore_secure_cfg(SECURE_DEVICE_MDSS);
+	if (ret) {
+		dprintf(CRITICAL,
+			"%s: Failed to restore MDP security configs",
+			__func__);
+		goto clks_disable;
+	}
+
+	mdss_dsi_auto_pll_20nm_config(pinfo->mipi.pll_0_base,
+		pinfo->mipi.pll_1_base, pll_data);
+
+	if (!dsi_pll_20nm_enable_seq(pinfo->mipi.pll_0_base)) {
+		ret = ERROR;
+		dprintf(CRITICAL, "PLL failed to lock!\n");
+		goto clks_disable;
+	}
+
+	pll_codes->codes[0] = readl_relaxed(pinfo->mipi.pll_0_base +
+		MMSS_DSI_PHY_PLL_CORE_KVCO_CODE);
+	pll_codes->codes[1] = readl_relaxed(pinfo->mipi.pll_0_base +
+		MMSS_DSI_PHY_PLL_CORE_VCO_TUNE);
+	dprintf(SPEW, "codes %d %d\n", pll_codes->codes[0],
+		pll_codes->codes[1]);
+
+	mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, flags,
+		pll_data->pclk_m,
+		pll_data->pclk_n,
+		pll_data->pclk_d);
+
 	return NO_ERROR;
+
+clks_disable:
+	mdp_clock_disable();
+	mmss_bus_clock_disable();
+	mdp_gdsc_ctrl(0);
+
+	return ret;
 }
 
 int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
diff --git a/target/thulium/init.c b/target/thulium/init.c
index 6f2a568..28c6b2c 100644
--- a/target/thulium/init.c
+++ b/target/thulium/init.c
@@ -222,22 +222,22 @@
 
 	platform_read_boot_config();
 
+#ifdef MMC_SDHCI_SUPPORT
 	if (platform_boot_dev_isemmc())
 	{
 		target_sdc_init();
 	}
-	else
+#endif
+#ifdef UFS_SUPPORT
+	if (!platform_boot_dev_isemmc())
 	{
 		ufs_device.base = UFS_BASE;
 		ufs_init(&ufs_device);
 	}
+#endif
 
 	/* Storage initialization is complete, read the partition table info */
-	if (partition_read_table())
-	{
-		dprintf(CRITICAL, "Error reading the partition table info\n");
-		ASSERT(0);
-	}
+	mmc_read_partition_table(0);
 }
 
 unsigned board_machtype(void)
@@ -327,9 +327,7 @@
 
 void target_usb_phy_reset()
 {
-#ifndef USE_HSONLY_MODE
 	usb30_qmp_phy_reset();
-#endif
 	qusb2_phy_reset();
 }
 
@@ -340,10 +338,7 @@
 	t_usb_iface = calloc(1, sizeof(target_usb_iface_t));
 	ASSERT(t_usb_iface);
 
-#ifndef USE_HSONLY_MODE
 	t_usb_iface->phy_init   = usb30_qmp_phy_init;
-#endif
-
 	t_usb_iface->phy_reset  = target_usb_phy_reset;
 	t_usb_iface->clock_init = clock_usb30_init;
 	t_usb_iface->vbus_override = 1;
@@ -362,12 +357,6 @@
 	return 1;
 }
 
-void target_fastboot_init(void)
-{
-	/* We are entering fastboot mode, so read partition table */
-	mmc_read_partition_table(1);
-}
-
 crypto_engine_type board_ce_type(void)
 {
 	return CRYPTO_ENGINE_TYPE_SW;