Merge "platform: msm_shared: fix issue with tuning command"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 3daaef5..2df5af0 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -67,6 +67,10 @@
 #include <dev_tree.h>
 #endif
 
+#if WDOG_SUPPORT
+#include <wdog.h>
+#endif
+
 #include "image_verify.h"
 #include "recovery.h"
 #include "bootimg.h"
@@ -667,6 +671,10 @@
 
 	enter_critical_section();
 
+	/* Initialise wdog to catch early kernel crashes */
+#if WDOG_SUPPORT
+	msm_wdog_init();
+#endif
 	/* do any platform specific cleanup before kernel entry */
 	platform_uninit();
 
@@ -1715,10 +1723,7 @@
 		if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
 		{
 			memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
-			if (is_secure_boot_enable())
-				info->is_unlocked = 0;
-			else
-				info->is_unlocked = 1;
+			info->is_unlocked = 0;
 			info->is_verified = 0;
 			info->is_tampered = 0;
 #if USER_BUILD_VARIANT
@@ -2103,18 +2108,21 @@
 void cmd_erase(const char *arg, void *data, unsigned sz)
 {
 #if VERIFIED_BOOT
-	if(!device.is_unlocked && !device.is_verified)
+	if (target_build_variant_user())
 	{
-		fastboot_fail("device is locked. Cannot erase");
-		return;
-	}
-	if(!device.is_unlocked && device.is_verified)
-	{
-		if(!boot_verify_flash_allowed(arg))
+		if(!device.is_unlocked && !device.is_verified)
 		{
-			fastboot_fail("cannot flash this partition in verified state");
+			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
 
@@ -2251,10 +2259,9 @@
 void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 {
 	unsigned int chunk;
-	unsigned int chunk_data_sz;
+	uint64_t chunk_data_sz;
 	uint32_t *fill_buf = NULL;
 	uint32_t fill_val;
-	uint32_t chunk_blk_cnt = 0;
 	sparse_header_t *sparse_header;
 	chunk_header_t *chunk_header;
 	uint32_t total_blocks = 0;
@@ -2342,15 +2349,13 @@
 			return;
 		}
 
-		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
-
-		/* Make sure multiplication does not overflow uint32 size */
-		if (sparse_header->blk_sz && (chunk_header->chunk_sz != chunk_data_sz / sparse_header->blk_sz))
-		{
-			fastboot_fail("Bogus size sparse and chunk header");
+		if (!sparse_header->blk_sz ){
+			fastboot_fail("Invalid block size\n");
 			return;
 		}
 
+		chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
+
 		/* Make sure that the chunk size calculated from sparse image does not
 		 * exceed partition size
 		 */
@@ -2363,7 +2368,7 @@
 		switch (chunk_header->chunk_type)
 		{
 			case CHUNK_TYPE_RAW:
-			if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
+			if((uint64_t)chunk_header->total_sz != ((uint64_t)sparse_header->chunk_hdr_sz +
 											chunk_data_sz))
 			{
 				fastboot_fail("Bogus chunk size for chunk type Raw");
@@ -2375,8 +2380,11 @@
 				return;
 			}
 
+			/* chunk_header->total_sz is uint32,So chunk_data_sz is now less than 2^32
+			   otherwise it will return in the line above
+			 */
 			if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
-						chunk_data_sz,
+						(uint32_t)chunk_data_sz,
 						(unsigned int*)data))
 			{
 				fastboot_fail("flash write failure");
@@ -2387,7 +2395,7 @@
 				return;
 			}
 			total_blocks += chunk_header->chunk_sz;
-			data += chunk_data_sz;
+			data += (uint32_t)chunk_data_sz;
 			break;
 
 			case CHUNK_TYPE_FILL:
@@ -2411,14 +2419,13 @@
 			}
 			fill_val = *(uint32_t *)data;
 			data = (char *) data + sizeof(uint32_t);
-			chunk_blk_cnt = chunk_data_sz / sparse_header->blk_sz;
 
 			for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
 			{
 				fill_buf[i] = fill_val;
 			}
 
-			for (i = 0; i < chunk_blk_cnt; i++)
+			for (i = 0; i < chunk_header->chunk_sz; i++)
 			{
 				/* Make sure that the data written to partition does not exceed partition size */
 				if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + sparse_header->blk_sz > size)
@@ -2453,7 +2460,7 @@
 			case CHUNK_TYPE_CRC:
 			if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
 			{
-				fastboot_fail("Bogus chunk size for chunk type Dont Care");
+				fastboot_fail("Bogus chunk size for chunk type CRC");
 				return;
 			}
 			if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
@@ -2465,7 +2472,7 @@
 				fastboot_fail("integer overflow occured");
 				return;
 			}
-			data += chunk_data_sz;
+			data += (uint32_t)chunk_data_sz;
 			if (data_end < (uint32_t)data) {
 				fastboot_fail("buffer overreads occured due to invalid sparse header");
 				return;
@@ -2565,18 +2572,21 @@
 #endif /* SSD_ENABLE */
 
 #if VERIFIED_BOOT
-	if(!device.is_unlocked)
+	if (target_build_variant_user())
 	{
-		fastboot_fail("device is locked. Cannot flash images");
-		return;
-	}
-	if(!device.is_unlocked && device.is_verified)
-	{
-		if(!boot_verify_flash_allowed(arg))
+		if(!device.is_unlocked)
 		{
-			fastboot_fail("cannot flash this partition in verified state");
+			fastboot_fail("device is locked. Cannot flash images");
 			return;
 		}
+		if(!device.is_unlocked && device.is_verified)
+		{
+			if(!boot_verify_flash_allowed(arg))
+			{
+				fastboot_fail("cannot flash this partition in verified state");
+				return;
+			}
+		}
 	}
 #endif
 
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 88d2125..4d5a1ff 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
@@ -222,7 +222,7 @@
 /* Panel timing                                                              */
 /*---------------------------------------------------------------------------*/
 static const uint32_t nt35597_wqxga_dualdsi_video_timings[] = {
-	0xe2, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x28, 0x38,  0x2a, 0x03, 0x04, 0x00
+	0xd5, 0x32, 0x22, 0x00, 0x60, 0x64, 0x26, 0x36, 0x29, 0x03, 0x04, 0x00
 };
 
 static const uint32_t nt35597_wqxga_dualdsi_thulium_video_timings[] = {
diff --git a/dev/gcdb/display/panel_display.c b/dev/gcdb/display/panel_display.c
index d258db2..2555274 100755
--- a/dev/gcdb/display/panel_display.c
+++ b/dev/gcdb/display/panel_display.c
@@ -55,7 +55,9 @@
 static int dsi_panel_ctl_base_setup(struct msm_panel_info *pinfo,
 	char *panel_destination)
 {
-	int base_offset = 0, base1_offset = 0;
+	int base_offset = 0, base1_offset = 0, base_phy_offset = 0,
+	base1_phy_offset = 0, base_phy_pll_offset = 0,
+	base1_phy_pll_offset = 0, base_phy_reg_offset = 0;
 
 	/*
 	 * Base offsets may vary for few platforms. Add the difference to get
@@ -63,33 +65,38 @@
 	 */
 	base_offset = dsi_platform_base_offset_adjust(MIPI_DSI0_BASE);
 	base1_offset = dsi_platform_base_offset_adjust(MIPI_DSI1_BASE);
+	base_phy_offset = dsi_platform_base_offset_adjust(DSI0_PHY_BASE);
+	base1_phy_offset = dsi_platform_base_offset_adjust(DSI1_PHY_BASE);
+	base_phy_pll_offset = dsi_platform_base_offset_adjust(DSI0_PLL_BASE);
+	base1_phy_pll_offset = dsi_platform_base_offset_adjust(DSI1_PLL_BASE);
+	base_phy_reg_offset = dsi_platform_base_offset_adjust(DSI0_REGULATOR_BASE);
 	dprintf(SPEW, "base offset = %d, %x\n", base_offset, base_offset);
 
 	if (!strcmp(panel_destination, "DISPLAY_1")) {
 		pinfo->dest = DISPLAY_1;
 		pinfo->mipi.ctl_base = MIPI_DSI0_BASE + base_offset;
-		pinfo->mipi.phy_base = DSI0_PHY_BASE + base_offset;
+		pinfo->mipi.phy_base = DSI0_PHY_BASE + base_phy_offset;
 		pinfo->mipi.sctl_base = MIPI_DSI1_BASE + base1_offset;
-		pinfo->mipi.sphy_base = DSI1_PHY_BASE + base1_offset;
+		pinfo->mipi.sphy_base = DSI1_PHY_BASE + base1_phy_offset;
 		if (pinfo->mipi.use_dsi1_pll) {
 			dprintf(CRITICAL, "%s: Invalid combination: DSI0 controller + DSI1 PLL, using DSI0 PLL\n",
 				__func__);
 			pinfo->mipi.use_dsi1_pll = 0;
 		}
-		pinfo->mipi.pll_base = DSI0_PLL_BASE + base_offset;
-		pinfo->mipi.spll_base = DSI1_PLL_BASE + base1_offset;
+		pinfo->mipi.pll_base = DSI0_PLL_BASE + base_phy_pll_offset;
+		pinfo->mipi.spll_base = DSI1_PLL_BASE + base1_phy_pll_offset;
 	} else if (!strcmp(panel_destination, "DISPLAY_2")) {
 		pinfo->dest = DISPLAY_2;
 		pinfo->mipi.ctl_base = MIPI_DSI1_BASE + base1_offset;
-		pinfo->mipi.phy_base = DSI1_PHY_BASE + base1_offset;
+		pinfo->mipi.phy_base = DSI1_PHY_BASE + base1_phy_offset;
 		pinfo->mipi.sctl_base = MIPI_DSI0_BASE + base_offset;
-		pinfo->mipi.sphy_base = DSI0_PHY_BASE + base_offset;
+		pinfo->mipi.sphy_base = DSI0_PHY_BASE + base_phy_offset;
 		if (pinfo->mipi.use_dsi1_pll) {
-			pinfo->mipi.pll_base = DSI1_PLL_BASE + base1_offset;
-			pinfo->mipi.spll_base = DSI0_PLL_BASE + base_offset;
+			pinfo->mipi.pll_base = DSI1_PLL_BASE + base1_phy_pll_offset;
+			pinfo->mipi.spll_base = DSI0_PLL_BASE + base_phy_pll_offset;
 		} else {
-			pinfo->mipi.pll_base = DSI0_PLL_BASE + base_offset;
-			pinfo->mipi.spll_base = DSI1_PLL_BASE + base1_offset;
+			pinfo->mipi.pll_base = DSI0_PLL_BASE + base_phy_pll_offset;
+			pinfo->mipi.spll_base = DSI1_PLL_BASE + base1_phy_pll_offset;
 		}
 	} else {
 		pinfo->dest = DISPLAY_UNKNOWN;
@@ -99,8 +106,8 @@
 	}
 
 	/* Both DSI0 and DSI1 use the same regulator */
-	pinfo->mipi.reg_base = DSI0_REGULATOR_BASE + base_offset;
-	pinfo->mipi.sreg_base = DSI0_REGULATOR_BASE + base_offset;
+	pinfo->mipi.reg_base = DSI0_REGULATOR_BASE + base_phy_reg_offset;
+	pinfo->mipi.sreg_base = DSI0_REGULATOR_BASE + base_phy_reg_offset;
 
 	dprintf(SPEW, "%s: panel dest=%s, ctl_base=0x%08x, phy_base=0x%08x\n",
 		__func__, panel_destination, pinfo->mipi.ctl_base,
diff --git a/dev/pmic/pm8x41/pm8x41_vib.c b/dev/pmic/pm8x41/pm8x41_vib.c
index 7dbba77..3246b9f 100644
--- a/dev/pmic/pm8x41/pm8x41_vib.c
+++ b/dev/pmic/pm8x41/pm8x41_vib.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
@@ -27,9 +27,7 @@
  */
 
 #include <bits.h>
-#include <debug.h>
-#include <reg.h>
-#include <pm8x41.h>
+#include <pm8x41_hw.h>
 #include <pm_vib.h>
 
 #define QPNP_VIB_EN    BIT(7)
diff --git a/dev/vib/vibrator.c b/dev/vib/vibrator.c
index e8cb8c7..b3e79c0 100644
--- a/dev/vib/vibrator.c
+++ b/dev/vib/vibrator.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
@@ -26,13 +26,11 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <debug.h>
-#include <reg.h>
 #include <stdlib.h>
 #include <kernel/timer.h>
-#include <platform/timer.h>
-#include <vibrator.h>
+#include <kernel/thread.h>
 #include <pm_vib.h>
+#include <vibrator.h>
 
 #define CHECK_VIB_TIMER_FREQUENCY    50
 
@@ -52,7 +50,7 @@
 }
 
 /* Function to turn off vibrator when the vib_timer is expired. */
-static enum handler_return vib_timer_func(struct timer *v_timer, void *arg)
+static enum handler_return vib_timer_func(struct timer *v_timer, time_t t, void *arg)
 {
 	timer_cancel(&vib_timer);
 	vib_turn_off();
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
index 87e31dd..e3aaec3 100644
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -296,50 +296,93 @@
 }
 
 /* Disable all the branch clocks needed by the DSI controller */
-void gcc_dsi_clocks_disable(void)
+void gcc_dsi_clocks_disable(uint32_t flags)
 {
-	clk_disable(clk_get("mdss_esc0_clk"));
-	writel(0x0, DSI_PIXEL0_CBCR);
-	writel(0x0, DSI_BYTE0_CBCR);
+	if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
+		clk_disable(clk_get("mdss_esc0_clk"));
+		writel(0x0, DSI_PIXEL0_CBCR);
+		writel(0x0, DSI_BYTE0_CBCR);
+	}
+
+	if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
+		clk_disable(clk_get("mdss_esc1_clk"));
+		writel(0x0, DSI_PIXEL1_CBCR);
+		writel(0x0, DSI_BYTE1_CBCR);
+	}
 }
 
 /* Configure all the branch clocks needed by the DSI controller */
-void gcc_dsi_clocks_enable(uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
+void gcc_dsi_clocks_enable(uint32_t flags, uint8_t pclk0_m,
+		uint8_t pclk0_n, uint8_t pclk0_d)
 {
 	int ret;
 
-	/*
-	 * Configure Byte clock -autopll- This will not change becasue
-	 * byte clock does not need any divider
-	 */
-	/* Set the source for DSI0 byte RCG */
-	writel(0x100, DSI_BYTE0_CFG_RCGR);
-	/* Set the update RCG bit */
-	writel(0x1, DSI_BYTE0_CMD_RCGR);
-	rcg_update_config(DSI_BYTE0_CMD_RCGR);
-	/* Enable the branch clock */
-	writel(0x1, DSI_BYTE0_CBCR);
-	branch_clk_halt_check(DSI_BYTE0_CBCR);
+	if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
+		/* Enable DSI0 branch clocks */
 
-	/* Configure Pixel clock */
-	/* Set the source for DSI0 pixel RCG */
-	writel(0x100, DSI_PIXEL0_CFG_RCGR);
-	/* Set the MND for DSI0 pixel clock */
-	writel(pclk0_m, DSI_PIXEL0_M);
-	writel(pclk0_n, DSI_PIXEL0_N);
-	writel(pclk0_d, DSI_PIXEL0_D);
-	/* Set the update RCG bit */
-	writel(0x1, DSI_PIXEL0_CMD_RCGR);
-	rcg_update_config(DSI_PIXEL0_CMD_RCGR);
-	/* Enable the branch clock */
-	writel(0x1, DSI_PIXEL0_CBCR);
-	branch_clk_halt_check(DSI_PIXEL0_CBCR);
+		/* Set the source for DSI0 byte RCG */
+		writel(0x100, DSI_BYTE0_CFG_RCGR);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_BYTE0_CMD_RCGR);
+		rcg_update_config(DSI_BYTE0_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_BYTE0_CBCR);
+		branch_clk_halt_check(DSI_BYTE0_CBCR);
 
-	/* Configure ESC clock */
-	ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
-	if (ret) {
-		dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
-		ASSERT(0);
+		/* Configure Pixel clock */
+		/* Set the source for DSI0 pixel RCG */
+		writel(0x100, DSI_PIXEL0_CFG_RCGR);
+		/* Set the MND for DSI0 pixel clock */
+		writel(pclk0_m, DSI_PIXEL0_M);
+		writel(pclk0_n, DSI_PIXEL0_N);
+		writel(pclk0_d, DSI_PIXEL0_D);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_PIXEL0_CMD_RCGR);
+		rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_PIXEL0_CBCR);
+		branch_clk_halt_check(DSI_PIXEL0_CBCR);
+
+		/* Configure ESC clock */
+		ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
+		if (ret) {
+			dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
+			ASSERT(0);
+		}
+	}
+
+	if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
+		/* Enable DSI1 branch clocks */
+
+		/* Set the source for DSI1 byte RCG */
+		writel(0x100, DSI_BYTE1_CFG_RCGR);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_BYTE1_CMD_RCGR);
+		rcg_update_config(DSI_BYTE1_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_BYTE1_CBCR);
+		branch_clk_halt_check(DSI_BYTE1_CBCR);
+
+		/* Configure Pixel clock */
+		/* Set the source for DSI1 pixel RCG */
+		writel(0x100, DSI_PIXEL1_CFG_RCGR);
+		/* Set the MND for DSI1 pixel clock */
+		writel(pclk0_m, DSI_PIXEL1_M);
+		writel(pclk0_n, DSI_PIXEL1_N);
+		writel(pclk0_d, DSI_PIXEL1_D);
+		/* Set the update RCG bit */
+		writel(0x1, DSI_PIXEL1_CMD_RCGR);
+		rcg_update_config(DSI_PIXEL1_CMD_RCGR);
+		/* Enable the branch clock */
+		writel(0x1, DSI_PIXEL1_CBCR);
+		branch_clk_halt_check(DSI_PIXEL1_CBCR);
+
+		/* Configure ESC clock */
+		ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
+		if (ret) {
+			dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
+			ASSERT(0);
+		}
 	}
 }
 
