Merge "project: msm8996: Enable power on vibrator"
diff --git a/include/platform.h b/include/platform.h
index 9c8e698..156097e 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -66,10 +66,11 @@
 int platform_is_msm8909();
 int platform_is_msm8992();
 int platform_is_msm8956();
+uint32_t platform_is_msm8976_v_1_1();
 int boot_device_mask(int);
 uint32_t platform_detect_panel();
 uint32_t platform_get_max_periph();
 int platform_is_msm8996();
-uint64_t platform_get_ddr_start();
 bool platform_use_qmp_misc_settings();
+bool platform_is_mdmcalifornium();
 #endif
diff --git a/include/target.h b/include/target.h
index f2e2acd..e05613b 100644
--- a/include/target.h
+++ b/include/target.h
@@ -24,6 +24,7 @@
  */
 #ifndef __TARGET_H
 #define __TARGET_H
+#include <qmp_phy.h>
 
 /* Target helper functions exposed to USB driver */
 typedef struct {
@@ -88,6 +89,9 @@
 bool target_build_variant_user();
 void pmic_reset_configure(uint8_t reset_type);
 
+struct qmp_reg *target_get_qmp_settings();
+int target_get_qmp_regsize();
+
 #if PON_VIB_SUPPORT
 uint32_t get_vibration_type();
 #endif
diff --git a/platform/mdm9640/acpuclock.c b/platform/mdm9640/acpuclock.c
index 40827eb..99fd7d0 100644
--- a/platform/mdm9640/acpuclock.c
+++ b/platform/mdm9640/acpuclock.c
@@ -35,6 +35,7 @@
 #include <platform/clock.h>
 #include <platform/iomap.h>
 #include <platform/timer.h>
+#include <platform.h>
 
 void clock_config_uart_dm(uint8_t id)
 {
@@ -92,7 +93,11 @@
 		ASSERT(0);
 	}
 
-	ret = clk_get_set_enable("usb30_pipe_clk", 19200000, 1);
+	if (platform_is_mdmcalifornium())
+		ret = clk_get_set_enable("usb30_pipe_clk_mdmcalifornium", 0, 1);
+	else
+		ret = clk_get_set_enable("usb30_pipe_clk", 19200000, 1);
+
 	if(ret)
 	{
 		dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
@@ -106,6 +111,20 @@
 		ASSERT(0);
 	}
 
+	ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, true);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_mock_utmi_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb30_sleep_clk", 0, true);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_sleep_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
 	ret = clk_get_set_enable("usb_phy_cfg_ahb_clk", 0, 1);
 	if(ret)
 	{
@@ -169,12 +188,85 @@
 
 void clock_bumpup_pipe3_clk()
 {
-	int ret = 0;
+	int ret =0;
 
-	ret = clk_get_set_enable("usb30_pipe_clk", 125000000, 0);
+	if (platform_is_mdmcalifornium())
+		ret = clk_get_set_enable("usb30_pipe_clk", 0, true);
+	else
+		ret = clk_get_set_enable("usb30_pipe_clk", 125000000, true);
+
 	if(ret)
 	{
 		dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
 		ASSERT(0);
 	}
 }
+
+void clock_reset_usb_phy()
+{
+	int ret;
+
+	struct clk *phy_reset_clk = NULL;
+	struct clk *pipe_reset_clk = NULL;
+	struct clk *master_clk = NULL;
+
+	master_clk = clk_get("usb30_master_clk");
+	ASSERT(master_clk);
+
+	/* Look if phy com clock is present */
+	phy_reset_clk = clk_get("usb30_phy_reset");
+	ASSERT(phy_reset_clk);
+
+	pipe_reset_clk = clk_get("usb30_pipe_clk");
+	ASSERT(pipe_reset_clk);
+
+	/* ASSERT */
+	ret = clk_reset(master_clk, CLK_RESET_ASSERT);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to assert usb30_master_reset clk\n");
+		return;
+	}
+	ret = clk_reset(phy_reset_clk, CLK_RESET_ASSERT);
+
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to assert usb30_phy_reset clk\n");
+		goto deassert_master_clk;
+	}
+
+	ret = clk_reset(pipe_reset_clk, CLK_RESET_ASSERT);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to assert usb30_pipe_clk\n");
+		goto deassert_phy_clk;
+	}
+
+	udelay(100);
+
+	/* DEASSERT */
+	ret = clk_reset(pipe_reset_clk, CLK_RESET_DEASSERT);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to deassert usb_pipe_clk\n");
+		return;
+	}
+
+deassert_phy_clk:
+
+	ret = clk_reset(phy_reset_clk, CLK_RESET_DEASSERT);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to deassert usb30_phy_com_reset clk\n");
+		return;
+	}
+deassert_master_clk:
+
+	ret = clk_reset(master_clk, CLK_RESET_DEASSERT);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to deassert usb30_master clk\n");
+		return;
+	}
+
+}
diff --git a/platform/mdm9640/include/platform/clock.h b/platform/mdm9640/include/platform/clock.h
index e450661..7fdf8a7 100644
--- a/platform/mdm9640/include/platform/clock.h
+++ b/platform/mdm9640/include/platform/clock.h
@@ -35,5 +35,6 @@
 void platform_clock_init(void);
 void clock_config_uart_dm(uint8_t id);
 void clock_usb30_init(void);
+void clock_reset_usb_phy();
 
 #endif
diff --git a/platform/mdm9640/include/platform/iomap.h b/platform/mdm9640/include/platform/iomap.h
index f92f556..2a21206 100644
--- a/platform/mdm9640/include/platform/iomap.h
+++ b/platform/mdm9640/include/platform/iomap.h
@@ -170,9 +170,16 @@
 #define USB3_AUX_D                  (CLK_CTL_BASE + 0x5E06C)
 #define USB3_AUX_CBCR               (CLK_CTL_BASE + 0x5E044)
 
+#define USB30_MOCK_UTMI_CBCR        (CLK_CTL_BASE + 0x5E008)
+#define USB30_SLEEP_CBCR            (CLK_CTL_BASE + 0x5E004)
+#define USB30_MOCK_UTMI_CMD_RCGR    (CLK_CTL_BASE + 0x5E020)
+#define USB30_MOCK_UTMI_CFG_RCGR    (CLK_CTL_BASE + 0x5E024)
+
 /* USB 3.0 phy */
 #define USB3_PHY_BCR                (CLK_CTL_BASE + 0x0005E034)
 
+#define USB_30_BCR                  (CLK_CTL_BASE + 0x0005E070)
+
 /* QUSB2 PHY */
 #define QUSB2_PHY_BASE              0x00079000
 #define GCC_QUSB2_PHY_BCR           (CLK_CTL_BASE + 0x00041028)
@@ -197,5 +204,17 @@
 #define APCS_ALIAS0_IPC_INTERRUPT   0xB011008
 /* eMMC Display */
 #define TLMM_EBI2_EMMC_GPIO_CFG     0x01111000
+
+/* QMP rev registers */
+#define USB3_PHY_REVISION_ID0       (QMP_PHY_BASE + 0x988)
+#define USB3_PHY_REVISION_ID1       (QMP_PHY_BASE + 0x98C)
+#define USB3_PHY_REVISION_ID2       (QMP_PHY_BASE + 0x990)
+#define USB3_PHY_REVISION_ID3       (QMP_PHY_BASE + 0x994)
+
 #define EBI2_BOOT_SELECT            0x2
+#define GCC_RX2_USB2_CLKREF_EN      0x01841030
+#define USB3_PHY_STATUS             0x78974
+/* Register for finding out if single ended or differential clock enablement */
+#define TCSR_PHY_CLK_SCHEME_SEL     0x01956044
+
 #endif
diff --git a/platform/mdm9640/mdm9640-clock.c b/platform/mdm9640/mdm9640-clock.c
index f6b85fb..0d4c26f 100644
--- a/platform/mdm9640/mdm9640-clock.c
+++ b/platform/mdm9640/mdm9640-clock.c
@@ -276,10 +276,10 @@
 	},
 };
 
-
 static struct branch_clk gcc_usb30_master_clk =
 {
 	.cbcr_reg     = (uint32_t *) GCC_USB30_MASTER_CBCR,
+	.bcr_reg      = (uint32_t *) USB_30_BCR,
 	.parent       = &usb30_master_clk_src.c,
 
 	.c = {
@@ -319,6 +319,19 @@
 	},
 };
 
