platform: correct the sequence for enabling DSI pixel clock

In the current implementation, the M,N,D values for DSI pixel clock is
set after setting the update RCG bit in DSI_PCLK_CMD_RCGR register.
This causes the dirty bits for M,N,D to be set in PCLK_CMD_RCGR causing
issues during handoff in kernel for DSI pixel clock. Update the sequence
to take care of this for multiple targets.

Change-Id: Ifcc53ca1787b710cd1a154738a7c1ccd472d22c7
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
index bdd1d6d..87e31dd 100644
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -36,6 +36,8 @@
 #include <platform/clock.h>
 #include <platform.h>
 
+#define MAX_LOOPS	500
+
 void hsusb_clock_init(void)
 {
 	int ret;
@@ -265,6 +267,34 @@
 	}
 }
 
+static void rcg_update_config(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(0)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < MAX_LOOPS; i++) {
+		if (!(readl(reg) & BIT(31)))
+			return;
+		udelay(1);
+	}
+
+	dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+	ASSERT(0);
+}
+
 /* Disable all the branch clocks needed by the DSI controller */
 void gcc_dsi_clocks_disable(void)
 {
@@ -278,20 +308,32 @@
 {
 	int ret;
 
-	/* Configure Byte clock -autopll- This will not change becasue
-	byte clock does not need any divider*/
+	/*
+	 * 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);
 
 	/* Configure Pixel clock */
+	/* Set the source for DSI0 pixel RCG */
 	writel(0x100, DSI_PIXEL0_CFG_RCGR);
-	writel(0x1, DSI_PIXEL0_CMD_RCGR);
-	writel(0x1, DSI_PIXEL0_CBCR);
-
+	/* 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);