diff --git a/platform/msm8952/include/platform/clock.h b/platform/msm8952/include/platform/clock.h
index 495914d..f6e962a 100644
--- a/platform/msm8952/include/platform/clock.h
+++ b/platform/msm8952/include/platform/clock.h
@@ -78,6 +78,9 @@
 #define DSI_PIXEL1_N                    REG_MM(0x4D0C4)
 #define DSI_PIXEL1_D                    REG_MM(0x4D0C8)
 
+#define MMSS_DSI_CLKS_FLAG_DSI0         BIT(0)
+#define MMSS_DSI_CLKS_FLAG_DSI1         BIT(1)
+
 void platform_clock_init(void);
 
 void clock_init_mmc(uint32_t interface);
@@ -92,6 +95,7 @@
 void mdss_bus_clocks_disable(void);
 void mdp_clock_enable(void);
 void mdp_clock_disable(void);
-void gcc_dsi_clocks_enable(uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d);
-void gcc_dsi_clocks_disable(void);
+void gcc_dsi_clocks_enable(uint32_t flags, 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 68b8227..ae61934 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -285,6 +285,26 @@
 #endif
 #define MDP_INTF_1_BASE                         REG_MDP(0x12700)
 
+#ifdef MDP_INTF_2_BASE
+#undef MDP_INTF_2_BASE
+#endif
+#define MDP_INTF_2_BASE                         REG_MDP(0x12F00)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_EN
+#undef MDP_REG_SPLIT_DISPLAY_EN
+#endif
+#define MDP_REG_SPLIT_DISPLAY_EN                REG_MDP(0x12F4)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL
+#undef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL
+#endif
+#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL    REG_MDP(0x12F8)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL
+#undef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL
+#endif
+#define MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL    REG_MDP(0x13F0)
+
 #ifdef MMSS_MDP_SMP_ALLOC_W_BASE
 #undef MMSS_MDP_SMP_ALLOC_W_BASE
 #endif
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
index 33788b0..af4f279 100644
--- a/platform/msm8952/platform.c
+++ b/platform/msm8952/platform.c
@@ -66,7 +66,7 @@
 	{    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,            10,              COMMON_MEMORY},
+	{    MIPI_FB_ADDR,          MIPI_FB_ADDR,            42,              COMMON_MEMORY},
 };
 
 void platform_early_init(void)