+
+static struct branch_clk gcc_usb30_pipe_clk_mdmcalifornium = {
+	.bcr_reg      = (uint32_t *) USB3_PIPE_BCR,
+	.cbcr_reg     = (uint32_t *) USB3_PIPE_CBCR,
+	.has_sibling  = 1,
+	.halt_check   = 0,
+
+	.c = {
+		.dbg_name = "usb30_pipe_clk_mdmcalifornium",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_usb30_aux_clk[] = {
 	F(   1000000,         cxo,    1,    5,    96),
 	F_END
@@ -369,6 +382,47 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src[] = {
+	F(  60000000, gpll0,   10,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb30_mock_utmi_clk_src = {
+	.cmd_reg      = (uint32_t *) USB30_MOCK_UTMI_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB30_MOCK_UTMI_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_usb30_mock_utmi_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_usb30_mock_utmi_clk = {
+	.cbcr_reg    = (uint32_t *) USB30_MOCK_UTMI_CBCR,
+	.has_sibling = 0,
+	.parent      = &usb30_mock_utmi_clk_src.c,
+
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_usb30_sleep_clk = {
+	.cbcr_reg    = (uint32_t *) USB30_SLEEP_CBCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "usb30_sleep_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+
+
 static struct clk_lookup msm_clocks_9640[] =
 {
 	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
@@ -380,12 +434,15 @@
 	CLK_LOOKUP("usb30_iface_clk",  gcc_sys_noc_usb30_axi_clk.c),
 	CLK_LOOKUP("usb30_master_clk", gcc_usb30_master_clk.c),
 	CLK_LOOKUP("usb30_pipe_clk",   gcc_usb30_pipe_clk.c),
+	CLK_LOOKUP("usb30_pipe_clk_mdmcalifornium",   gcc_usb30_pipe_clk_mdmcalifornium.c),
 	CLK_LOOKUP("usb30_aux_clk",    gcc_usb30_aux_clk.c),
 
 	CLK_LOOKUP("usb2b_phy_sleep_clk", gcc_usb2a_phy_sleep_clk.c),
 	CLK_LOOKUP("usb30_phy_reset",     gcc_usb30_phy_reset.c),
 
+	CLK_LOOKUP("usb30_mock_utmi_clk", gcc_usb30_mock_utmi_clk.c),
 	CLK_LOOKUP("usb_phy_cfg_ahb_clk", gcc_usb_phy_cfg_ahb_clk.c),
+	CLK_LOOKUP("usb30_sleep_clk",     gcc_usb30_sleep_clk.c),
 };
 
 void platform_clock_init(void)
diff --git a/platform/mdm9640/platform.c b/platform/mdm9640/platform.c
index 6ccbe19..f69053c 100644
--- a/platform/mdm9640/platform.c
+++ b/platform/mdm9640/platform.c
@@ -156,14 +156,45 @@
 	return phys_addr;
 }
 
+
+bool platform_is_mdmcalifornium()
+{
+	uint32_t platform_id = board_platform_id();
+	bool ret;
+
+	switch(platform_id)
+	{
+		case MDMCALIFORNIUM1:
+		case MDMCALIFORNIUM2:
+		case MDMCALIFORNIUM3:
+		case MDMCALIFORNIUM4:
+				ret = true;
+				break;
+		default:
+				ret = false;
+	};
+
+	return ret;
+}
+
 uint32_t platform_boot_config()
 {
 	uint32_t boot_config;
 
-	if (board_soc_version() >= 0x20000)
+	if (platform_is_mdmcalifornium())
+		boot_config = BOOT_CONFIG_REG_V2;
+	/* Else the platform is 9x45 */
+	else if (board_soc_version() >= 0x20000)
 		boot_config = BOOT_CONFIG_REG_V2;
 	else
 		boot_config = BOOT_CONFIG_REG_V1;
 
 	return boot_config;
 }
+
+uint32_t platform_get_qmp_rev()
+{
+	return readl(USB3_PHY_REVISION_ID3) << 24 | readl(USB3_PHY_REVISION_ID2) << 16 |
+		   readl(USB3_PHY_REVISION_ID1) << 8 | readl(USB3_PHY_REVISION_ID0);
+}
+
diff --git a/platform/mdmfermium/acpuclock.c b/platform/mdmfermium/acpuclock.c
index 7463222..bd068ad 100644
--- a/platform/mdmfermium/acpuclock.c
+++ b/platform/mdmfermium/acpuclock.c
@@ -37,11 +37,81 @@
 
 void hsusb_clock_init(void)
 {
+	int ret;
+	struct clk *iclk, *cclk;
 
+	ret = clk_get_set_enable("usb_iface_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb_core_clk", 133330000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	mdelay(20);
+
+	iclk = clk_get("usb_iface_clk");
+	cclk = clk_get("usb_core_clk");
+
+	clk_disable(iclk);
+	clk_disable(cclk);
+
+	mdelay(20);
+
+	/* Start the block reset for usb */
+	writel(1, USB_HS_BCR);
+
+	mdelay(20);
+
+	/* Take usb block out of reset */
+	writel(0, USB_HS_BCR);
+
+	mdelay(20);
+
+	ret = clk_enable(iclk);
+
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_enable(cclk);
+
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
+		ASSERT(0);
+	}
 }
 
 /* Configure UART clock based on the UART block id*/
 void clock_config_uart_dm(uint8_t id)
 {
+	int ret;
+	char iclk[64];
+	char cclk[64];
 
+	snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
+	snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
+
+	ret = clk_get_set_enable(iclk, 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable(cclk, 7372800, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
+		ASSERT(0);
+	}
 }
diff --git a/platform/mdmfermium/include/platform/iomap.h b/platform/mdmfermium/include/platform/iomap.h
index d1eb89e..205cd19 100644
--- a/platform/mdmfermium/include/platform/iomap.h
+++ b/platform/mdmfermium/include/platform/iomap.h
@@ -88,18 +88,18 @@
 
 
 /* GPLL */
-#define GPLL0_STATUS                       (CLK_CTL_BASE + 0x21024)
+#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)
 
 /* UART */
 #define BLSP1_AHB_CBCR                     (CLK_CTL_BASE + 0x1008)
-#define BLSP1_UART2_APPS_CBCR              (CLK_CTL_BASE + 0x302C)
-#define BLSP1_UART2_APPS_CMD_RCGR          (CLK_CTL_BASE + 0x3034)
-#define BLSP1_UART2_APPS_CFG_RCGR          (CLK_CTL_BASE + 0x3038)
-#define BLSP1_UART2_APPS_M                 (CLK_CTL_BASE + 0x303C)
-#define BLSP1_UART2_APPS_N                 (CLK_CTL_BASE + 0x3040)
-#define BLSP1_UART2_APPS_D                 (CLK_CTL_BASE + 0x3044)
+#define BLSP1_UART5_APPS_CBCR              (CLK_CTL_BASE + 0x603c)
+#define BLSP1_UART5_APPS_CMD_RCGR          (CLK_CTL_BASE + 0x6044)
+#define BLSP1_UART5_APPS_CFG_RCGR          (CLK_CTL_BASE + 0x6048)
+#define BLSP1_UART5_APPS_M                 (CLK_CTL_BASE + 0x604C)
+#define BLSP1_UART5_APPS_N                 (CLK_CTL_BASE + 0x6050)
+#define BLSP1_UART5_APPS_D                 (CLK_CTL_BASE + 0x6054)
 
 /* USB */
 #define USB_HS_BCR                         (CLK_CTL_BASE + 0x41000)
diff --git a/platform/mdmfermium/mdmfermium-clock.c b/platform/mdmfermium/mdmfermium-clock.c
index 235d40f..35fbd27 100644
--- a/platform/mdmfermium/mdmfermium-clock.c
+++ b/platform/mdmfermium/mdmfermium-clock.c
@@ -100,8 +100,8 @@
 {
 	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
 	.en_mask      = BIT(0),
-	.status_reg   = (void *) GPLL0_STATUS,
-	.status_mask  = BIT(17),
+	.status_reg   = (void *) GPLL0_MODE,
+	.status_mask  = BIT(30),
 	.parent       = &cxo_clk_src.c,
 
 	.c = {
@@ -112,7 +112,7 @@
 };
 
 /* UART Clocks */
-static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_2_apps_clk[] =
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart5_apps_clk[] =
 {
 	F( 3686400,  gpll0,    1,  72,  15625),
 	F( 7372800,  gpll0,    1, 144,  15625),
@@ -132,16 +132,16 @@
 	F_END
 };
 
-static struct rcg_clk blsp1_uart2_apps_clk_src =
+static struct rcg_clk blsp1_uart5_apps_clk_src =
 {
-	.cmd_reg      = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
-	.cfg_reg      = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
-	.m_reg        = (uint32_t *) BLSP1_UART2_APPS_M,
-	.n_reg        = (uint32_t *) BLSP1_UART2_APPS_N,
-	.d_reg        = (uint32_t *) BLSP1_UART2_APPS_D,
+	.cmd_reg      = (uint32_t *) BLSP1_UART5_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART5_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART5_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART5_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART5_APPS_D,
 
 	.set_rate     = clock_lib2_rcg_set_rate_mnd,
-	.freq_tbl     = ftbl_gcc_blsp1_2_uart1_2_apps_clk,
+	.freq_tbl     = ftbl_gcc_blsp1_2_uart5_apps_clk,
 	.current_freq = &rcg_dummy_freq,
 
 	.c = {
@@ -150,13 +150,13 @@
 	},
 };
 
-static struct branch_clk gcc_blsp1_uart2_apps_clk =
+static struct branch_clk gcc_blsp1_uart5_apps_clk =
 {
-	.cbcr_reg     = (uint32_t *) BLSP1_UART2_APPS_CBCR,
-	.parent       = &blsp1_uart2_apps_clk_src.c,
+	.cbcr_reg     = (uint32_t *) BLSP1_UART5_APPS_CBCR,
+	.parent       = &blsp1_uart5_apps_clk_src.c,
 
 	.c = {
-		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.dbg_name = "gcc_blsp1_uart5_apps_clk",
 		.ops      = &clk_ops_branch,
 	},
 };
@@ -219,8 +219,8 @@
 /* Clock lookup table */
 static struct clk_lookup mdm_clocks_fermium[] =
 {
-	CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
-	CLK_LOOKUP("uart2_core_clk",  gcc_blsp1_uart2_apps_clk.c),
+	CLK_LOOKUP("uart5_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("uart5_core_clk",  gcc_blsp1_uart5_apps_clk.c),
 
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
 	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
index e3aaec3..ec37789 100644
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -132,7 +132,12 @@
 	}
 	else if(freq == MMC_CLK_192MHZ)
 	{
-		ret = clk_get_set_enable(clk_name, 192000000, 1);
+		if (platform_is_msm8956() && platform_is_msm8976_v_1_1())
+
+			ret = clk_get_set_enable(clk_name, 186400000, 1);
+		else
+
+			ret = clk_get_set_enable(clk_name, 192000000, 1);
 	}
 	else if(freq == MMC_CLK_200MHZ)
 	{
@@ -140,7 +145,12 @@
 	}
 	else if(freq == MMC_CLK_400MHZ)
 	{
-		ret = clk_get_set_enable(clk_name, 384000000, 1);
+		if (platform_is_msm8956() && platform_is_msm8976_v_1_1())
+
+			ret = clk_get_set_enable(clk_name, 372800000, 1);
+		else
+
+			ret = clk_get_set_enable(clk_name, 384000000, 1);
 	}
 	else
 	{
@@ -312,16 +322,28 @@
 }
 
 /* Configure all the branch clocks needed by the DSI controller */
-void gcc_dsi_clocks_enable(uint32_t flags, uint8_t pclk0_m,
+void gcc_dsi_clocks_enable(uint32_t flags, bool use_dsi1_pll, uint8_t pclk0_m,
 		uint8_t pclk0_n, uint8_t pclk0_d)
 {
 	int ret;
+	int dsi0_cfg_rcgr, dsi1_cfg_rcgr = 0;
+
+	dsi0_cfg_rcgr = BIT(8); /* DSI0 can only be sourced from PLL0 */
+
+	/*
+	 * DSI1<->PLL1 for 1.) 8956 v1.0 always 2.) Single DSI cases on DSI1
+	 * DSI1<->PLL0 for 8956 v1.1 split DSI cases
+	 */
+	if (!platform_is_msm8976_v_1_1() || use_dsi1_pll)
+		dsi1_cfg_rcgr = BIT(8);
+	else if (flags == (MMSS_DSI_CLKS_FLAG_DSI0 | MMSS_DSI_CLKS_FLAG_DSI1))
+		dsi1_cfg_rcgr = BIT(8) | BIT(9);
 
 	if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
 		/* Enable DSI0 branch clocks */
 
 		/* Set the source for DSI0 byte RCG */
-		writel(0x100, DSI_BYTE0_CFG_RCGR);
+		writel(dsi0_cfg_rcgr, DSI_BYTE0_CFG_RCGR);
 		/* Set the update RCG bit */
 		writel(0x1, DSI_BYTE0_CMD_RCGR);
 		rcg_update_config(DSI_BYTE0_CMD_RCGR);
@@ -331,7 +353,7 @@
 
 		/* Configure Pixel clock */
 		/* Set the source for DSI0 pixel RCG */
-		writel(0x100, DSI_PIXEL0_CFG_RCGR);
+		writel(dsi0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
 		/* Set the MND for DSI0 pixel clock */
 		writel(pclk0_m, DSI_PIXEL0_M);
 		writel(pclk0_n, DSI_PIXEL0_N);
@@ -355,7 +377,7 @@
 		/* Enable DSI1 branch clocks */
 
 		/* Set the source for DSI1 byte RCG */
-		writel(0x100, DSI_BYTE1_CFG_RCGR);
+		writel(dsi1_cfg_rcgr, DSI_BYTE1_CFG_RCGR);
 		/* Set the update RCG bit */
 		writel(0x1, DSI_BYTE1_CMD_RCGR);
 		rcg_update_config(DSI_BYTE1_CMD_RCGR);
@@ -365,7 +387,7 @@
 
 		/* Configure Pixel clock */
 		/* Set the source for DSI1 pixel RCG */
-		writel(0x100, DSI_PIXEL1_CFG_RCGR);
+		writel(dsi1_cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
 		/* Set the MND for DSI1 pixel clock */
 		writel(pclk0_m, DSI_PIXEL1_M);
 		writel(pclk0_n, DSI_PIXEL1_N);
diff --git a/platform/msm8952/include/platform/clock.h b/platform/msm8952/include/platform/clock.h
index f6e962a..c9e8cc7 100644
--- a/platform/msm8952/include/platform/clock.h
+++ b/platform/msm8952/include/platform/clock.h
@@ -95,7 +95,7 @@
 void mdss_bus_clocks_disable(void);
 void mdp_clock_enable(void);
 void mdp_clock_disable(void);
-void gcc_dsi_clocks_enable(uint32_t flags, uint8_t pclk0_m,
+void gcc_dsi_clocks_enable(uint32_t flags,  bool use_dsi1_pll, uint8_t pclk0_m,
 		uint8_t pclk0_n, uint8_t pclk0_d);
 void gcc_dsi_clocks_disable(uint32_t flags);
 #endif
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index f58b033..c135f3f 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -102,6 +102,7 @@
 
 /* GPLL */
 #define GPLL0_STATUS                       (CLK_CTL_BASE + 0x2101C)
+#define GPLL2_STATUS                       (CLK_CTL_BASE + 0x4A01C)
 #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)
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
index b87406d..3214895 100644
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -39,6 +39,7 @@
 /* Mux source select values */
 #define cxo_source_val    0
 #define gpll0_source_val  1
+#define gpll2_source_val  4
 #define gpll4_source_val  2
 #define cxo_mm_source_val 0
 #define gpll0_mm_source_val 6
@@ -112,6 +113,21 @@
 	},
 };
 
+static struct pll_vote_clk gpll2_clk_src =
+{
+	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
+	.en_mask      = BIT(2),
+	.status_reg   = (void *) GPLL2_STATUS,
+	.status_mask  = BIT(17),
+	.parent       = &cxo_clk_src.c,
+
+	.c = {
+		.rate     = 932000000,
+		.dbg_name = "gpll2_clk_src",
+		.ops      = &clk_ops_pll_vote,
+	},
+};
+
 static struct pll_vote_clk gpll4_clk_src =
 {
 	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
@@ -157,6 +173,21 @@
 	F_END
 };
 
+/* SDCC Clocks for version 8976 v 1.1*/
+static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk_8976_v_1_1[] =
+{
+	F(   144000,    cxo,  16,   3,  25),
+	F(   400000,    cxo,  12,   1,   4),
+	F( 20000000,  gpll0,  10,   1,   4),
+	F( 25000000,  gpll0,  16,   1,   2),
+	F( 50000000,  gpll0,  16,   0,   0),
+	F(100000000,  gpll0,   8,   0,   0),
+	F(177770000,  gpll0, 4.5,   0,   0),
+	F(186400000,  gpll2,   5,   0,   0),
+	F(372800000,  gpll2, 2.5,   0,   0),
+	F_END
+};
+
 static struct rcg_clk sdcc1_apps_clk_src =
 {
 	.cmd_reg      = (uint32_t *) SDCC1_CMD_RCGR,
@@ -594,9 +625,18 @@
 	mdss_mdp_clk_src.freq_tbl = ftbl_mdp_clk_8956;
 }
 
+void msm8976_v_1_1_sdcc_clock_modify()
+{
+	sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_8976_v_1_1;
+}
+
 void platform_clock_init(void)
 {
-	if (platform_is_msm8956())
+	if (platform_is_msm8956()) {
 		msm8956_clock_override();
+		if (platform_is_msm8976_v_1_1())
+			/*freq and GPLL change for 8976 v1.1 */
+			msm8976_v_1_1_sdcc_clock_modify();
+	}
 	clk_init(msm_clocks_8952, ARRAY_SIZE(msm_clocks_8952));
 }
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
index ec5a1d8..8adaf4c 100644
--- a/platform/msm8952/platform.c
+++ b/platform/msm8952/platform.c
@@ -41,6 +41,7 @@
 #include <platform.h>
 #include <target/display.h>
 
+#define MSM8976_SOC_V11 0x10001
 #define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
 #define APPS_SS_SIZE   ((APPS_SS_END - APPS_SS_BASE)/MB)
 
@@ -194,3 +195,14 @@
 
 	return ret;
 }
+
+uint32_t platform_is_msm8976_v_1_1()
+{
+	uint32_t soc_ver = board_soc_version();
+	uint32_t ret = 0;
+
+	if(soc_ver == MSM8976_SOC_V11)
+		ret = 1;
+
+	return ret;
+}
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 7efabc6..265d7c7 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -551,9 +551,4 @@
 #define APPS_WDOG_RESET_REG         (APSS_WDOG_BASE + 0x04)
 #define APPS_WDOG_CTL_REG           (APSS_WDOG_BASE + 0x08)
 
-#define DDR_START                    platform_get_ddr_start()
-#define ABOOT_FORCE_KERNEL_ADDR      DDR_START + 0x8000
-#define ABOOT_FORCE_RAMDISK_ADDR     DDR_START + 0x2200000
-#define ABOOT_FORCE_TAGS_ADDR        DDR_START + 0x2000000
-#define ABOOT_FORCE_KERNEL64_ADDR    DDR_START + 0x80000
 #endif
diff --git a/platform/msm8996/platform.c b/platform/msm8996/platform.c
index 6bad8f6..79bf7c9 100644
--- a/platform/msm8996/platform.c
+++ b/platform/msm8996/platform.c
@@ -68,19 +68,12 @@
 /*       Physical addr,    Virtual addr,     Mapping type ,              Size (in MB),            Flags */
     {    0x00000000,        0x00000000,       MMU_L2_NS_SECTION_MAPPING,  512,                IOMAP_MEMORY},
     {    MEMBASE,           MEMBASE,          MMU_L2_NS_SECTION_MAPPING,  (MEMSIZE / MB),      LK_MEMORY},
+    {    KERNEL_ADDR,       KERNEL_ADDR,      MMU_L2_NS_SECTION_MAPPING,  KERNEL_SIZE,         SCRATCH_MEMORY},
     {    SCRATCH_ADDR,      SCRATCH_ADDR,     MMU_L2_NS_SECTION_MAPPING,  SCRATCH_SIZE,        SCRATCH_MEMORY},
     {    MSM_SHARED_BASE,   MSM_SHARED_BASE,  MMU_L2_NS_SECTION_MAPPING,  MSM_SHARED_SIZE,     COMMON_MEMORY},
     {    RPMB_SND_RCV_BUF,  RPMB_SND_RCV_BUF, MMU_L2_NS_SECTION_MAPPING,  RPMB_SND_RCV_BUF_SZ, IOMAP_MEMORY},
 };
 
-static mmu_section_t default_mmu_section_table_3gb[] =
-{
-/*       Physical addr,    Virtual addr,     Mapping type ,              Size (in MB),            Flags */
-    {    0x40000000,        0x40000000,       MMU_L1_NS_SECTION_MAPPING,  1024       ,        COMMON_MEMORY},
-    {    0x80000000,        0x80000000,       MMU_L2_NS_SECTION_MAPPING,  88         ,        COMMON_MEMORY},
-};
-
-
 /* Map the ddr for download mode, this region belongs to non-hlos images and pil */
 static mmu_section_t dload_mmu_section_table[] =
 {
@@ -122,52 +115,11 @@
 {
 	int i;
 	int table_sz = ARRAY_SIZE(default_mmu_section_table);
-	mmu_section_t kernel_mmu_section_table;
-	uint64_t ddr_size = smem_get_ddr_size();
-	uint32_t kernel_size = 0;
-
-	if (ddr_size == MEM_4GB)
-	{
-		ddr_start = 0x80000000;
-		/* As per the memory map when DDR is 4GB first 88 MB is hlos memory
-		 * use this for loading the kernel
-		 */
-		kernel_size = 88;
-	}
-	else if (ddr_size == MEM_3GB)
-	{
-		ddr_start = 0x20000000;
-		/* As per memory map wheh DDR is 3GB the first 512 MB is assigned to hlos
-		 * use this region for loading kernel
-		 */
-		kernel_size = 512;
-	}
-	else
-	{
-		dprintf(CRITICAL, "Unsupported memory map\n");
-		ASSERT(0);
-	}
-
-	kernel_mmu_section_table.paddress = ddr_start;
-	kernel_mmu_section_table.vaddress = ddr_start;
-	kernel_mmu_section_table.type = MMU_L2_NS_SECTION_MAPPING;
-	kernel_mmu_section_table.size = kernel_size;
-	kernel_mmu_section_table.flags = SCRATCH_MEMORY;
-
-	/* Map kernel entry */
-	arm_mmu_map_entry(&kernel_mmu_section_table);
 
 	/* Map default memory needed for lk , scratch, rpmb & iomap */
 	for (i = 0 ; i < table_sz; i++)
 		arm_mmu_map_entry(&default_mmu_section_table[i]);
 
-	/* Map the rest of the DDR for 3GB needed for ramdump */
-	if (ddr_size == MEM_3GB)
-	{
-		for (i = 0 ; i < (int)ARRAY_SIZE(default_mmu_section_table_3gb); i++)
-			arm_mmu_map_entry(&default_mmu_section_table_3gb[i]);
-	}
-
 	if (scm_device_enter_dload())
 	{
 		/* TZ & Hyp memory can be mapped only while entering the download mode */
diff --git a/platform/msm_shared/clock_lib2.c b/platform/msm_shared/clock_lib2.c
index ad088cb..50042f2 100644
--- a/platform/msm_shared/clock_lib2.c
+++ b/platform/msm_shared/clock_lib2.c
@@ -32,7 +32,7 @@
 #include <clock.h>
 #include <clock_pll.h>
 #include <clock_lib2.h>
-
+#include <platform/timer.h>
 
 /*=============== CXO clock ops =============*/
 int cxo_clk_enable(struct clk *clk)
@@ -55,14 +55,32 @@
 {
 	int rc = 0;
 	uint32_t cbcr_val;
+	int retry = 100;
 	struct branch_clk *bclk = to_branch_clk(clk);
 
 	cbcr_val  = readl(bclk->cbcr_reg);
 	cbcr_val |= CBCR_BRANCH_ENABLE_BIT;
 	writel(cbcr_val, bclk->cbcr_reg);
 
+	/* Some clocks do not need to check the enable status, return
+	 * if the halt_check is not set
+	 */
+	if (!bclk->halt_check)
+		return rc;
+
 	/* wait until status shows it is enabled */
-	while(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT);
+	while(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT)
+	{
+		/* Add 100 ms of time out, bail out if the clock is not enable
+		 * within 100 ms */
+		if (!retry)
+		{
+			rc = 1;
+			break;
+		}
+		retry--;
+		mdelay(1);
+	}
 
 	return rc;
 }
diff --git a/platform/msm_shared/include/qusb2_phy.h b/platform/msm_shared/include/qusb2_phy.h
index fc971c8..d3ed338 100644
--- a/platform/msm_shared/include/qusb2_phy.h
+++ b/platform/msm_shared/include/qusb2_phy.h
@@ -32,6 +32,8 @@
 
 void qusb2_phy_reset(void);
 
+#define QUSB2PHY_PLL_LOCK        0x20
+
 #define QUSB2PHY_PORT_POWERDOWN     (QUSB2_PHY_BASE + 0x000000B4)
 #define QUSB2PHY_PORT_UTMI_CTRL2    (QUSB2_PHY_BASE + 0x000000C4)
 #define QUSB2PHY_PLL_TEST           (QUSB2_PHY_BASE + 0x00000004)
@@ -45,6 +47,7 @@
 #define QUSB2PHY_PORT_TEST2         (QUSB2_PHY_BASE + 0x0000009C)
 #define QUSB2PHY_PLL_PWR_CTL        (QUSB2_PHY_BASE + 0x00000018)
 #define QUSB2PHY_PLL_AUTOPGM_CTL1   (QUSB2_PHY_BASE + 0x0000001C)
+#define QUSB2PHY_PLL_STATUS         (QUSB2_PHY_BASE + 0x00000038)
 
 
 #endif
diff --git a/platform/msm_shared/qmp_usb30_phy.c b/platform/msm_shared/qmp_usb30_phy.c
index 56b009a..a558cea 100644
--- a/platform/msm_shared/qmp_usb30_phy.c
+++ b/platform/msm_shared/qmp_usb30_phy.c
@@ -37,6 +37,7 @@
 #include <debug.h>
 #include <qtimer.h>
 #include <platform.h>
+#include <target.h>
 
 #define HS_PHY_COMMON_CTRL             0xEC
 #define USE_CORECLK                    BIT(14)
@@ -256,12 +257,30 @@
 void usb30_qmp_phy_init()
 {
 	int timeout = QMP_PHY_MAX_TIMEOUT;
-	uint32_t rev_id = 0;
 	uint32_t phy_status = 0;
 	uint32_t qmp_reg_size;
 	uint32_t i;
 
-	rev_id = platform_get_qmp_rev();
+
+#if USE_TARGET_QMP_SETTINGS
+	struct qmp_reg *target_qmp_settings = NULL;
+	qmp_reg_size = target_get_qmp_regsize();
+	target_qmp_settings = target_get_qmp_settings();
+	if (qmp_reg_size && target_qmp_settings)
+	{
+		for (i = 0 ; i < qmp_reg_size; i++)
+		{
+			/* As per the hw document we need to add a delay of 1 ms after setting
+			 * QSERDES_COM_RESETSM_CNTRL2 and before setting QSERDES_COM_CMN_CONFIG */
+			if (i == 7)
+				mdelay(1);
+			writel(target_qmp_settings[i].val, QMP_PHY_BASE + target_qmp_settings[i].off);
+		}
+	goto phy_status;
+	}
+#endif
+
+	uint32_t rev_id = platform_get_qmp_rev();
 
 	/* Sequence as per HPG */
 	writel(0x01, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_DOWN_CONTROL);
@@ -342,12 +361,25 @@
 		writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START);
 	}
 
-	if (rev_id >= 0x20000000)
-		phy_status = 0x77c;
-	else
-		phy_status = 0x728;
+#if USE_TARGET_QMP_SETTINGS
+phy_status:
+#endif
 
-	while ((readl(QMP_PHY_BASE + phy_status) & PHYSTATUS))
+	/* For future targets defined USB3_PHY_STATUS in the iomap.h
+	 * Initial version of driver was written thinking phy_status register
+	 * address would not change, but the address keeps changing for every chip
+	 * so better get the address from iomap amd keep the backward compatibility
+	 */
+#if USB3_PHY_STATUS
+	phy_status = USB3_PHY_STATUS;
+#else
+	if (rev_id >= 0x20000000)
+		phy_status = QMP_PHY_BASE + 0x77c;
+	else
+		phy_status = QMP_PHY_BASE + 0x728;
+#endif
+
+	while ((readl(phy_status) & PHYSTATUS))
 	{
 		udelay(1);
 		timeout--;
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
index 0c9077b..8543e97 100644
--- a/platform/msm_shared/qseecom_lk.c
+++ b/platform/msm_shared/qseecom_lk.c
@@ -850,6 +850,7 @@
 	struct qseecom_client_send_data_ireq send_data_req;
 	struct qseecom_command_scm_resp resp;
 	void *buf = NULL;
+	void *rsp_buf_temp = NULL;
 	uint32_t size = 0;
 
 	if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
@@ -859,10 +860,19 @@
 	}
 	dprintf(SPEW, "%s called\n", __func__);
 
-	/* Allocate for req or rsp len whichever is higher, both req and rsp point
-	 * to the same buffer
-	 */
-	size = (req->cmd_req_len > req->resp_len) ? req->cmd_req_len : req->resp_len;
+	if (req->cmd_req_len > (UINT_MAX - req->resp_len)) {
+		dprintf(CRITICAL, "%s:Integer overflow\n", __func__);
+		dprintf(CRITICAL, "req->cmd_req_len: %u\n", req->cmd_req_len);
+		dprintf(CRITICAL, "req->resp_len: %u\n", req->resp_len);
+		return GENERIC_ERROR;
+	}
+
+	if ((req->cmd_req_len + req->resp_len) > (RPMB_SND_RCV_BUF_SZ * 1024 * 1024)) {
+		dprintf(CRITICAL, "%s:Cmd + Rsp len greater than TA buf\n", __func__);
+		dprintf(CRITICAL, "req->cmd_req_len: %u\n", req->cmd_req_len);
+		dprintf(CRITICAL, "req->resp_len: %u\n", req->resp_len);
+		return GENERIC_ERROR;
+	}
 
 	/* The req rsp buffer will be xPU protected by TZ during a TZ APP call
 	 * This will still be protected during a listener call and there is a
@@ -878,8 +888,6 @@
 		return GENERIC_ERROR;
 	}
 
-	memscpy(buf, ROUNDUP(size, PAGE_SIZE), req->cmd_req_buf, req->cmd_req_len);
-
 	send_data_req.qsee_cmd_id = QSEE_CLIENT_SEND_DATA_COMMAND;
 	send_data_req.app_id = app_id;
 
@@ -888,14 +896,20 @@
 	 */
 	send_data_req.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
 	send_data_req.req_len = req->cmd_req_len;
-	send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	size = ROUNDUP(req->cmd_req_len, PAGE_SIZE);
+	rsp_buf_temp = (uint8_t *)buf + size;
+	send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t)rsp_buf_temp);
 	send_data_req.rsp_len = req->resp_len;
 
+	memscpy(buf, (RPMB_SND_RCV_BUF_SZ * 1024 * 1024), req->cmd_req_buf, req->cmd_req_len);
+	memscpy(rsp_buf_temp, req->resp_len, req->resp_buf, req->resp_len);
+
 	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
 				(void *)&send_data_req,
 				sizeof(send_data_req), (void *)&resp, sizeof(resp));
 
-	memscpy(req->resp_buf, req->resp_len, (void *)send_data_req.rsp_ptr, send_data_req.rsp_len);
+	memscpy(req->cmd_req_buf, req->cmd_req_len, (void *)buf, send_data_req.req_len);
+	memscpy(req->resp_buf, req->resp_len, (void *)rsp_buf_temp, send_data_req.rsp_len);
 	return ret;
 }
 
@@ -941,6 +955,16 @@
 					__func__, ret);
 			goto err;
 		}
+                dprintf(DEBUG, "Loading cmnlib done\n");
+#if ENABLE_CMNLIB64_LOADING
+                ret = qseecom_load_commonlib_image("cmnlib64");
+                if (ret) {
+                        dprintf(CRITICAL, "%s qseecom_load_commonlib_image failed with status:%d\n",
+                                        __func__, ret);
+                        goto err;
+                }
+                dprintf(DEBUG, "Loading cmnlib64 done\n");
+#endif
 		qseecom.cmnlib_loaded = 1;
 	}
 	/* Check if App already exits, if exits increase ref_cnt
diff --git a/platform/msm_shared/qusb2_phy.c b/platform/msm_shared/qusb2_phy.c
index 8981df7..ced1fea 100644
--- a/platform/msm_shared/qusb2_phy.c
+++ b/platform/msm_shared/qusb2_phy.c
@@ -32,6 +32,7 @@
 #include <bits.h>
 #include <debug.h>
 #include <qtimer.h>
+#include <platform.h>
 
 __WEAK int platform_is_msm8994()
 {
@@ -43,12 +44,24 @@
 	return 0;
 }
 
+__WEAK int platform_is_mdmcalifornium()
+{
+	return 0;
+}
+
 void qusb2_phy_reset(void)
 {
 	uint32_t val;
 	/* Default tune value */
 	uint8_t tune2 = 0xB3;
+	int retry = 100;
+	int se_clock = 1;
 
+	/* Disable the ref clock before phy reset */
+#if GCC_RX2_USB2_CLKREF_EN
+	writel((readl(GCC_RX2_USB2_CLKREF_EN) & ~0x1), GCC_RX2_USB2_CLKREF_EN);
+	dmb();
+#endif
 	/* Block Reset */
 	val = readl(GCC_QUSB2_PHY_BCR) | BIT(0);
 	writel(val, GCC_QUSB2_PHY_BCR);
@@ -62,7 +75,7 @@
 	/* set CLAMP_N_EN and stay with disabled USB PHY */
 	writel(0x23, QUSB2PHY_PORT_POWERDOWN);
 
-	if (platform_is_msm8996())
+	if (platform_is_msm8996() || platform_is_mdmcalifornium())
 	{
 		writel(0xF8, QUSB2PHY_PORT_TUNE1);
 		/* Upper nibble of tune2 register should be updated based on the fuse value.
@@ -83,7 +96,19 @@
 		writel(0x79, QUSB2PHY_PLL_USER_CTL1);
 		writel(0x21, QUSB2PHY_PLL_USER_CTL2);
 		writel(0x14, QUSB2PHY_PORT_TEST2);
-		writel(0x80, QUSB2PHY_PLL_TEST);
+		/* TCSR register bit 0 indicates whether single ended clock
+		 * or differential clock configuration is enabled. Based on the
+		 * configuration set the PLL_TEST register.
+		 */
+#if TCSR_PHY_CLK_SCHEME_SEL
+		se_clock = readl(TCSR_PHY_CLK_SCHEME_SEL) & 0x1;
+#endif
+		/* By default consider differential clock configuration and if TCSR
+		 * register bit 0 is not set then use single ended setting
+		 */
+		if (se_clock)
+			writel(0x80, QUSB2PHY_PLL_TEST);
+
 		writel(0x9F, QUSB2PHY_PLL_AUTOPGM_CTL1);
 		writel(0x00, QUSB2PHY_PLL_PWR_CTL);
 	}
@@ -105,12 +130,28 @@
 	/* Wait for tuning params to take effect right before re-enabling power*/
 	udelay(10);
 
-	/* Disable the PHY */
-	writel(0x23, QUSB2PHY_PORT_POWERDOWN);
 	/* Enable ULPI mode */
 	if (platform_is_msm8994())
 		writel(0x0,  QUSB2PHY_PORT_UTMI_CTRL2);
 	/* Enable PHY */
 	/* set CLAMP_N_EN and USB PHY is enabled*/
 	writel(0x22, QUSB2PHY_PORT_POWERDOWN);
+	mdelay(10);
+
+#if GCC_RX2_USB2_CLKREF_EN
+	writel((readl(GCC_RX2_USB2_CLKREF_EN) | 0x1), GCC_RX2_USB2_CLKREF_EN);
+	dmb();
+#endif
+
+	/* Check PLL status */
+	while (!(readl(QUSB2PHY_PLL_STATUS) & QUSB2PHY_PLL_LOCK))
+	{
+		retry--;
+		udelay(100);
+		if (!retry)
+		{
+			dprintf(CRITICAL, "QUSB2PHY failed to lock: %d", readl(QUSB2PHY_PLL_STATUS));
+			break;
+		}
+	}
 }
diff --git a/platform/msm_shared/reboot.c b/platform/msm_shared/reboot.c
index 8f53633..6d97b0c 100644
--- a/platform/msm_shared/reboot.c
+++ b/platform/msm_shared/reboot.c
@@ -71,12 +71,13 @@
 	uint8_t hard_restart_reason = 0;
 
 	/* Read reboot reason and scrub it
-	 * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
+	 * Bit-2 to bit-7 of SOFT_RB_SPARE for hard reset reason
 	 */
 	hard_restart_reason = REG_READ(PON_SOFT_RB_SPARE);
-	REG_WRITE(PON_SOFT_RB_SPARE, hard_restart_reason & 0x1f);
+	REG_WRITE(PON_SOFT_RB_SPARE, hard_restart_reason & 0x03);
 
-	return hard_restart_reason;
+	/* Extract the bits 5 to 7 and return */
+	return hard_restart_reason & 0xFC;
 }
 
 /* Return true if it is triggered by alarm. */
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index df4b136..ae381bc 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -1064,36 +1064,40 @@
 	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);
 
 	if (!scm_arm_support)
 	{
-		data.out_buf     = (uint8_t*) rbuf;
+		data.out_buf     = (uint8_t*) rand_buf;
 		data.out_buf_size = r_len;
 
 		/*
 		 * random buffer must be flushed/invalidated before and after TZ call.
 		 */
-		arch_clean_invalidate_cache_range((addr_t) rbuf, r_len);
+		arch_clean_invalidate_cache_range((addr_t) rand_buf, r_len);
 
 		ret = scm_call(TZ_SVC_CRYPTO, PRNG_CMD_ID, &data, sizeof(data), NULL, 0);
 
 		/* Invalidate the updated random buffer */
-		arch_clean_invalidate_cache_range((addr_t) rbuf, r_len);
+		arch_clean_invalidate_cache_range((addr_t) rand_buf, r_len);
 	}
 	else
 	{
 		scm_arg.x0 = MAKE_SIP_SCM_CMD(TZ_SVC_CRYPTO, PRNG_CMD_ID);
 		scm_arg.x1 = MAKE_SCM_ARGS(0x2,SMC_PARAM_TYPE_BUFFER_READWRITE);
-		scm_arg.x2 = (uint32_t) rbuf;
+		scm_arg.x2 = (uint32_t) rand_buf;
 		scm_arg.x3 = r_len;
 
 		ret = scm_call2(&scm_arg, NULL);
 		if (!ret)
-			arch_clean_invalidate_cache_range((addr_t) rbuf, r_len);
+			arch_clean_invalidate_cache_range((addr_t) rand_buf, r_len);
 		else
 			dprintf(CRITICAL, "Secure canary SCM failed: %x\n", ret);
 	}
 
+	//Copy back into the return buffer
+	memcpy(rbuf, rand_buf, r_len);
 	return ret;
 }
 
@@ -1195,14 +1199,14 @@
 
 	if ((arg->x1 & 0xF) > SCM_MAX_ARG_LEN - 1)
 	{
-		indir_arg = memalign(CACHE_LINE, (SCM_INDIR_MAX_LEN * sizeof(uint32_t)));
+		indir_arg = memalign(CACHE_LINE, ROUNDUP((SCM_INDIR_MAX_LEN * sizeof(uint32_t)), CACHE_LINE));
 		ASSERT(indir_arg);
 
 		for (i = 0 ; i < SCM_INDIR_MAX_LEN; i++)
 		{
 			indir_arg[i] = arg->x5[i];
 		}
-		arch_clean_invalidate_cache_range((addr_t) indir_arg, (SCM_INDIR_MAX_LEN * sizeof(uint32_t)));
+		arch_clean_invalidate_cache_range((addr_t) indir_arg, ROUNDUP((SCM_INDIR_MAX_LEN * sizeof(uint32_t)), CACHE_LINE));
 		x5 = (addr_t) indir_arg;
 	}
 
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 7abfbc9..312a33d 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -435,7 +435,11 @@
 	MDMCALIFORNIUM4  = 285,
 	MDMCALIFORNIUM5  = 286,
 	APQ8052  = 289,
-	MDMFERMIUM  = 290,
+	MDMFERMIUM1 = 290,
+	MDMFERMIUM2  = 296,
+	MDMFERMIUM3  = 297,
+	MDMFERMIUM4  = 298,
+	MDMFERMIUM5  = 299,
 	APQ8096  = 291,
 	MSMTITANIUM  = 293,
 };
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
index aaf17a8..63de398 100644
--- a/platform/msm_shared/ucs.c
+++ b/platform/msm_shared/ucs.c
@@ -446,9 +446,6 @@
 		return -UFS_FAILURE;
 	}
 
