Merge "msm:clock-8974: Add suspend/resume support for DSI PLL"
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 4d147c3..14e1185 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -67,7 +67,9 @@
static int pll_byte_clk_rate;
static int pll_pclk_rate;
static int pll_initialized;
+static int pll_enabled;
static struct clk *mdss_dsi_ahb_clk;
+static unsigned long dsi_pll_rate;
static void __iomem *hdmi_phy_base;
static void __iomem *hdmi_phy_pll_base;
@@ -135,6 +137,7 @@
int pll_divcfg1, pll_divcfg2;
int half_bitclk_rate;
+ pr_debug("%s:\n", __func__);
if (pll_initialized)
return 0;
@@ -193,10 +196,13 @@
REG_W(0x00, mdss_dsi_base + 0x0290); /* CAL CFG9 */
REG_W(0x20, mdss_dsi_base + 0x029c); /* EFUSE CFG */
+ dsi_pll_rate = rate;
+
pll_byte_clk_rate = 53000000;
pll_pclk_rate = 105000000;
clk_disable(mdss_dsi_ahb_clk);
+ pr_debug("%s: **** PLL initialized success\n", __func__);
pll_initialized = 1;
return 0;
@@ -206,11 +212,19 @@
{
u32 status;
u32 max_reads, timeout_us;
- static int pll_enabled;
+ int i;
if (pll_enabled)
return 0;
+ if (!pll_initialized) {
+ if (dsi_pll_rate)
+ mdss_dsi_pll_byte_set_rate(c, dsi_pll_rate);
+ else
+ pr_err("%s: Calling clk_en before set_rate\n",
+ __func__);
+ }
+
if (!mdss_dsi_ahb_clk) {
pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
__func__);
@@ -218,26 +232,39 @@
}
clk_enable(mdss_dsi_ahb_clk);
- /* PLL power up */
- REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
- REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
- udelay(20);
- REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
- udelay(20);
- REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
- /* poll for PLL ready status */
- max_reads = 20;
- timeout_us = 100;
- if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
- status,
- ((status & 0x01) == 1),
- max_reads, timeout_us)) {
+ /* PLL power up */
+ for (i = 0; i < 3; i++) {
+ REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
+ REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
+ udelay(20);
+ REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
+ udelay(20);
+ REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
+
+ /* poll for PLL ready status */
+ max_reads = 20;
+ timeout_us = 100;
+ if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
+ status,
+ ((status & 0x01) == 1),
+ max_reads, timeout_us)) {
+ pr_debug("%s: DSI PLL status=%x failed to Lock\n",
+ __func__, status);
+ pr_debug("%s:Trying to power UP PLL again\n",
+ __func__);
+ } else
+ break;
+ }
+
+ if ((status & 0x01) != 1) {
pr_err("%s: DSI PLL status=%x failed to Lock\n",
__func__, status);
clk_disable(mdss_dsi_ahb_clk);
return -EINVAL;
}
+
+ pr_debug("%s: **** PLL Lock success\n", __func__);
clk_disable(mdss_dsi_ahb_clk);
pll_enabled = 1;
@@ -253,6 +280,9 @@
clk_enable(mdss_dsi_ahb_clk);
writel_relaxed(0x00, mdss_dsi_base + 0x0220); /* GLB CFG */
clk_disable(mdss_dsi_ahb_clk);
+ pr_debug("%s: **** disable pll Initialize\n", __func__);
+ pll_initialized = 0;
+ pll_enabled = 0;
}
void hdmi_pll_disable(void)