Skip to content

Commit

Permalink
ARM: tegra: clock: Fix clock issues in suspend
Browse files Browse the repository at this point in the history
The PLLP registers are now being restored by the low-level resume code,
and the CPU may be running off PLLP, so don't touch them during clock
resume.

Save plld, plls, pllu, and audio clock during suspend (originally
fixed by Mayuresh Kulkarni <mkulkarni@nvidia.com>)

The lock time for plld is 1000 us, so increase the delay after
setting the PLLs.

Add a BUG_ON to ensure the size of the suspend context area is
correct.

Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Colin Cross <ccross@android.com>
  • Loading branch information
Colin Cross committed Feb 21, 2011
1 parent 9743b38 commit c2f44a9
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions arch/arm/mach-tegra/tegra2_clocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2236,24 +2236,26 @@ void __init tegra2_init_clocks(void)

#ifdef CONFIG_PM
static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
PERIPH_CLK_SOURCE_NUM + 19];
PERIPH_CLK_SOURCE_NUM + 22];

void tegra_clk_suspend(void)
{
unsigned long off, i;
u32 *ctx = clk_rst_suspend;

*ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
*ctx++ = clk_readl(tegra_pll_p.reg + PLL_BASE);
*ctx++ = clk_readl(tegra_pll_p.reg + PLL_MISC(&tegra_pll_p));
*ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
*ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
*ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
*ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
*ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE);
*ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
*ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
*ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
*ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE);
*ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));

*ctx++ = clk_readl(tegra_pll_m_out1.reg);
*ctx++ = clk_readl(tegra_pll_p_out1.reg);
*ctx++ = clk_readl(tegra_pll_p_out3.reg);
*ctx++ = clk_readl(tegra_pll_a_out0.reg);
*ctx++ = clk_readl(tegra_pll_c_out1.reg);

Expand All @@ -2264,6 +2266,8 @@ void tegra_clk_suspend(void)
*ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
*ctx++ = clk_readl(tegra_clk_pclk.reg);

*ctx++ = clk_readl(tegra_clk_audio.reg);

for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
off += 4) {
if (off == PERIPH_CLK_SOURCE_EMC)
Expand All @@ -2281,6 +2285,8 @@ void tegra_clk_suspend(void)

*ctx++ = clk_readl(MISC_CLK_ENB);
*ctx++ = clk_readl(CLK_MASK_ARM);

BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend));
}

void tegra_clk_resume(void)
Expand All @@ -2293,17 +2299,19 @@ void tegra_clk_resume(void)
val |= *ctx++;
clk_writel(val, OSC_CTRL);

clk_writel(*ctx++, tegra_pll_p.reg + PLL_BASE);
clk_writel(*ctx++, tegra_pll_p.reg + PLL_MISC(&tegra_pll_p));
clk_writel(*ctx++, 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);
clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
udelay(300);
clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE);
clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE);
clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE);
clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
udelay(1000);

clk_writel(*ctx++, tegra_pll_m_out1.reg);
clk_writel(*ctx++, tegra_pll_p_out1.reg);
clk_writel(*ctx++, tegra_pll_p_out3.reg);
clk_writel(*ctx++, tegra_pll_a_out0.reg);
clk_writel(*ctx++, tegra_pll_c_out1.reg);

Expand All @@ -2314,6 +2322,8 @@ void tegra_clk_resume(void)
clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
clk_writel(*ctx++, tegra_clk_pclk.reg);

clk_writel(*ctx++, tegra_clk_audio.reg);

/* enable all clocks before configuring clock sources */
clk_writel(0xbffffff9ul, CLK_OUT_ENB);
clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
Expand Down

0 comments on commit c2f44a9

Please sign in to comment.