-	/* Flush buffer. */
-	arch_invalidate_cache_range((addr_t) param, SCSI_INQUIRY_LEN);
-
 	return UFS_SUCCESS;
 }
 
@@ -468,7 +465,7 @@
 	STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sense_cdb));
 	struct scsi_req_build_type req_upiu;
 	struct scsi_sense_cdb      *cdb_param;
-	uint8_t                    buf[SCSI_SENSE_BUF_LEN];
+	STACKBUF_DMA_ALIGN(buf, SCSI_SENSE_BUF_LEN);
 
 	cdb_param = (struct scsi_sense_cdb *) cdb;
 
diff --git a/project/mdm9640.mk b/project/mdm9640.mk
index 24addd8..2aa002a 100644
--- a/project/mdm9640.mk
+++ b/project/mdm9640.mk
@@ -45,5 +45,9 @@
 DEFINES += SMD_SUPPORT=1
 endif
 
+# Reset USB clock from target code
+DEFINES += USB_RESET_FROM_CLK=1
+
 # Turn on Werror
 CFLAGS += -Werror
+DEFINES += USE_TARGET_QMP_SETTINGS=1
diff --git a/project/mdmfermium.mk b/project/mdmfermium.mk
index 8a7b5f5..96de0cb 100644
--- a/project/mdmfermium.mk
+++ b/project/mdmfermium.mk
@@ -17,6 +17,7 @@
 DEFINES += DEVICE_TREE=1
 DEFINES += CONTIGUOUS_MEMORY=1
 
