msm: clock-pll: SR2 Pll enable function for 8226
The SR2 plls in 8226 have a bit which indicates they have finished
changing frequencies. Poll this bit to verify PLL 'lock' before
returning.
Change-Id: Ifb1b8a0b920a0e6055a4eb6355bb67645e7e9f8e
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index 8e11d37..cd4ead1 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -54,6 +54,7 @@
static DEFINE_SPINLOCK(pll_reg_lock);
#define ENABLE_WAIT_MAX_LOOPS 200
+#define PLL_LOCKED_BIT BIT(16)
static int pll_vote_clk_enable(struct clk *c)
{
@@ -148,6 +149,51 @@
writel_relaxed(regval, pll_config);
}
+static int sr2_pll_clk_enable(struct clk *c)
+{
+ unsigned long flags;
+ struct pll_clk *pll = to_pll_clk(c);
+ int ret = 0, count;
+ u32 mode = readl_relaxed(PLL_MODE_REG(pll));
+
+ spin_lock_irqsave(&pll_reg_lock, flags);
+
+ /* Disable PLL bypass mode. */
+ mode |= PLL_BYPASSNL;
+ writel_relaxed(mode, PLL_MODE_REG(pll));
+
+ /*
+ * H/W requires a 5us delay between disabling the bypass and
+ * de-asserting the reset. Delay 10us just to be safe.
+ */
+ mb();
+ udelay(10);
+
+ /* De-assert active-low PLL reset. */
+ mode |= PLL_RESET_N;
+ writel_relaxed(mode, PLL_MODE_REG(pll));
+
+ /* Wait for pll to lock. */
+ for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
+ if (readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)
+ break;
+ udelay(1);
+ }
+
+ if (!(readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT))
+ pr_err("PLL %s didn't lock after enabling it!\n", c->dbg_name);
+
+ /* Enable PLL output. */
+ mode |= PLL_OUTCTRL;
+ writel_relaxed(mode, PLL_MODE_REG(pll));
+
+ /* Ensure that the write above goes through before returning. */
+ mb();
+
+ spin_unlock_irqrestore(&pll_reg_lock, flags);
+ return ret;
+}
+
static void __pll_clk_enable_reg(void __iomem *mode_reg)
{
u32 mode = readl_relaxed(mode_reg);
@@ -290,8 +336,6 @@
return 0;
}
-#define PLL_LOCKED_BIT BIT(16)
-
int sr_hpm_lp_pll_clk_enable(struct clk *c)
{
unsigned long flags;
@@ -337,6 +381,13 @@
.handoff = local_pll_clk_handoff,
};
+struct clk_ops clk_ops_sr2_pll = {
+ .enable = sr2_pll_clk_enable,
+ .disable = local_pll_clk_disable,
+ .set_rate = local_pll_clk_set_rate,
+ .handoff = local_pll_clk_handoff,
+};
+
struct pll_rate {
unsigned int lvalue;
unsigned long rate;