diff --git a/platform/msm_shared/board.c b/platform/msm_shared/board.c
index 03f794c..1265f29 100644
--- a/platform/msm_shared/board.c
+++ b/platform/msm_shared/board.c
@@ -33,6 +33,9 @@
 #include <baseband.h>
 #include <boot_device.h>
 
+static uint16_t format_major = 0;
+static uint16_t format_minor = 0;
+
 static struct board_data board = {UNKNOWN,
 	0,
 	0,
@@ -44,6 +47,9 @@
 	{{PMIC_IS_INVALID, 0, 0}, {PMIC_IS_INVALID, 0, 0},
 	{PMIC_IS_INVALID, 0, 0}},
 	0,
+	0,
+	0,
+	NULL,
 };
 
 static void platform_detect()
@@ -53,13 +59,12 @@
 	struct smem_board_info_v8 board_info_v8;
 	struct smem_board_info_v9 board_info_v9;
 	struct smem_board_info_v10 board_info_v10;
+	struct smem_board_info_v11 board_info_v11;
 	unsigned int board_info_len = 0;
 	unsigned ret = 0;
 	unsigned format = 0;
 	unsigned pmic_type = 0;
 	uint8_t i;
-	uint16_t format_major = 0;
-	uint16_t format_minor = 0;
 
 	ret = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION,
 						   &format, sizeof(format), 0);
@@ -192,7 +197,7 @@
 			}
 			board.foundry_id = board_info_v9.foundry_id;
 		}
-		else if (format_minor >= 0xA)
+		else if (format_minor == 0xA)
 		{
 			board_info_len = sizeof(board_info_v10);
 
@@ -236,6 +241,37 @@
 			board.foundry_id = board_info_v10.foundry_id;
 			board.chip_serial = board_info_v10.chip_serial;
 		}