+DEFINES += SPMI_CORE_V2=1
 DEFINES += BAM_V170=1
 #Disable thumb mode
 ENABLE_THUMB := false
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 60618b0..368dc99 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -36,10 +36,17 @@
 
 DEFINES += ABOOT_IGNORE_BOOT_HEADER_ADDRS=1
 
+DEFINES += ABOOT_FORCE_KERNEL_ADDR=0x80080000
+DEFINES += ABOOT_FORCE_RAMDISK_ADDR=0x82200000
+DEFINES += ABOOT_FORCE_TAGS_ADDR=0x82000000
+DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x80080000
+
 DEFINES += USB_RESET_FROM_CLK=1
 DEFINES += USE_BOOTDEV_CMDLINE=1
 DEFINES += USE_RPMB_FOR_DEVINFO=1
 DEFINES += ENABLE_WBC=1
+#Enable below flag to compile cmnlib64
+#DEFINES += ENABLE_CMNLIB64_LOADING=1
 
 ENABLE_HAP_VIB_SUPPORT := true
 
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 565b0b2..62d48ab 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -54,6 +54,7 @@
 #include <sdhci_msm.h>
 #include <uart_dm.h>
 #include <boot_device.h>
+#include <qmp_phy.h>
 
 extern void smem_ptable_init(void);
 extern void smem_add_modem_partitions(struct ptable *flash_ptable);
