Merge "platform: msm_shared: Update MDP5 for msm8956 support"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 83d1531..9a908ce 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
 
@@ -2263,6 +2271,8 @@
 	int index = INVALID_PTN;
 	uint32_t i;
 	uint8_t lun = 0;
+	/*End of the sparse image address*/
+	uint32_t data_end = (uint32_t)data + sz;
 
 	index = partition_get_index(arg);
 	ptn = partition_get_offset(index);
@@ -2272,28 +2282,34 @@
 	}
 
 	size = partition_get_size(index);
-	if (ROUND_TO_PAGE(sz,511) > size) {
-		fastboot_fail("size too large");
-		return;
-	}
 
 	lun = partition_get_lun(index);
 	mmc_set_lun(lun);
 
+	if (sz < sizeof(sparse_header_t)) {
+		fastboot_fail("size too low");
+		return;
+	}
+
 	/* Read and skip over sparse image header */
 	sparse_header = (sparse_header_t *) data;
+
 	if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
 		fastboot_fail("size too large");
 		return;
 	}
 
-	data += sparse_header->file_hdr_sz;
-	if(sparse_header->file_hdr_sz > sizeof(sparse_header_t))
+	data += sizeof(sparse_header_t);
+
+	if (data_end < (uint32_t)data) {
+		fastboot_fail("buffer overreads occured due to invalid sparse header");
+		return;
+	}
+
+	if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
 	{
-		/* Skip the remaining bytes in a header that is longer than
-		 * we expected.
-		 */
-		data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
+		fastboot_fail("sparse header size mismatch");
+		return;
 	}
 
 	dprintf (SPEW, "=== Sparse Image Header ===\n");
@@ -2318,17 +2334,20 @@
 		chunk_header = (chunk_header_t *) data;
 		data += sizeof(chunk_header_t);
 
+		if (data_end < (uint32_t)data) {
+			fastboot_fail("buffer overreads occured due to invalid sparse header");
+			return;
+		}
+
 		dprintf (SPEW, "=== Chunk Header ===\n");
 		dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
 		dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
 		dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
 
-		if(sparse_header->chunk_hdr_sz > sizeof(chunk_header_t))
+		if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
 		{
-			/* Skip the remaining bytes in a header that is longer than
-			 * we expected.
-			 */
-			data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t));
+			fastboot_fail("chunk header size mismatch");
+			return;
 		}
 
 		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
@@ -2359,6 +2378,11 @@
 				return;
 			}
 
+			if (data_end < (uint32_t)data + chunk_data_sz) {
+				fastboot_fail("buffer overreads occured due to invalid sparse header");
+				return;
+			}
+
 			if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
 						chunk_data_sz,
 						(unsigned int*)data))
@@ -2389,6 +2413,10 @@
 				return;
 			}
 
+			if (data_end < (uint32_t)data + sizeof(uint32_t)) {
+				fastboot_fail("buffer overreads occured due to invalid sparse header");
+				return;
+			}
 			fill_val = *(uint32_t *)data;
 			data = (char *) data + sizeof(uint32_t);
 			chunk_blk_cnt = chunk_data_sz / sparse_header->blk_sz;
@@ -2441,7 +2469,15 @@
 				return;
 			}
 			total_blocks += chunk_header->chunk_sz;
+			if ((uint32_t)data > UINT_MAX - chunk_data_sz) {
+				fastboot_fail("integer overflow occured");
+				return;
+			}
 			data += chunk_data_sz;
+			if (data_end < (uint32_t)data) {
+				fastboot_fail("buffer overreads occured due to invalid sparse header");
+				return;
+			}
 			break;
 
 			default:
@@ -2537,18 +2573,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/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 3db1d21..578f4de 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -62,6 +62,7 @@
 
 int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
 int scm_random(uint32_t * rbuf, uint32_t  r_len);
+void free_mdtp_image(void);
 
 /********************************************************************************/
 
@@ -422,7 +423,7 @@
 				// Valid PIN - deactivate and continue boot
 				dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
 				write_deactivated_DIP();
-				return;
+				goto out;
 			}
 			else
 			{
@@ -440,6 +441,9 @@
 		dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
 		display_error_msg(); /* This will never return */
 	}
+
+	out:
+	free_mdtp_image();
 }
 
 /* Verify the boot or recovery partitions using boot_verifier. */
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 6200eb5..fcf7259 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -99,7 +99,7 @@
 
 static bool g_initial_screen_displayed = false;
 