+		else if (format_minor >= 0xB)
+		{
+			board_info_len = sizeof(board_info_v11);
+
+			ret = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
+					&board_info_v11,
+					board_info_len);
+			if (ret)
+				return;
+
+			board.platform = board_info_v11.board_info_v3.msm_id;
+			board.platform_version = board_info_v11.board_info_v3.msm_version;
+			board.platform_hw = board_info_v11.board_info_v3.hw_platform;
+			board.platform_subtype = board_info_v11.platform_subtype;
+			/*
+			 * fill in board.target with variant_id information
+			 * bit no         |31  24 |23             16|15              8|7         0|
+			 * board.target = |subtype|plat_hw_ver major|plat_hw_ver minor|hw_platform|
+			 *
+			 */
+
+			board.target = (((board_info_v11.platform_subtype & 0xff) << 24) |
+						   (((board_info_v11.platform_version >> 16) & 0xff) << 16) |
+						   ((board_info_v11.platform_version & 0xff) << 8) |
+						   (board_info_v11.board_info_v3.hw_platform & 0xff));
+
+			board.foundry_id = board_info_v11.foundry_id;
+			board.chip_serial = board_info_v11.chip_serial;
+			board.num_pmics = board_info_v11.num_pmics;
+			board.pmic_array_offset = board_info_v11.pmic_array_offset;
+		}
 
 		/* HLOS subtype
 		 * bit no                        |31    20 | 19        16|15    13 |12      11 | 10          8 | 7     0|
@@ -251,6 +287,58 @@
 	}
 }
 
+void pmic_info_populate()
+{
+	struct smem_board_info_v11 *bi_v11=NULL;
+	unsigned int board_info_len = 0;
+	unsigned ret = 0;
+	uint32_t pmic_type = 0;
+
+	if (format_minor < 0xB)
+	{
+		// not needed for smem versions < 0xB
+		return;
+	}
+
+	board_info_len = sizeof(struct smem_board_info_v11) + board.num_pmics * sizeof(struct smem_pmic_info);
+	if(!(bi_v11 = malloc(board_info_len)))
+	{
+		dprintf(CRITICAL, "Error allocating memory for board structure\n");
+		ASSERT(0);
+	}
+	ret = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
+					bi_v11,
+					board_info_len);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Error reading from SMEM for populating pmic info\n");
+		goto free_bi_v11;
+	}
+
+	if(!(board.pmic_info_array = malloc(board.num_pmics * sizeof(struct board_pmic_data))))
+	{
+		dprintf(CRITICAL, "Error allocating memory for pmic info array\n");
+		ASSERT(0);
+	}
+	struct board_pmic_data *info = board.pmic_info_array;
+	for (uint8_t i = 0; i < board.num_pmics; i++)
+	{
+		memcpy(info, (void *)(bi_v11) + board.pmic_array_offset + (i * sizeof(struct smem_pmic_info)), sizeof(struct smem_pmic_info));
+		/*
+		 * fill in pimc_board_info with pmic type and pmic version information
+		 * bit no  		  	    |31  24|23         16|15          8|7		 0|
+		 * pimc_board_info =    |Unused|Major version|Minor version|PMIC_MODEL|
+		 *
+		 */
+		pmic_type = info->pmic_type == PMIC_IS_INVALID? 0 : info->pmic_type;
+		info->pmic_target = (((info->pmic_version >> 16) & 0xff) << 16) |
+			   ((info->pmic_version & 0xff) << 8) | (pmic_type & 0xff);
+		info++;
+	}
+free_bi_v11:
+	free(bi_v11);
+}
+
 void board_init()
 {
 	platform_detect();
@@ -296,21 +384,35 @@
 uint8_t board_pmic_info(struct board_pmic_data *info, uint8_t num_ent)
 {
 	uint8_t i;
-
-	for (i = 0; i < num_ent && i < SMEM_MAX_PMIC_DEVICES; i++) {
-		info->pmic_type = board.pmic_info[i].pmic_type;
-		info->pmic_version = board.pmic_info[i].pmic_version;
-		info->pmic_target = board.pmic_info[i].pmic_target;
-		info++;
+	if (format_major == 0x0)
+	{
+		if (format_minor < 0xB)
+		{
+			for (i = 0; i < num_ent && i < SMEM_MAX_PMIC_DEVICES; i++) {
+				info->pmic_type = board.pmic_info[i].pmic_type;
+				info->pmic_version = board.pmic_info[i].pmic_version;
+				info->pmic_target = board.pmic_info[i].pmic_target;
+				info++;
+			}
+			return (i--);
+		}
 	}
-
-	return (i--);
+	return 0;
 }
 
 uint32_t board_pmic_target(uint8_t num_ent)
 {
-	if (num_ent < SMEM_MAX_PMIC_DEVICES) {
-		return board.pmic_info[num_ent].pmic_target;
+	if (format_major == 0x0 && num_ent < SMEM_MAX_PMIC_DEVICES)
+	{
+		if (format_minor < 0xB && num_ent < SMEM_V8_SMEM_MAX_PMIC_DEVICES)
+		{
+			return board.pmic_info[num_ent].pmic_target;
+		}
+		else
+		{
+			if (num_ent < board.num_pmics)
+				return  board.pmic_info_array[num_ent].pmic_target;
+		}
 	}
 	return 0;
 }
diff --git a/platform/msm_shared/include/board.h b/platform/msm_shared/include/board.h
index 834b203..4d4c7a9 100644
--- a/platform/msm_shared/include/board.h
+++ b/platform/msm_shared/include/board.h
@@ -53,6 +53,9 @@
 	uint32_t baseband;
 	struct board_pmic_data pmic_info[MAX_PMIC_DEVICES];
 	uint32_t platform_hlos_subtype;
+	uint32_t num_pmics;
+	uint32_t pmic_array_offset;
+	struct board_pmic_data *pmic_info_array;
 };
 
 void board_init();
@@ -69,6 +72,7 @@
 uint32_t board_hlos_subtype(void);
 uint32_t board_pmic_target(uint8_t num_ent);
 uint32_t board_chip_serial(void);
+void pmic_info_populate();
 
 /* DDR Subtype Macros
  * Determine the DDR Size on the device and define
diff --git a/platform/msm_shared/include/mdp5.h b/platform/msm_shared/include/mdp5.h
index e48fe85..43e2c0e 100644
--- a/platform/msm_shared/include/mdp5.h
+++ b/platform/msm_shared/include/mdp5.h
@@ -91,6 +91,7 @@
 #define MDSS_MDP_HW_REV_108    MDSS_MDP_REV(1, 8, 0) /* 8939 v1.0 */
 #define MDSS_MDP_HW_REV_109    MDSS_MDP_REV(1, 9, 0) /* 8994 v2.0 */
 #define MDSS_MDP_HW_REV_110    MDSS_MDP_REV(1, 10, 0) /* 8992 v1.0 */
+#define MDSS_MDP_HW_REV_111    MDSS_MDP_REV(1, 11, 0) /* 8956 v1.0 */
 #define MDSS_MDP_HW_REV_112    MDSS_MDP_REV(1, 12, 0) /* 8952 v1.0 */
 #define MDSS_MDP_HW_REV_200    MDSS_MDP_REV(2, 0, 0) /* 8092 v1.0 */
 
diff --git a/platform/msm_shared/include/mipi_dsi.h b/platform/msm_shared/include/mipi_dsi.h
index 81c4612..845c495 100644
--- a/platform/msm_shared/include/mipi_dsi.h
+++ b/platform/msm_shared/include/mipi_dsi.h
@@ -71,7 +71,8 @@
 #define TIMING_DB_MODE		     0x1E8
 
 #define DSI_HW_REV_103			0x10030000	/* 8994 */
-#define DSI_HW_REV_103_1		0x10030001	/* 8936/8939 */
+#define DSI_HW_REV_103_1		0x10030001	/* 8936/8939/8952 */
+#define DSI_HW_REV_104_2		0x10040002	/* 8956 */
 #define DSI_HW_REV_104			0x10040000	/* thulium */
 
 #define DTYPE_GEN_WRITE2 0x23	/* 4th Byte is 0x80 */
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index d67b5c8..ef083ea 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -75,6 +75,7 @@
 
 	if ((mdss_mdp_rev == MDSS_MDP_HW_REV_106) ||
 		(mdss_mdp_rev == MDSS_MDP_HW_REV_108) ||
+		(mdss_mdp_rev == MDSS_MDP_HW_REV_111) ||
 		(mdss_mdp_rev == MDSS_MDP_HW_REV_112))
 		mdss_mdp_intf_off = 0x59100;
 	else if (mdss_mdp_rev >= MDSS_MDP_HW_REV_102)
@@ -91,7 +92,8 @@
 	uint32_t mdss_mdp_rev = readl(MDP_HW_REV);
 
 	/* return MMSS_MDP_PPB0_CONFIG offset from MDSS base */
-	if (mdss_mdp_rev == MDSS_MDP_HW_REV_108)
+	if ((mdss_mdp_rev == MDSS_MDP_HW_REV_108) ||
+		(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;
@@ -105,7 +107,8 @@
 {
 	uint32_t mdss_mdp_rev = readl(MDP_HW_REV);
 
-	if (mdss_mdp_rev == MDSS_MDP_HW_REV_110)
+	if ((mdss_mdp_rev == MDSS_MDP_HW_REV_110) ||
+		(mdss_mdp_rev == MDSS_MDP_HW_REV_111))
 		return 0xB0020;
 	else if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
 		return 0xB0000;
@@ -189,6 +192,7 @@
 	/* For targets from MDP v1.5, MDP INTF registers are double buffered */
 	if ((mdss_mdp_rev == MDSS_MDP_HW_REV_106) ||
 		(mdss_mdp_rev == MDSS_MDP_HW_REV_108) ||
+		(mdss_mdp_rev == MDSS_MDP_HW_REV_111) ||
 		(mdss_mdp_rev == MDSS_MDP_HW_REV_112)) {
 		if (pinfo->dest == DISPLAY_2) {
 			*ctl0_reg_val |= BIT(31);
@@ -351,11 +355,12 @@
 	if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_101) ||
 		MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_106) ||
 		MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_108) ||
+		MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_111) ||
 		MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_112)) {
 		switch (pinfo->pipe_type) {
 			case MDSS_MDP_PIPE_TYPE_RGB:
 				*left_sspp_client_id = 0x7; /* 7 */
-				*right_sspp_client_id = 0x11; /* 17 */
+				*right_sspp_client_id = 0x8; /* 8 */
 				break;
 			case MDSS_MDP_PIPE_TYPE_DMA:
 				*left_sspp_client_id = 0x4; /* 4 */
@@ -364,7 +369,7 @@
 			case MDSS_MDP_PIPE_TYPE_VIG:
 			default:
 				*left_sspp_client_id = 0x1; /* 1 */
-				*right_sspp_client_id = 0x4; /* 4 */
+				*right_sspp_client_id = 0x9; /* 9 */
 				break;
 		}
 	} else {
@@ -419,8 +424,9 @@
 		(mdss_mdp_rev == MDSS_MDP_HW_REV_112)) {
 		/* 8Kb per SMP on 8916/8952 */
 		smp_size = 8192;
-	} else if (mdss_mdp_rev == MDSS_MDP_HW_REV_108) {
-		/* 10Kb per SMP on 8939 */
+	} else if ((mdss_mdp_rev == MDSS_MDP_HW_REV_108) ||
+		(mdss_mdp_rev == MDSS_MDP_HW_REV_111)) {
+		/* 10Kb per SMP on 8939/8956 */
 		smp_size = 10240;
 	} else if ((mdss_mdp_rev >= MDSS_MDP_HW_REV_103) &&
 		(mdss_mdp_rev < MDSS_MDP_HW_REV_200)) {
@@ -792,6 +798,8 @@
 		 MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev,
 			MDSS_MDP_HW_REV_108) ||
 		 MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev,
+			MDSS_MDP_HW_REV_111) ||
+		 MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev,
 			MDSS_MDP_HW_REV_112))
 		map = 0xE4;
 	else if (MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev,
@@ -825,6 +833,7 @@
 
 	if (MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev, MDSS_MDP_HW_REV_106) ||
 		 MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev, MDSS_MDP_HW_REV_108) ||
