arm: tegra: clock: clock fix for lp0
Luke Huang [Sat, 25 Jun 2011 03:13:09 +0000 (20:13 -0700)]
Since clock is required when resetting devices, always enable pllc and plla at
the beginning of clock restore routine. The actual value will be restored back
after reset.

Original-Change-Id: Ic141ddb8cde5958d4e0f8b1154b8204a68c0ca50
Reviewed-on: http://git-master/r/38388
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: R254cf377d4cde1863f560867fafc10b4f37a87c9

arch/arm/mach-tegra/tegra3_clocks.c

index 13c7140..062af82 100644 (file)
@@ -4185,6 +4185,8 @@ void tegra_clk_resume(void)
        unsigned long off;
        const u32 *ctx = clk_rst_suspend;
        u32 val;
+       u32 pllc_base;
+       u32 plla_base;
 
        val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
        val |= *ctx++;
@@ -4192,9 +4194,15 @@ void tegra_clk_resume(void)
        clk_writel(*ctx++, CPU_SOFTRST_CTRL);
 
        /* FIXME: add plld, and wait for lock */
-       clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
+       /* Since we are going to reset devices in this function, pllc/a is
+        * required to be enabled. The actual value will be restore back later.
+        */
+       pllc_base = *ctx++;
+       clk_writel(pllc_base | PLL_BASE_ENABLE, tegra_pll_c.reg + PLL_BASE);
        clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
-       clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
+
+       plla_base = *ctx++;
+       clk_writel(plla_base | PLL_BASE_ENABLE, tegra_pll_a.reg + PLL_BASE);
        clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
        udelay(300);
 
@@ -4258,6 +4266,10 @@ void tegra_clk_resume(void)
        clk_writel(*ctx++, MISC_CLK_ENB);
        clk_writel(*ctx++, CLK_MASK_ARM);
 
+       /* Restore back the actual pllc/a value */
+       clk_writel(pllc_base, tegra_pll_c.reg + PLL_BASE);
+       clk_writel(plla_base, tegra_pll_a.reg + PLL_BASE);
+
        /* Since EMC clock is not restored update current state, and mark
           EMC DFS as out of sync */
        tegra3_periph_clk_init(&tegra_clk_emc);