@@ -239,6 +240,7 @@
 	struct ptable *ptable;
 	int system_ptn_index = -1;
 	uint32_t buflen;
+	int ret = -1;
 
 	if (!cmdline || !part ) {
 		dprintf(CRITICAL, "WARN: Invalid input param\n");
@@ -274,6 +276,7 @@
 			/* Adding command line parameters according to target boot type */
 			snprintf(*buf, buflen, UBI_CMDLINE);
 			snprintf(*buf+strlen(*buf), buflen, " root=ubi0:rootfs ubi.mtd=%d", system_ptn_index);
+			ret = 0;
 		}
 		else {
 			buflen = strlen("EXT4_CMDLINE") + sizeof(int) +1;
@@ -291,10 +294,11 @@
 				return -1;
 			}
 			snprintf(*buf, buflen, EXT4_CMDLINE"%d", system_ptn_index);
+			ret = 0;
 		}
 	}
 	/*in success case buf will be freed in the calling function of this*/
-	return 0;
+	return ret;
 }
 
 const char * target_usb_controller()
@@ -372,7 +376,14 @@
 
 void target_usb_phy_reset(void)
 {
-	usb30_qmp_phy_reset();
+	/* Reset sequence for californium is different from 9x40, use the reset sequence
+	 * from clock driver
+	 */
+	if (platform_is_mdmcalifornium())
+		clock_reset_usb_phy();
+	else
+		usb30_qmp_phy_reset();
+
 	qusb2_phy_reset();
 }
 