+		 MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev, MDSS_MDP_HW_REV_111) ||
 		 MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev, MDSS_MDP_HW_REV_112)) {
 		vbif_qos[0] = 2;
 		vbif_qos[1] = 2;
diff --git a/platform/msm_shared/mipi_dsi_phy.c b/platform/msm_shared/mipi_dsi_phy.c
index 9a26a9d..b7faf5d 100644
--- a/platform/msm_shared/mipi_dsi_phy.c
+++ b/platform/msm_shared/mipi_dsi_phy.c
@@ -32,6 +32,7 @@
 #include <mdp5.h>
 #include <platform/timer.h>
 #include <platform/iomap.h>
+#include <target/display.h>
 #include <arch/defines.h>
 
 #if (DISPLAY_TYPE_MDSS == 0)
@@ -253,56 +254,54 @@
 	}
 }
 
-static void mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd,
-	uint32_t phy_base)
+static void mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd, uint32_t ctl_base,
+	uint32_t phy_base, uint32_t reg_base)
 {
 	/* DSI0 and DSI1 have a common regulator */
-	uint32_t off = 0x0280;	/* phy regulator ctrl settings */
 
 	if (pd->regulator_mode == DSI_PHY_REGULATOR_LDO_MODE) {
 		/* Regulator ctrl 0 */
-		writel(0x00, DSI0_PHY_BASE + off + (4 * 0));
+		writel(0x00, reg_base + (4 * 0));
 		/* Regulator ctrl - CAL_PWD_CFG */
-		writel(pd->regulator[6], DSI0_PHY_BASE + off + (4 * 6));
+		writel(pd->regulator[6], reg_base + (4 * 6));
 		/* Add h/w recommended delay */
 		udelay(1000);
 		/* Regulator ctrl - TEST */
-		writel(pd->regulator[5], DSI0_PHY_BASE + off + (4 * 5));
+		writel(pd->regulator[5], reg_base + (4 * 5));
 		/* Regulator ctrl 3 */
-		writel(pd->regulator[3], DSI0_PHY_BASE + off + (4 * 3));
+		writel(pd->regulator[3], reg_base + (4 * 3));
 		/* Regulator ctrl 2 */
-		writel(pd->regulator[2], DSI0_PHY_BASE + off + (4 * 2));
+		writel(pd->regulator[2], reg_base + (4 * 2));
 		/* Regulator ctrl 1 */
-		writel(pd->regulator[1], DSI0_PHY_BASE + off + (4 * 1));
+		writel(pd->regulator[1], reg_base + (4 * 1));
 		/* Regulator ctrl 4 */
-		writel(pd->regulator[4], DSI0_PHY_BASE + off + (4 * 4));
+		writel(pd->regulator[4], reg_base + (4 * 4));
 		/* LDO ctrl */
-		if (readl(MIPI_DSI0_BASE) == DSI_HW_REV_103_1) /* 8916/8939 */
+		if ((readl(ctl_base) == DSI_HW_REV_103_1) ||
+			(readl(ctl_base) == DSI_HW_REV_104_2)) /* 8916/8939/8952/8956 */
 			writel(0x05, phy_base + 0x01dc);
-		else if (readl(MIPI_DSI0_BASE) == DSI_HW_REV_103) /* 8994 */
-			writel(0x1d, phy_base + 0x01dc);
 		else
 			writel(0x0d, phy_base + 0x01dc);
 		dmb();
 	} else {
 		/* Regulator ctrl 0 */
-		writel(0x00, DSI0_PHY_BASE + off + (4 * 0));
+		writel(0x00, reg_base + (4 * 0));
 		/* Regulator ctrl - CAL_PWD_CFG */
-		writel(pd->regulator[6], DSI0_PHY_BASE + off + (4 * 6));
+		writel(pd->regulator[6], reg_base + (4 * 6));
 		/* Add h/w recommended delay */
 		udelay(1000);
 		/* Regulator ctrl 1 */
-		writel(pd->regulator[1], DSI0_PHY_BASE + off + (4 * 1));
+		writel(pd->regulator[1], reg_base + (4 * 1));
 		/* Regulator ctrl 2 */
-		writel(pd->regulator[2], DSI0_PHY_BASE + off + (4 * 2));
+		writel(pd->regulator[2], reg_base + (4 * 2));
 		/* Regulator ctrl 3 */
-		writel(pd->regulator[3], DSI0_PHY_BASE + off + (4 * 3));
+		writel(pd->regulator[3], reg_base + (4 * 3));
 		/* Regulator ctrl 4 */
-		writel(pd->regulator[4], DSI0_PHY_BASE + off + (4 * 4));
+		writel(pd->regulator[4], reg_base + (4 * 4));
 		/* LDO ctrl */
 		writel(0x00, phy_base + 0x01dc);
 		/* Regulator ctrl 0 */
-		writel(pd->regulator[0], DSI0_PHY_BASE + off + (4 * 0));
+		writel(pd->regulator[0], reg_base + (4 * 0));
 		dmb();
 	}
 }
