ARM: tegra11: clock: Add PLLC2/3, PLLC, PLLX resume operations
Alex Frid [Sat, 1 Sep 2012 03:40:02 +0000 (20:40 -0700)]
Change-Id: Idc1fc070e77ea8161a10321fe074ea329671fb98
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/130853
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

arch/arm/mach-tegra/tegra11_clocks.c

index 504dc12..aadf0a2 100644 (file)
@@ -2243,6 +2243,33 @@ static int tegra11_pllcx_clk_set_rate(struct clk *c, unsigned long rate)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static void tegra11_pllcx_clk_resume_enable(struct clk *c)
+{
+       unsigned long rate = clk_get_rate_all_locked(c->parent);
+       u32 val = clk_readl(c->reg + PLL_BASE);
+       enum clk_state state = c->state;
+
+       if (val & PLL_BASE_ENABLE)
+               return;         /* already resumed */
+
+       /* Restore input divider */
+       val &= ~PLLCX_BASE_DIVM_MASK;
+       val |= PLL_FIXED_MDIV(c, rate) << PLL_BASE_DIVM_SHIFT;
+       clk_writel(val, c->reg + PLL_BASE);
+
+       /* temporarily sync h/w and s/w states, final sync happens
+          in tegra_clk_resume later */
+       c->state = OFF;
+       pllcx_set_defaults(c, rate, c->mul);
+
+       rate = clk_get_rate_all_locked(c) + 1;
+       tegra11_pllcx_clk_set_rate(c, rate);
+       tegra11_pllcx_clk_enable(c);
+       c->state = state;
+}
+#endif
+
 static struct clk_ops tegra_pllcx_ops = {
        .init                   = tegra11_pllcx_clk_init,
        .enable                 = tegra11_pllcx_clk_enable,
@@ -2514,6 +2541,30 @@ static int tegra11_pllxc_clk_set_rate(struct clk *c, unsigned long rate)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static void tegra11_pllxc_clk_resume_enable(struct clk *c)
+{
+       unsigned long rate = clk_get_rate_all_locked(c->parent);
+       enum clk_state state = c->state;
+
+       if (clk_readl(c->reg + PLL_BASE) & PLL_BASE_ENABLE)
+               return;         /* already resumed */
+
+       /* temporarily sync h/w and s/w states, final sync happens
+          in tegra_clk_resume later */
+       c->state = OFF;
+       if (c->flags & PLLX)
+               pllx_set_defaults(c, rate);
+       else
+               pllc_set_defaults(c, rate);
+
+       rate = clk_get_rate_all_locked(c) + 1;
+       tegra11_pllxc_clk_set_rate(c, rate);
+       tegra11_pllxc_clk_enable(c);
+       c->state = state;
+}
+#endif
+
 static struct clk_ops tegra_pllxc_ops = {
        .init                   = tegra11_pllxc_clk_init,
        .enable                 = tegra11_pllxc_clk_enable,