@@ -394,10 +405,123 @@
 
 uint32_t target_override_pll()
 {
-	return 1;
+	if (platform_is_mdmcalifornium())
+		return 0;
+	else
+		return 1;
 }
 
 uint32_t target_get_hlos_subtype()
 {
 	return board_hlos_subtype();
 }
+
+/* QMP settings are different from californium when compared to v2.0/v1.0 hardware.
+ * Use the QMP settings from target code to keep the common driver clean
+ */
+struct qmp_reg qmp_settings[] =
+{
+	{0x804, 0x01}, /*USB3PHY_PCIE_USB3_PCS_POWER_DOWN_CONTROL */
+	{0xAC, 0x14}, /* QSERDES_COM_SYSCLK_EN_SEL */
+	{0x34, 0x08}, /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */
+	{0x174, 0x30}, /* QSERDES_COM_CLK_SELECT */
+	{0x3C, 0x06}, /* QSERDES_COM_SYS_CLK_CTRL */
+	{0xB4, 0x00}, /* QSERDES_COM_RESETSM_CNTRL */
+	{0xB8, 0x08}, /* QSERDES_COM_RESETSM_CNTRL2 */
+	{0x194, 0x06}, /* QSERDES_COM_CMN_CONFIG */
+	{0x19c, 0x01}, /* QSERDES_COM_SVS_MODE_CLK_SEL */
+	{0x178, 0x00}, /* QSERDES_COM_HSCLK_SEL */
+	{0xd0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */
+	{0xdc, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
+	{0xe0, 0x55}, /* QSERDES_COM_DIV_FRAC_START2_MODE0 */
+	{0xe4, 0x03}, /* QSERDES_COM_DIV_FRAC_START3_MODE0 */
+	{0x78, 0x0b}, /* QSERDES_COM_CP_CTRL_MODE0 */
+	{0x84, 0x16}, /* QSERDES_COM_PLL_RCTRL_MODE0 */
+	{0x90, 0x28}, /* QSERDES_COM_PLL_CCTRL_MODE0 */
+	{0x108, 0x80}, /* QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */
+	{0x10C, 0x00}, /* QSERDES_COM_INTEGLOOP_GAIN1_MODE0 */
+	{0x184, 0x0A}, /* QSERDES_COM_CORECLK_DIV */
+	{0x4c, 0x15}, /* QSERDES_COM_LOCK_CMP1_MODE0 */
+	{0x50, 0x34}, /* QSERDES_COM_LOCK_CMP2_MODE0 */
+	{0x54, 0x00}, /* QSERDES_COM_LOCK_CMP3_MODE0 */
+	{0xC8, 0x00}, /* QSERDES_COM_LOCK_CMP_EN */
+	{0x18c, 0x00}, /* QSERDES_COM_CORE_CLK_EN */
+	{0xcc, 0x00}, /* QSERDES_COM_LOCK_CMP_CFG */
+	{0x128, 0x00}, /* QSERDES_COM_VCO_TUNE_MAP */
+	{0x0C, 0x0A}, /* QSERDES_COM_BG_TIMER */
+	{0x10, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */
+	{0x1c, 0x31}, /* QSERDES_COM_SSC_PER1 */
+	{0x20, 0x01}, /* QSERDES_COM_SSC_PER2 */
+	{0x14, 0x00}, /* QSERDES_COM_SSC_ADJ_PER1 */
+	{0x18, 0x00}, /* QSERDES_COM_SSC_ADJ_PER2 */
+	{0x24, 0xde}, /* QSERDES_COM_SSC_STEP_SIZE1 */
+	{0x28, 0x07}, /* QSERDES_COM_SSC_STEP_SIZE2 */
+	{0x48, 0x0F}, /* USB3PHY_QSERDES_COM_PLL_IVCO */
+	{0x70, 0x0F}, /* USB3PHY_QSERDES_COM_BG_TRIM */
+	{0x100, 0x80}, /* QSERDES_COM_INTEGLOOP_INITVAL */
+
+	/* Rx Settings */
+	{0x440, 0x0b}, /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */
+	{0x4d8, 0x02}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
+	{0x4dc, 0x6c}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
+	{0x4e0, 0xbb}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
+	{0x508, 0x77}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */
+	{0x50c, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */
+	{0x514, 0x03}, /* QSERDES_RX_SIGDET_CNTRL */
+	{0x51c, 0x16}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */
+	{0x448, 0x75}, /* QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE */
+	{0x450, 0x00}, /* QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW */
+	{0x454, 0x00}, /* QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH */
+	{0x40C, 0x0a}, /* QSERDES_RX_UCDR_FO_GAIN */
+	{0x41C, 0x06}, /* QSERDES_RX_UCDR_SO_GAIN */
+	{0x510, 0x00}, /*QSERDES_RX_SIGDET_ENABLES */
+
+	/* Tx settings */
+	{0x268, 0x45}, /* QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN */
+	{0x2ac, 0x12}, /* QSERDES_TX_RCV_DETECT_LVL_2 */
+	{0x294, 0x06}, /* QSERDES_TX_LANE_MODE */
+	{0x254, 0x00}, /* QSERDES_TX_RES_CODE_LANE_OFFSET */
+
+	/* FLL settings */
+	{0x8c8, 0x83}, /* PCIE_USB3_PCS_FLL_CNTRL2 */
+	{0x8c4, 0x02}, /* PCIE_USB3_PCS_FLL_CNTRL1 */
+	{0x8cc, 0x09}, /* PCIE_USB3_PCS_FLL_CNT_VAL_L */
+	{0x8D0, 0xA2}, /* PCIE_USB3_PCS_FLL_CNT_VAL_H_TOL */
+	{0x8D4, 0x85}, /* PCIE_USB3_PCS_FLL_MAN_CODE */
+
+	/* PCS Settings */
+	{0x880, 0xD1}, /* PCIE_USB3_PCS_LOCK_DETECT_CONFIG1 */
+	{0x884, 0x1F}, /* PCIE_USB3_PCS_LOCK_DETECT_CONFIG2 */
+	{0x888, 0x47}, /* PCIE_USB3_PCS_LOCK_DETECT_CONFIG3 */
+	{0x80C, 0x9F}, /* PCIE_USB3_PCS_TXMGN_V0 */
+	{0x824, 0x17}, /* PCIE_USB3_PCS_TXDEEMPH_M6DB_V0 */
+	{0x828, 0x0F}, /* PCIE_USB3_PCS_TXDEEMPH_M3P5DB_V0 */
+	{0x8B8, 0x75}, /* PCIE_USB3_PCS_RXEQTRAINING_WAIT_TIME */
+	{0x8BC, 0x13}, /* PCIE_USB3_PCS_RXEQTRAINING_RUN_TIME */
+	{0x8B0, 0x86}, /* PCIE_USB3_PCS_LFPS_TX_ECSTART_EQTLOCK */
+	{0x8A0, 0x04}, /* PCIE_USB3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK */
+	{0x88C, 0x44}, /* PCIE_USB3_PCS_TSYNC_RSYNC_TIME */
+	{0x870, 0xE7}, /* PCIE_USB3_PCS_RCVR_DTCT_DLY_P1U2_L */
+	{0x874, 0x03}, /* PCIE_USB3_PCS_RCVR_DTCT_DLY_P1U2_H */
+	{0x878, 0x40}, /* PCIE_USB3_PCS_RCVR_DTCT_DLY_U3_L */
+	{0x87c, 0x00}, /* PCIE_USB3_PCS_RCVR_DTCT_DLY_U3_H */
+	{0x9D8, 0x88}, /* PCIE_USB3_PCS_RX_SIGDET_LVL */
+	{0x808, 0x03}, /* PCIE_USB3_PCS_START_CONTROL */
+	{0x800, 0x00}, /* PCIE_USB3_PCS_SW_RESET */
+};
+
+struct qmp_reg *target_get_qmp_settings()
+{
+	if (platform_is_mdmcalifornium())
+		return qmp_settings;
+	else
+		return NULL;
+}
+
+int target_get_qmp_regsize()
+{
+	if (platform_is_mdmcalifornium())
+		return ARRAY_SIZE(qmp_settings);
+	else
+		return 0;
+}
diff --git a/target/mdm9640/keypad.c b/target/mdm9640/keypad.c
index 11ba6e8..2f637f1 100644
--- a/target/mdm9640/keypad.c
+++ b/target/mdm9640/keypad.c
@@ -29,6 +29,8 @@
 #include <reg.h>
 #include <platform/gpio.h>
 #include <platform/iomap.h>
+#include <pm8x41.h>
+#include <platform.h>
 
 /* GPIO that controls the button
  * for FASTBOOT.
@@ -43,9 +45,14 @@
 {
 	int ret;
 
-	gpio_tlmm_config(FASTBOOT_KEY_GPIO_ID, 0, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA, GPIO_ENABLE);
+	if (platform_is_mdmcalifornium())
+		ret = pm8x41_resin_status();
+	else
+	{
+		gpio_tlmm_config(FASTBOOT_KEY_GPIO_ID, 0, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA, GPIO_ENABLE);
 
-	ret = gpio_get_state(FASTBOOT_KEY_GPIO_ID);
+		ret = gpio_get_state(FASTBOOT_KEY_GPIO_ID);
+	}
 
 	return ret;
 }
diff --git a/target/mdmfermium/init.c b/target/mdmfermium/init.c
index 65d1b0a..5a91d7f 100644
--- a/target/mdmfermium/init.c
+++ b/target/mdmfermium/init.c
@@ -115,10 +115,26 @@
 	}
 }
 
+/* Return Non zero (i.e 0x2) if vol_down pressed */
+uint32_t target_volume_down()
+{
+	/* Volume down button tied in with PMIC RESIN. */
+	return pm8x41_resin_status();
+}
+
+static void target_keystatus()
+{
+	keys_init();
+
+	if(target_volume_down())
+		keys_post_event(KEY_VOLUMEDOWN, 1);
+}
+
 void target_early_init(void)
 {
 #if WITH_DEBUG_UART
-	uart_dm_init(1, 0, BLSP1_UART5_BASE);
+	/*BLSP1 and UART5*/
+	uart_dm_init(5, 0, BLSP1_UART5_BASE);
 #endif
 }
 
@@ -150,6 +166,7 @@
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
 
+	target_keystatus();
 	config.pipes.read_pipe = DATA_PRODUCER_PIPE;
 	config.pipes.write_pipe = DATA_CONSUMER_PIPE;
 	config.pipes.cmd_pipe = CMD_PIPE;
@@ -190,7 +207,11 @@
 
 	switch(platform)
 	{
-	case MDMFERMIUM:
+	case MDMFERMIUM1:
+	case MDMFERMIUM2:
+	case MDMFERMIUM3:
+	case MDMFERMIUM4:
+	case MDMFERMIUM5:
 		board->baseband = BASEBAND_MDM;
         break;
 	default:
@@ -280,6 +301,7 @@
 
 void reboot_device(unsigned reboot_reason)
 {
+	uint8_t reset_type = 0;
 	 /* Write the reboot reason */
 	writel(reboot_reason, RESTART_REASON_ADDR);
 
@@ -288,7 +310,12 @@
 	* This call should be based on the pmic version
 	* when PM8019 v2 is available.
 	*/
-	pm8x41_v2_reset_configure(PON_PSHOLD_WARM_RESET);
+	if(reboot_reason)
+		reset_type = PON_PSHOLD_WARM_RESET;
+	else
+		reset_type = PON_PSHOLD_HARD_RESET;
+
+	pm8x41_v2_reset_configure(reset_type);
 
 	/* Drop PS_HOLD for MSM */
 	writel(0x00, MPM2_MPM_PS_HOLD);
diff --git a/target/mdmfermium/rules.mk b/target/mdmfermium/rules.mk
index 59f53ff..b614ea5 100644
--- a/target/mdmfermium/rules.mk
+++ b/target/mdmfermium/rules.mk
@@ -18,7 +18,6 @@
 
 BASE_ADDR                           := 0x80000000
 
-DEFINES += NO_KEYPAD_DRIVER=1
 
 MODULES += \
 	dev/keys \
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index b2585fc..0598833 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -330,15 +330,16 @@
 		if (!ret)
 			dprintf(CRITICAL, "Not able to enable master pll\n");
 
-		if (platform_is_msm8956() && pinfo->mipi.dual_dsi) {
+		if (platform_is_msm8956() && pinfo->mipi.dual_dsi &&
+			!platform_is_msm8976_v_1_1()) {
 				ret = mdss_dsi_pll_config(pinfo->mipi.spll_base,
 					pinfo->mipi.sctl_base, pll_data);
 			if (!ret)
 				dprintf(CRITICAL, "Not able to enable second pll\n");
 		}
 
-		gcc_dsi_clocks_enable(flags, pll_data->pclk_m, pll_data->pclk_n,
-				pll_data->pclk_d);
+		gcc_dsi_clocks_enable(flags, pinfo->mipi.use_dsi1_pll,
+			pll_data->pclk_m, pll_data->pclk_n, pll_data->pclk_d);
 	} else if(!target_cont_splash_screen()) {
 		gcc_dsi_clocks_disable(flags);
 		mdp_clock_disable();
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index c658935..e59bfc2 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -15,6 +15,9 @@
 
 SCRATCH_ADDR := 0x91C00000
 SCRATCH_SIZE := 740
+KERNEL_ADDR  := 0x80000000
+KERNEL_SIZE  := 88
+
 # LPAE supports only 32 virtual address, L1 pt size is 4
 L1_PT_SZ     := 4
 L2_PT_SZ     := 3
@@ -43,6 +46,8 @@
 	BASE_ADDR=$(BASE_ADDR) \
 	TAGS_ADDR=$(TAGS_ADDR) \
 	RAMDISK_ADDR=$(RAMDISK_ADDR) \
+	KERNEL_ADDR=$(KERNEL_ADDR) \
+	KERNEL_SIZE=$(KERNEL_SIZE) \
 	SCRATCH_ADDR=$(SCRATCH_ADDR) \
 	SCRATCH_SIZE=$(SCRATCH_SIZE) \
 	L1_PT_SZ=$(L1_PT_SZ) \