@@ -360,20 +359,22 @@
 }
 
 static int mdss_dsi_phy_28nm_init(struct mipi_panel_info *mipi,
-				uint32_t ctl_base, uint32_t phy_base)
+				uint32_t ctl_base, uint32_t phy_base, uint32_t reg_base)
 {
 	struct mdss_dsi_phy_ctrl *pd;
-	uint32_t i, off = 0, ln, offset;
+	uint32_t i, off = 0, ln, offset, dsi0_phy_base;
 
 	if (mdp_get_revision() == MDP_REV_304)
 		return mdss_dsi_v2_phy_init(mipi, ctl_base);
 
 	pd = (mipi->mdss_dsi_phy_db);
 
+	/* PHY_CTRL_0 */
+	 writel(0x5b, phy_base + 0x0170);
 	/* Strength ctrl 0 */
 	writel(pd->strength[0], phy_base + 0x0184);
 
-	mdss_dsi_phy_regulator_init(pd, phy_base);
+	mdss_dsi_phy_regulator_init(pd, ctl_base, phy_base, reg_base);
 
 	off = 0x0140;	/* phy timing ctrl 0 - 11 */
 	for (i = 0; i < 12; i++) {
@@ -382,12 +383,6 @@
 		off += 4;
 	}
 
-	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
-	writel(0x00, phy_base + 0x0174);
-	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
-	writel(0x5f, phy_base + 0x0170);
-
-	dmb();
 	/* 4 lanes + clk lane configuration */
 	/* lane config n * (0 - 4) & DataPath setup */
 	for (ln = 0; ln < 5; ln++) {
@@ -400,16 +395,20 @@
 		}
 	}
 
-	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
-	writel(0x5f, phy_base + 0x0170);
+	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_4 */
+	writel(0x0a, phy_base + 0x0180);
+	dmb();
 
+	dsi0_phy_base = DSI0_PHY_BASE + target_display_get_base_offset(DSI0_PHY_BASE);
 	/* DSI_PHY_DSIPHY_GLBL_TEST_CTRL */
-	if (phy_base == DSI0_PHY_BASE ||
+	if ((phy_base == dsi0_phy_base) ||
 		(readl(mipi->ctl_base) == DSI_HW_REV_103_1))
 		writel(0x01, phy_base + 0x01d4);
 	else
 		writel(0x00, phy_base + 0x01d4);
 
+	/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
+	writel(0x5f, phy_base + 0x0170);
 	dmb();
 
 	off = 0x01b4;	/* phy BIST ctrl 0 - 5 */
@@ -494,11 +493,11 @@
 		break;
 	case DSI_PLL_TYPE_28NM:
 	default:
-		ret = mdss_dsi_phy_28nm_init(mipi,
-				mipi->ctl_base, mipi->phy_base);
+		ret = mdss_dsi_phy_28nm_init(mipi, mipi->ctl_base,
+					mipi->phy_base, mipi->reg_base);
 		if (mipi->dual_dsi)
 			ret = mdss_dsi_phy_28nm_init(mipi, mipi->sctl_base,
-					mipi->sphy_base);
+					mipi->sphy_base, mipi->reg_base);
 		break;
 	}
 
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index ceb25e6..5067b8a 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -33,10 +33,13 @@
 
 #include <sys/types.h>
 #include <platform.h>
+#include <malloc.h>
+#include <string.h>
 
 #define SMEM_V7_SMEM_MAX_PMIC_DEVICES   1
 #define SMEM_V8_SMEM_MAX_PMIC_DEVICES   3
-#define SMEM_MAX_PMIC_DEVICES           SMEM_V8_SMEM_MAX_PMIC_DEVICES
+#define SMEM_V11_SMEM_MAX_PMIC_DEVICES  4 // this is the max that device tree currently supports
+#define SMEM_MAX_PMIC_DEVICES           SMEM_V11_SMEM_MAX_PMIC_DEVICES
 
 #define SMEM_RAM_PTABLE_VERSION_OFFSET  8
 
@@ -207,6 +210,18 @@
 	uint32_t chip_serial; /* Used as serial number for v10 */
 };
 
