Merge "platform: msm8952: add support for split DSI for msm8956"
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/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 40460e0..517de58 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -274,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;
 
@@ -297,22 +324,23 @@
 			mdp_gdsc_ctrl(0);
 			return ret;
 		}
-		if (!platform_is_msm8956())
-			mdss_dsi_uniphy_pll_sw_reset_8952(pinfo->mipi.pll_base);
-		else
-			dsi_pll_sw_reset_8952(pinfo->mipi.pll_base);
-		mdss_dsi_auto_pll_config(pinfo->mipi.pll_base,
-						pinfo->mipi.ctl_base, pll_data);
-		if (platform_is_msm8956())
-			ret = dsi_pll_enable_seq_8956(pinfo->mipi.pll_base);
-		else
-			ret = dsi_pll_enable_seq_8952(pinfo->mipi.pll_base);
+
+		ret = mdss_dsi_pll_config(pinfo->mipi.pll_base,
+			pinfo->mipi.ctl_base, pll_data);
 		if (!ret)
-			dprintf(CRITICAL, "Not able to enable the pll\n");
-		gcc_dsi_clocks_enable(pll_data->pclk_m, pll_data->pclk_n,
+			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);