-static struct mdtp_fbimage g_mdtp_header;
+static struct mdtp_fbimage *g_mdtp_header = NULL;
 static struct fbcon_config *fb_config = NULL;
 
 /*----------------------------------------------------------------------------
@@ -107,13 +107,33 @@
  * -------------------------------------------------------------------------*/
 
 /**
+ * Allocate mdtp image
+ */
+static void alloc_mdtp_image() {
+	if (!g_mdtp_header) {
+		g_mdtp_header = (struct mdtp_fbimage *)malloc(sizeof(struct mdtp_fbimage));
+		ASSERT(g_mdtp_header);
+	}
+}
+
+/**
+ * Free mdtp image
+ */
+void free_mdtp_image() {
+	if (g_mdtp_header) {
+		free(g_mdtp_header);
+		g_mdtp_header = NULL;
+	}
+}
+
+/**
  * Load images from EMMC
  */
 static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
 {
 	int index = INVALID_PTN;
 	unsigned long long ptn = 0;
-	struct mdtp_fbimage *logo = &g_mdtp_header;
+	struct mdtp_fbimage *logo = g_mdtp_header;
 	uint32_t block_size = mmc_get_device_blocksize();
 
 	index = partition_get_index("mdtp");
@@ -433,12 +453,13 @@
  */
 static void display_initial_screen(uint32_t pin_length)
 {
-    if (g_initial_screen_displayed == true)
+	if (g_initial_screen_displayed == true)
 		return;
 
-    fb_config = fbcon_display();
+	fb_config = fbcon_display();
+	alloc_mdtp_image();
 
-    if (fb_config)
+	if (fb_config)
 	{
 		fbcon_clear();
 
@@ -589,6 +610,7 @@
 void display_error_msg()
 {
 	fb_config = fbcon_display();
+	alloc_mdtp_image();
 
 	if (fb_config)
 	{
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/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 6cda324..f6e962a 100644
--- a/platform/msm8952/include/platform/clock.h
+++ b/platform/msm8952/include/platform/clock.h
@@ -65,6 +65,22 @@
 #define DSI_PIXEL0_N                    REG_MM(0x4D00C)
 #define DSI_PIXEL0_D                    REG_MM(0x4D010)
 
+#define DSI_BYTE1_CMD_RCGR              REG_MM(0x4D0B0)
+#define DSI_BYTE1_CFG_RCGR              REG_MM(0x4D0B4)
+#define DSI_BYTE1_CBCR                  REG_MM(0x4D0A0)
+#define DSI_ESC1_CMD_RCGR               REG_MM(0x4D0A8)
+#define DSI_ESC1_CFG_RCGR               REG_MM(0x4D0AC)
+#define DSI_ESC1_CBCR                   REG_MM(0x4D09C)
+#define DSI_PIXEL1_CMD_RCGR             REG_MM(0x4D0B8)
+#define DSI_PIXEL1_CFG_RCGR             REG_MM(0x4D0BC)
+#define DSI_PIXEL1_CBCR                 REG_MM(0x4D0A4)
+#define DSI_PIXEL1_M                    REG_MM(0x4D0C0)
+#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);
@@ -79,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 762ee9d..ae61934 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -99,6 +99,7 @@
 #define APCS_CLOCK_BRANCH_ENA_VOTE         (CLK_CTL_BASE + 0x45004)
 #define GPLL4_MODE                         (CLK_CTL_BASE + 0x24000)
 #define GPLL4_STATUS                       (CLK_CTL_BASE + 0x24024)
+#define GPLL6_STATUS                       (CLK_CTL_BASE + 0x3701C)
 
 /* SDCC */
 #define SDC1_HDRV_PULL_CTL                 (TLMM_BASE_ADDR + 0x10A000)
@@ -149,11 +150,11 @@
 /* MDSS */
 #define MIPI_DSI_BASE               (0x1A98000)
 #define MIPI_DSI0_BASE              MIPI_DSI_BASE
-#define MIPI_DSI1_BASE              MIPI_DSI_BASE
+#define MIPI_DSI1_BASE              (0x1A96000)
 #define DSI0_PHY_BASE               (0x1A98500)
-#define DSI1_PHY_BASE               DSI0_PHY_BASE
+#define DSI1_PHY_BASE               (0x1A96400)
 #define DSI0_PLL_BASE               (0x1A98300)
-#define DSI1_PLL_BASE               DSI0_PLL_BASE
+#define DSI1_PLL_BASE               (0x1A96A00)
 #define DSI0_REGULATOR_BASE         (0x1A98780)
 #define DSI1_REGULATOR_BASE         DSI0_REGULATOR_BASE
 #define MDP_BASE                    (0x1A00000)
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
index fd1d6f7..b87406d 100644
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -41,7 +41,8 @@
 #define gpll0_source_val  1
 #define gpll4_source_val  2
 #define cxo_mm_source_val 0
-#define gpll0_mm_source_val 1
+#define gpll0_mm_source_val 6
+#define gpll6_mm_source_val 3
 
 struct clk_freq_tbl rcg_dummy_freq = F_END;
 
@@ -126,6 +127,21 @@
 	},
 };
 
+static struct pll_vote_clk gpll6_clk_src =
+{
+	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
+	.en_mask      = BIT(7),
+	.status_reg   = (void *) GPLL6_STATUS,
+	.status_mask  = BIT(17),
+	.parent       = &cxo_clk_src.c,
+
+	.c = {
+		.rate     = 1080000000,
+		.dbg_name = "gpll6_clk_src",
+		.ops      = &clk_ops_pll_vote,
+	},
+};
+
 /* SDCC Clocks */
 static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk[] =
 {
@@ -346,11 +362,30 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_mdss_esc1_1_clk[] = {
+	F_MM(19200000,    cxo,   1,   0,   0),
+	F_END
+};
+
 static struct clk_freq_tbl ftbl_mdp_clk[] = {
-	F_MM( 80000000,  gpll0,   10,    0,    0),
-	F_MM( 100000000, gpll0,    8,    0,    0),
-	F_MM( 200000000, gpll0,    4,    0,    0),
-	F_MM( 320000000, gpll0,  2.5,    0,    0),
+	F( 80000000,  gpll0,   10,    0,    0),
+	F( 100000000, gpll0,    8,    0,    0),
+	F( 200000000, gpll0,    4,    0,    0),
+	F( 320000000, gpll0,  2.5,    0,    0),
+	F_END
+};
+
+static struct clk_freq_tbl ftbl_mdp_clk_8956[] = {
+	F_MM(  50000000, gpll0,   16,    0,     0),
+	F_MM(  80000000, gpll0,   10,    0,     0),
+	F_MM( 100000000, gpll0,    8,    0,     0),
+	F_MM( 145454545, gpll0,  5.5,    0,     0),
+	F_MM( 160000000, gpll0,    5,    0,     0),
+	F_MM( 177777778, gpll0,  4.5,    0,     0),
+	F_MM( 200000000, gpll0,    4,    0,     0),
+	F_MM( 270000000, gpll6,    4,    0,     0),
+	F_MM( 320000000, gpll0,  2.5,    0,     0),
+	F_MM( 360000000, gpll6,    3,    0,     0),
 	F_END
 };
 
@@ -366,6 +401,18 @@
 	},
 };
 
+static struct rcg_clk dsi_esc1_clk_src = {
+	.cmd_reg  = (uint32_t *) DSI_ESC1_CMD_RCGR,
+	.cfg_reg  = (uint32_t *) DSI_ESC1_CFG_RCGR,
+	.set_rate = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl = ftbl_mdss_esc1_1_clk,
+
+	.c        = {
+		.dbg_name = "dsi_esc1_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
 static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
 	F_MM(19200000,    cxo,   1,   0,   0),
 	F_END
@@ -394,6 +441,17 @@
 	},
 };
 
+static struct branch_clk mdss_esc1_clk = {
+	.cbcr_reg    = (uint32_t *) DSI_ESC1_CBCR,
+	.parent      = &dsi_esc1_clk_src.c,
+	.has_sibling = 0,
+
+	.c           = {
+		.dbg_name = "mdss_esc1_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct branch_clk mdss_axi_clk = {
 	.cbcr_reg    = (uint32_t *) MDP_AXI_CBCR,
 	.has_sibling = 1,
@@ -517,6 +575,7 @@
 
 	CLK_LOOKUP("mdp_ahb_clk",          mdp_ahb_clk.c),
 	CLK_LOOKUP("mdss_esc0_clk",        mdss_esc0_clk.c),
+	CLK_LOOKUP("mdss_esc1_clk",        mdss_esc1_clk.c),
 	CLK_LOOKUP("mdss_axi_clk",         mdss_axi_clk.c),
 	CLK_LOOKUP("mdss_vsync_clk",       mdss_vsync_clk.c),
 	CLK_LOOKUP("mdss_mdp_clk_src",     mdss_mdp_clk_src.c),
@@ -532,6 +591,7 @@
 {
 	gpll4_clk_src.status_reg = (void *)GPLL4_STATUS;
 	gpll4_clk_src.status_mask = BIT(17);
+	mdss_mdp_clk_src.freq_tbl = ftbl_mdp_clk_8956;
 }
 
 void platform_clock_init(void)
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/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/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/rpm-glink.c b/platform/msm_shared/rpm-glink.c
index 77538f0..bc95db0 100644
--- a/platform/msm_shared/rpm-glink.c
+++ b/platform/msm_shared/rpm-glink.c
@@ -53,7 +53,8 @@
 
 glink_handle_type rpm_glink_port, ssr_glink_port;
 static uint32_t msg_id;
-static event_t wait_for_init;
+static event_t wait_for_rpm_init;
+static event_t wait_for_ssr_init;
 static event_t wait_for_data;
 
 extern glink_err_type glink_wait_link_down(glink_handle_type handle);
@@ -262,7 +263,17 @@
 {
 	if(event == GLINK_CONNECTED)
 	{
-		event_signal(&wait_for_init, false);
+		event_signal(&wait_for_rpm_init, false);
+		dprintf(INFO, "Glink Connection between APPS and RPM established\n");
+		return;
+	}
+}
+
+void rpm_glink_notify_state_ssr_isr(glink_handle_type handle, void *data, glink_channel_event_type event)
+{
+	if(event == GLINK_CONNECTED)
+	{
+		event_signal(&wait_for_ssr_init, false);
 		dprintf(INFO, "Glink Connection between APPS and RPM established\n");
 		return;
 	}
@@ -303,7 +314,7 @@
 	glink_ssr_open_cfg.notify_rx = NULL;
 	glink_ssr_open_cfg.notify_rxv = (glink_rxv_notification_cb)rpm_vector_glink_ssr_isr;
 	glink_ssr_open_cfg.notify_tx_done = (glink_tx_notification_cb)rpm_glink_tx_done_isr;
-	glink_ssr_open_cfg.notify_state = (glink_state_notification_cb)rpm_glink_notify_state_isr;
+	glink_ssr_open_cfg.notify_state = (glink_state_notification_cb)rpm_glink_notify_state_ssr_isr;
 	glink_ssr_open_cfg.priv = NULL;
 
 	ret = glink_open(&glink_ssr_open_cfg, &ssr_glink_port);
@@ -321,7 +332,8 @@
 {
 	glink_err_type ret;
 	glink_link_id_type link_id;
-	event_init(&wait_for_init, false, EVENT_FLAG_AUTOUNSIGNAL);
+	event_init(&wait_for_rpm_init, false, EVENT_FLAG_AUTOUNSIGNAL);
+	event_init(&wait_for_ssr_init, false, EVENT_FLAG_AUTOUNSIGNAL);
 
 	dprintf(INFO, "RPM GLink Init\n");
 	// Initialize RPM transport
@@ -339,7 +351,8 @@
 		dprintf(CRITICAL, "RPM Glink Init Failure 0x%x\n", ret);
 		ASSERT(0);
 	}
-	event_wait(&wait_for_init);
+	event_wait(&wait_for_rpm_init);
+	event_wait(&wait_for_ssr_init);
 }
 
 void rpm_glink_uninit()
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/init.c b/target/msm8952/init.c
index fb83af9..1f4f60c 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -167,21 +167,21 @@
 int target_volume_up()
 {
 	uint8_t status = 0;
+	uint32_t vol_up_gpio;
 
 	if(platform_is_msm8956())
-	{
-		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO_8956, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
-	}
+		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8956;
+
 	else
-	{
-		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
-	}
+		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO;
+
+	gpio_tlmm_config(vol_up_gpio, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
 
 	/* Wait for the gpio config to take effect - debounce time */
 	thread_sleep(10);
 
 	/* Get status of GPIO */
-	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
+	status = gpio_status(vol_up_gpio);
 
 	/* Active low signal. */
 	return !status;
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index b503962..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,10 +73,13 @@
 	{"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;
 
+#define TRULY_1080P_CMD_PANEL_ON_DELAY 40
+
 int oem_panel_rotation()
 {
 	return NO_ERROR;
@@ -89,7 +94,10 @@
 	if (panel_id == OTM1906C_1080P_CMD_PANEL) {
 		/* needs extra delay to avoid unexpected artifacts */
 		mdelay(OTM1906C_1080P_CMD_PANEL_ON_DELAY);
+	} else if (panel_id == TRULY_1080P_CMD_PANEL) {
+		mdelay(TRULY_1080P_CMD_PANEL_ON_DELAY);
 	}
+
 	return NO_ERROR;
 }
 
@@ -211,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));
@@ -253,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;
@@ -272,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();