+struct smem_board_info_v11 {
+	struct smem_board_info_v3 board_info_v3;
+	unsigned platform_version;
+	unsigned fused_chip;
+	unsigned platform_subtype;
+	struct smem_pmic_info pmic_info[SMEM_V8_SMEM_MAX_PMIC_DEVICES]; // Depreciated
+	uint32_t foundry_id; /* Used as foundry_id only for v9  */
+	uint32_t chip_serial; /* Used as serial number for v10 */
+	uint32_t num_pmics; /* Number of pmics in array */
+	uint32_t pmic_array_offset; /* Offset from base of structure to array of pmic info types */
+};
+
 typedef struct {
 	unsigned key_len;
 	unsigned iv_len;
diff --git a/target/msm8916/include/target/display.h b/target/msm8916/include/target/display.h
index e27432f..6f2bb2e 100644
--- a/target/msm8916/include/target/display.h
+++ b/target/msm8916/include/target/display.h
@@ -126,11 +126,11 @@
 };
 
 static const char panel_lane_config[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbb
+  0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
+  0x01, 0xc0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x97,
+  0x01, 0xc0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x97,
+  0x01, 0xc0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x97,
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff
 };
 
 static const uint32_t panel_physical_ctrl[] = {
diff --git a/target/msm8952/include/target/display.h b/target/msm8952/include/target/display.h
index 42b3527..5c02765 100644
--- a/target/msm8952/include/target/display.h
+++ b/target/msm8952/include/target/display.h
@@ -48,20 +48,28 @@
 
 extern uint32_t panel_regulator_settings[7];
 
-static const uint32_t dcdc_regulator_settings[] = {
+static const uint32_t dcdc_regulator_settings_lpm[] = {
   0x03, 0x08, 0x07, 0x00, 0x20, 0x07, 0x01
 };
 
-static const uint32_t ldo_regulator_settings[] = {
+static const uint32_t ldo_regulator_settings_lpm[] = {
+  0x00, 0x01, 0x01, 0x00, 0x20, 0x07, 0x00
+};
+
+static const uint32_t dcdc_regulator_settings_hpm[] = {
+  0x03, 0x09, 0x03, 0x00, 0x20, 0x07, 0x01
+};
+
+static const uint32_t ldo_regulator_settings_hpm[] = {
   0x00, 0x01, 0x01, 0x00, 0x20, 0x07, 0x00
 };
 
 static const char panel_lane_config[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
-  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbb
+  0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x97,
+  0x01, 0xc0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x97,
+  0x01, 0xc0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x97,
+  0x01, 0xc0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x97,
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff
 };
 
 static const uint32_t panel_physical_ctrl[] = {
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index 7fe6a47..50d693f 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -47,6 +47,7 @@
 #include "include/panel_truly_1080p_cmd.h"
 #include "include/panel_otm1906c_1080p_cmd.h"
 #include "include/panel_sharp_1080p_cmd.h"
+#include "include/panel_nt35597_wqxga_dualdsi_video.h"
 
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
@@ -56,6 +57,7 @@
 	TRULY_1080P_CMD_PANEL,
 	OTM1906C_1080P_CMD_PANEL,
 	SHARP_1080P_CMD_PANEL,
+	NT35597_WQXGA_DUALDSI_VIDEO_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -71,6 +73,7 @@
 	{"truly_1080p_video", TRULY_1080P_VIDEO_PANEL},
 	{"truly_1080p_cmd", TRULY_1080P_CMD_PANEL},
 	{"sharp_1080p_cmd", SHARP_1080P_CMD_PANEL},
+	{"nt35597_wqxga_dualdsi_video", NT35597_WQXGA_DUALDSI_VIDEO_PANEL},
 };
 
 static uint32_t panel_id;
@@ -216,6 +219,37 @@
 		memcpy(phy_db->timing,
 				sharp_1080p_cmd_timings, TIMING_SIZE);
 		break;
+	case NT35597_WQXGA_DUALDSI_VIDEO_PANEL:
+		panelstruct->paneldata    = &nt35597_wqxga_dualdsi_video_panel_data;
+		panelstruct->paneldata->panel_operating_mode = DST_SPLIT_FLAG |
+					SPLIT_DISPLAY_FLAG | DUAL_DSI_FLAG;
+		panelstruct->paneldata->panel_with_enable_gpio = 0;
+
+		panelstruct->panelres     = &nt35597_wqxga_dualdsi_video_panel_res;
+		panelstruct->color        = &nt35597_wqxga_dualdsi_video_color;
+		panelstruct->videopanel   = &nt35597_wqxga_dualdsi_video_video_panel;
+		panelstruct->commandpanel = &nt35597_wqxga_dualdsi_video_command_panel;
+		panelstruct->state        = &nt35597_wqxga_dualdsi_video_state;
+		panelstruct->laneconfig   = &nt35597_wqxga_dualdsi_video_lane_config;
+		panelstruct->paneltiminginfo
+					= &nt35597_wqxga_dualdsi_video_timing_info;
+		panelstruct->panelresetseq
+					= &nt35597_wqxga_dualdsi_video_reset_seq;
+		panelstruct->backlightinfo = &nt35597_wqxga_dualdsi_video_backlight;
+		pinfo->labibb = &nt35597_wqxga_dualdsi_video_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= nt35597_wqxga_dualdsi_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= NT35597_WQXGA_DUALDSI_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= nt35597_wqxga_dualdsi_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= NT35597_WQXGA_DUALDSI_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing, nt35597_wqxga_dualdsi_video_timings,
+			TIMING_SIZE);
+		pinfo->mipi.tx_eot_append = true;
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -258,10 +292,16 @@
 
 	switch (hw_id) {
 	case HW_PLATFORM_MTP:
-		panel_id = TRULY_1080P_VIDEO_PANEL;
+		if (platform_is_msm8956())
+			panel_id = NT35597_WQXGA_DUALDSI_VIDEO_PANEL;
+		else
+			panel_id = TRULY_1080P_VIDEO_PANEL;
 		break;
 	case HW_PLATFORM_SURF:
-		panel_id = TRULY_1080P_VIDEO_PANEL;
+		if (platform_is_msm8956())
+			panel_id = NT35597_WQXGA_DUALDSI_VIDEO_PANEL;
+		else
+			panel_id = TRULY_1080P_VIDEO_PANEL;
 		break;
 	case HW_PLATFORM_QRD:
 		panel_id = OTM1906C_1080P_CMD_PANEL;
@@ -277,8 +317,12 @@
 	 * Update all data structures after 'panel_init' label. Only panel
 	 * selection is supposed to happen before that.
 	 */
-	memcpy(panel_regulator_settings,
-			dcdc_regulator_settings, REGULATOR_SIZE);
+	if (platform_is_msm8956())
+		memcpy(panel_regulator_settings,
+			dcdc_regulator_settings_hpm, REGULATOR_SIZE);
+	else
+		memcpy(panel_regulator_settings,
+			dcdc_regulator_settings_lpm, REGULATOR_SIZE);
 	pinfo->pipe_type = MDSS_MDP_PIPE_TYPE_RGB;
 	return init_panel_data(panelstruct, pinfo, phy_db);
 }
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 2a908d6..517de58 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -45,6 +45,7 @@
 #include <platform/iomap.h>
 #include <target/display.h>
 #include <qtimer.h>
+#include <platform.h>
 
 #include "include/panel.h"
 #include "include/display_resource.h"
@@ -65,12 +66,21 @@
   "msmgpio", 91, 3, 1, 0, 1
 };
 
+static struct gpio_pin lcd_mode_gpio = {
+  "msmgpio", 107, 3, 1, 0, 1
+};
+
 #define VCO_DELAY_USEC 1000
 #define GPIO_STATE_LOW 0
 #define GPIO_STATE_HIGH 2
 #define RESET_GPIO_SEQ_LEN 3
 #define PMIC_WLED_SLAVE_ID 3
 
+#define DSI0_BASE_ADJUST -0x4000
+#define DSI0_PHY_BASE_ADJUST -0x4100
+#define DSI0_PHY_PLL_BASE_ADJUST -0x3900
+#define DSI0_PHY_REGULATOR_BASE_ADJUST -0x3C00
+
 static void mdss_dsi_uniphy_pll_sw_reset_8952(uint32_t pll_base)
 {
 	writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
@@ -92,6 +102,20 @@
 	writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
 	udelay(1);
 	writel(0x00, pll_base + 0x0068); /* PLL TEST CFG */
+	udelay(1);
+}
+
+static uint32_t dsi_pll_lock_status_8956(uint32_t pll_base)
+{
+	uint32_t counter, status;
+
+	status = readl(pll_base + 0x00c0) & 0x01;
+	for (counter = 0; counter < 5 && !status; counter++) {
+		udelay(100);
+		status = readl(pll_base + 0x00c0) & 0x01;
+	}
+
+	return status;
 }
 
 static uint32_t gf_1_dsi_pll_enable_sequence_8952(uint32_t pll_base)
@@ -201,6 +225,33 @@
 	return pll_locked;
 }
 
+static uint32_t dsi_pll_enable_seq_8956(uint32_t pll_base)
+{
+	/*
+	 * PLL power up sequence
+	 * Add necessary delays recommended by h/w team
+	 */
+
+	/* Lock Detect setting */
+	writel(0x0d, pll_base + 0x0064); /* LKDetect CFG2 */
+	writel(0x34, pll_base + 0x0070); /* PLL CAL_CFG1 */
+	writel(0x10, pll_base + 0x005c); /* LKDetect CFG0 */
+	writel(0x1a, pll_base + 0x0060); /* LKDetect CFG1 */
+
+	writel(0x01, pll_base + 0x0020); /* GLB CFG */
+	udelay(300);
+	writel(0x05, pll_base + 0x0020); /* GLB CFG */
+	udelay(300);
+	writel(0x0f, pll_base + 0x0020); /* GLB CFG */
+	udelay(300);
+	writel(0x07, pll_base + 0x0020); /* GLB CFG */
+	udelay(300);
+	writel(0x0f, pll_base + 0x0020); /* GLB CFG */
+	udelay(1000);
+
+	return dsi_pll_lock_status_8956(pll_base);
+}
+
 static int msm8952_wled_backlight_ctrl(uint8_t enable)
 {
 	uint8_t slave_id = PMIC_WLED_SLAVE_ID;	/* pmi */
@@ -223,12 +274,39 @@
 	return ret;
 }
 
