msm: clock-dss-8960: Fix HDMI PLL power up/down sequence

Fix HDMI PLL power up/down sequence along with proper control
of HDMI PHY registers to avoid PLL lock detect failures

CRs-Fixed: 328366
Change-Id: Ic8a791f62b1e695bd70081c11156d57191a66de3
Signed-off-by: Ravishangar Kalyanam <rkalya@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-dss-8960.c b/arch/arm/mach-msm/clock-dss-8960.c
index 7374f92..8331899 100644
--- a/arch/arm/mach-msm/clock-dss-8960.c
+++ b/arch/arm/mach-msm/clock-dss-8960.c
@@ -102,16 +102,38 @@
 	ahb_enabled = ahb_en_reg & BIT(4);
 	if (!ahb_enabled) {
 		writel_relaxed(ahb_en_reg | BIT(4), AHB_EN_REG);
+		/* Make sure iface clock is enabled before register access */
 		mb();
 	}
 
+	/* Assert PLL S/W reset */
+	writel_relaxed(0x8D, HDMI_PHY_PLL_LOCKDET_CFG2);
+	writel_relaxed(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
+	writel_relaxed(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
+	/* De-assert PLL S/W reset */
+	writel_relaxed(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
+
+	val = readl_relaxed(HDMI_PHY_REG_12);
+	val |= BIT(5);
+	/* Assert PHY S/W reset */
+	writel_relaxed(val, HDMI_PHY_REG_12);
+	val &= ~BIT(5);
+	/* De-assert PHY S/W reset */
+	writel_relaxed(val, HDMI_PHY_REG_12);
+	writel_relaxed(0x3f, HDMI_PHY_REG_2);
+
+	val = readl_relaxed(HDMI_PHY_REG_12);
+	val |= PWRDN_B;
+	writel_relaxed(val, HDMI_PHY_REG_12);
+	/* Wait 10 us for enabling global power for PHY */
+	mb();
+	udelay(10);
+
 	val = readl_relaxed(HDMI_PHY_PLL_PWRDN_B);
 	val |= PLL_PWRDN_B;
-	writel_relaxed(val, HDMI_PHY_PLL_PWRDN_B);
-	mb();
 	val &= ~PD_PLL;
 	writel_relaxed(val, HDMI_PHY_PLL_PWRDN_B);
-	mb();
+	writel_relaxed(0x80, HDMI_PHY_REG_2);
 
 	while (!(readl_relaxed(HDMI_PHY_PLL_STATUS0) & BIT(0)))
 		cpu_relax();
@@ -134,13 +156,15 @@
 		mb();
 	}
 
+	val = readl_relaxed(HDMI_PHY_REG_12);
+	val &= (~PWRDN_B);
+	writel_relaxed(val, HDMI_PHY_REG_12);
+
 	val = readl_relaxed(HDMI_PHY_PLL_PWRDN_B);
 	val |= PD_PLL;
+	val &= (~PLL_PWRDN_B);
 	writel_relaxed(val, HDMI_PHY_PLL_PWRDN_B);
-	mb();
-
-	val = val & (~PLL_PWRDN_B);
-	writel_relaxed(val, HDMI_PHY_PLL_PWRDN_B);
+	/* Make sure HDMI PHY/PLL are powered down */
 	mb();
 
 	if (!ahb_enabled)
@@ -156,25 +180,15 @@
 int hdmi_pll_set_rate(unsigned rate)
 {
 	unsigned int set_power_dwn = 0;
-	unsigned int val;
 	u32 ahb_en_reg = readl_relaxed(AHB_EN_REG);
 	u32 ahb_enabled = ahb_en_reg & BIT(4);
 
 	if (!ahb_enabled) {
 		writel_relaxed(ahb_en_reg | BIT(4), AHB_EN_REG);
+		/* Make sure iface clock is enabled before register access */
 		mb();
 	}
 
-	writel_relaxed(0x7f, HDMI_PHY_REG_2);
-	writel_relaxed(0x3f, HDMI_PHY_REG_2);
-	writel_relaxed(0x1f, HDMI_PHY_REG_2);
-
-	val = readl_relaxed(HDMI_PHY_REG_12);
-	val |= PWRDN_B;
-	writel_relaxed(val, HDMI_PHY_REG_12);
-	mb();
-
-	writel_relaxed(0x81, HDMI_PHY_REG_2);
 	if (hdmi_pll_on) {
 		hdmi_pll_disable();
 		set_power_dwn = 1;
@@ -198,9 +212,6 @@
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG1);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG2);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG3);
-		writel_relaxed(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
-		writel_relaxed(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
-		writel_relaxed(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
 		writel_relaxed(0x2A, HDMI_PHY_PLL_VCOCAL_CFG0);
 		writel_relaxed(0x03, HDMI_PHY_PLL_VCOCAL_CFG1);
 		writel_relaxed(0x2B, HDMI_PHY_PLL_VCOCAL_CFG2);
@@ -228,9 +239,6 @@
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG1);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG2);
 		writel_relaxed(0x20, HDMI_PHY_PLL_SSC_CFG3);
-		writel_relaxed(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
-		writel_relaxed(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
-		writel_relaxed(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
 		writel_relaxed(0xF4, HDMI_PHY_PLL_VCOCAL_CFG0);
 		writel_relaxed(0x02, HDMI_PHY_PLL_VCOCAL_CFG1);
 		writel_relaxed(0x2B, HDMI_PHY_PLL_VCOCAL_CFG2);
@@ -258,9 +266,6 @@
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG1);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG2);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG3);
-		writel_relaxed(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
-		writel_relaxed(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
-		writel_relaxed(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
 		writel_relaxed(0x2a, HDMI_PHY_PLL_VCOCAL_CFG0);
 		writel_relaxed(0x03, HDMI_PHY_PLL_VCOCAL_CFG1);
 		writel_relaxed(0x2B, HDMI_PHY_PLL_VCOCAL_CFG2);
@@ -300,9 +305,6 @@
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG1);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG2);
 		writel_relaxed(0x00, HDMI_PHY_PLL_SSC_CFG3);
-		writel_relaxed(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
-		writel_relaxed(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
-		writel_relaxed(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
 		writel_relaxed(0xe6, HDMI_PHY_PLL_VCOCAL_CFG0);
 		writel_relaxed(0x02, HDMI_PHY_PLL_VCOCAL_CFG1);
 		writel_relaxed(0x2B, HDMI_PHY_PLL_VCOCAL_CFG2);
@@ -311,10 +313,10 @@
 		writel_relaxed(0x00, HDMI_PHY_PLL_VCOCAL_CFG5);
 		writel_relaxed(0x33, HDMI_PHY_PLL_VCOCAL_CFG6);
 		writel_relaxed(0x00, HDMI_PHY_PLL_VCOCAL_CFG7);
-		writel_relaxed(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
 	break;
 	}
 
+	/* Make sure writes complete before disabling iface clock */
 	mb();
 
 	if (set_power_dwn)