-int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
+static int32_t mdss_dsi_pll_config(uint32_t pll_base, uint32_t ctl_base,
+		struct mdss_dsi_pll_config *pll_data)
 {
 	int32_t ret = 0;
+	if (!platform_is_msm8956())
+		mdss_dsi_uniphy_pll_sw_reset_8952(pll_base);
+	else
+		dsi_pll_sw_reset_8952(pll_base);
+	mdss_dsi_auto_pll_config(pll_base, ctl_base, pll_data);
+	if (platform_is_msm8956())
+		ret = dsi_pll_enable_seq_8956(pll_base);
+	else
+		ret = dsi_pll_enable_seq_8952(pll_base);
+
+	return ret;
+}
+
+int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
+{
+	int32_t ret = 0, flags;
 	struct mdss_dsi_pll_config *pll_data;
 	dprintf(SPEW, "target_panel_clock\n");
 
+	if (pinfo->dest == DISPLAY_2) {
+		flags = MMSS_DSI_CLKS_FLAG_DSI1;
+		if (pinfo->mipi.dual_dsi)
+			flags |= MMSS_DSI_CLKS_FLAG_DSI0;
+	} else {
+		flags = MMSS_DSI_CLKS_FLAG_DSI0;
+		if (pinfo->mipi.dual_dsi)
+			flags |= MMSS_DSI_CLKS_FLAG_DSI1;
+	}
+
 	pll_data = pinfo->mipi.dsi_pll_config;
 	pll_data->vco_delay = VCO_DELAY_USEC;
 
@@ -246,15 +324,23 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		mdss_dsi_uniphy_pll_sw_reset_8952(pinfo->mipi.pll_base);
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
-						pinfo->mipi.ctl_base, pll_data);
-		if (!dsi_pll_enable_seq_8952(pinfo->mipi.pll_base))
-			dprintf(CRITICAL, "Not able to enable the pll\n");
-		gcc_dsi_clocks_enable(pll_data->pclk_m, pll_data->pclk_n,
+
+		ret = mdss_dsi_pll_config(pinfo->mipi.pll_base,
+			pinfo->mipi.ctl_base, pll_data);
+		if (!ret)
+			dprintf(CRITICAL, "Not able to enable master pll\n");
+
+		if (platform_is_msm8956() && pinfo->mipi.dual_dsi) {
+				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);
 	} else if(!target_cont_splash_screen()) {
-		gcc_dsi_clocks_disable();
+		gcc_dsi_clocks_disable(flags);
 		mdp_clock_disable();
 		mdss_bus_clocks_disable();
 		mdp_gdsc_ctrl(enable);
@@ -268,8 +354,13 @@
 {
 	int ret = NO_ERROR;
 
+	if (platform_is_msm8956()) {
+		reset_gpio.pin_id = 25;
+		bkl_gpio.pin_id = 66;
+	}
+
 	if (enable) {
-		if (pinfo->mipi.use_enable_gpio) {
+		if (pinfo->mipi.use_enable_gpio && !platform_is_msm8956()) {
 			gpio_tlmm_config(enable_gpio.pin_id, 0,
 				enable_gpio.pin_direction, enable_gpio.pin_pull,
 				enable_gpio.pin_strength,
@@ -298,10 +389,23 @@
 				gpio_set_dir(reset_gpio.pin_id, GPIO_STATE_HIGH);
 			mdelay(resetseq->sleep[i]);
 		}
+
+		if (platform_is_msm8956()) {
+			gpio_tlmm_config(lcd_mode_gpio.pin_id, 0,
+				lcd_mode_gpio.pin_direction, lcd_mode_gpio.pin_pull,
+				lcd_mode_gpio.pin_strength, lcd_mode_gpio.pin_state);
+
+			if (pinfo->lcdc.split_display || pinfo->lcdc.dst_split)
+				gpio_set_dir(lcd_mode_gpio.pin_id, GPIO_STATE_LOW);
+			else
+				gpio_set_dir(lcd_mode_gpio.pin_id, GPIO_STATE_HIGH);
+		}
 	} else if(!target_cont_splash_screen()) {
 		gpio_set_dir(reset_gpio.pin_id, 0);
-		if (pinfo->mipi.use_enable_gpio)
+		if (pinfo->mipi.use_enable_gpio && !platform_is_msm8956())
 			gpio_set_dir(enable_gpio.pin_id, 0);
+		if (platform_is_msm8956())
+			gpio_set_dir(lcd_mode_gpio.pin_id, 0);
 	}
 
 	return ret;
@@ -372,17 +476,39 @@
 	return NO_ERROR;
 }
 
+int target_display_get_base_offset(uint32_t base)
+{
+	if(platform_is_msm8956()) {
+		if (base == MIPI_DSI0_BASE)
+			return DSI0_BASE_ADJUST;
+		else if (base == DSI0_PHY_BASE)
+			return DSI0_PHY_BASE_ADJUST;
+		else if (base == DSI0_PLL_BASE)
+			return DSI0_PHY_PLL_BASE_ADJUST;
+		else if (base == DSI0_REGULATOR_BASE)
+			return DSI0_PHY_REGULATOR_BASE_ADJUST;
+	}
+
+	return 0;
+}
+
 int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
 {
+	uint32_t ldo_num = REG_LDO6 | REG_LDO17;
+
+	if (platform_is_msm8956())
+		ldo_num |= REG_LDO1;
+	else
+		ldo_num |= REG_LDO2;
 
 	if (enable) {
-		regulator_enable(REG_LDO2 | REG_LDO6 | REG_LDO17);
+		regulator_enable(ldo_num);
 		mdelay(10);
 		wled_init(pinfo);
 		qpnp_ibb_enable(true); /*5V boost*/
 		mdelay(50);
 	} else {
-		regulator_disable(REG_LDO2 | REG_LDO6 | REG_LDO17);
+		regulator_disable(ldo_num);
 	}
 
 	return NO_ERROR;
diff --git a/target/msm8994/target_display.c b/target/msm8994/target_display.c
index bb3fa2f..2384b1f 100644
--- a/target/msm8994/target_display.c
+++ b/target/msm8994/target_display.c
@@ -589,9 +589,11 @@
 int target_display_get_base_offset(uint32_t base)
 {
 	if(platform_is_msm8992()) {
-		if (base == MIPI_DSI0_BASE)
+		if ((base == MIPI_DSI0_BASE) || (base == DSI0_PHY_BASE) ||
+		    (base == DSI0_PLL_BASE) || (base == DSI0_REGULATOR_BASE))
 			return DSI0_BASE_ADJUST;
-		else if (base == MIPI_DSI1_BASE)
+		else if ((base == MIPI_DSI1_BASE) || (base == DSI1_PHY_BASE) ||
+			(base == DSI1_PLL_BASE))
 			return DSI1_BASE_ADJUST;
 	}
 
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index f3c1327..2659ee2 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -235,6 +235,8 @@
 {
 	dprintf(INFO, "target_init()\n");
 
+	pmic_info_populate();
+
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
 
 	target_keystatus();