summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-08-21 22:38:44 -0700
committerYu-Huan Hsu <yhsu@nvidia.com>2010-09-03 12:16:24 -0700
commit0e52d7fe25b11a656c376a37890be219470661fb (patch)
treeaa4411e695c2f180f935d91554b1fee1212c59a1
parenta537fc2dce58424510fc514eb499c544ae1ac96e (diff)
[ARM/tegra] power: Added non-boot PLL restoration.tegra-10.8.3
Added non-boot PLL (PLLC/PLLA/PLLD) restoration during clock resume before clock dividers are restored. (Current restoration in RM happens late after clock dividers are restored). Change-Id: I9661f5ddba0ba4b25d5a00c78820792791777429 Reviewed-on: http://git-master/r/5515 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Iqbal Bhinderwala <iqbalb@nvidia.com> Reviewed-by: Rajkumar Jayaraman <rjayaraman@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/clock_nvrm.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/clock_nvrm.c b/arch/arm/mach-tegra/clock_nvrm.c
index cc4dde9be1e6..598c001179a2 100644
--- a/arch/arm/mach-tegra/clock_nvrm.c
+++ b/arch/arm/mach-tegra/clock_nvrm.c
@@ -455,6 +455,7 @@ void __init tegra_init_clock(void)
#ifdef CONFIG_PM
#define CLK_RESET_RST_DEVICES_L 0x04
#define CLK_RESET_RST_DEVICES_NUM 3
+#define CLK_RESET_PROPAGATION_US 10
#define CLK_RESET_CLK_OUT_ENB_L 0x10
#define CLK_RESET_CLK_OUT_ENB_H 0x14
@@ -469,6 +470,17 @@ void __init tegra_init_clock(void)
#define CLK_RESET_OSC_CTRL 0x50
#define CLK_RESET_OSC_CTRL_MASK 0x3f2 /* drive strength & bypass */
+#define CLK_RESET_PLLC_BASE 0x80
+#define CLK_RESET_PLLC_MISC 0x8C
+#define CLK_RESET_PLLA_BASE 0xB0
+#define CLK_RESET_PLLA_MISC 0xBC
+#define CLK_RESET_PLLD_BASE 0xD0
+#define CLK_RESET_PLLD_MISC 0xDC
+#define CLK_RESET_NON_BOOT_PLLS_NUM 3
+#define CLK_RESET_PLL_ENABLE_MASK (0x1 << 30)
+#define CLK_RESET_PLL_STAB_US 300
+#define CLK_RESET_PLL_STAB_LONG_US 1000
+
#define CLK_RESET_CLK_SOURCE_I2S1 0x100
#define CLK_RESET_CLK_SOURCE_EMC 0x19c
#define CLK_RESET_CLK_SOURCE_OSC 0x1fc
@@ -476,6 +488,7 @@ void __init tegra_init_clock(void)
(((CLK_RESET_CLK_SOURCE_OSC - CLK_RESET_CLK_SOURCE_I2S1) / 4) + 1 - 1)
static u32 clk_rst[CLK_RESET_RST_DEVICES_NUM + CLK_RESET_CLK_OUT_ENB_NUM +
+ (CLK_RESET_NON_BOOT_PLLS_NUM * 2) +
CLK_RESET_CLK_SOURCE_NUM + 3];
void tegra_clk_suspend(void)
@@ -486,6 +499,13 @@ void tegra_clk_suspend(void)
*ctx++ = readl(car + CLK_RESET_OSC_CTRL) & CLK_RESET_OSC_CTRL_MASK;
+ *ctx++ = readl(car + CLK_RESET_PLLC_MISC);
+ *ctx++ = readl(car + CLK_RESET_PLLC_BASE);
+ *ctx++ = readl(car + CLK_RESET_PLLA_MISC);
+ *ctx++ = readl(car + CLK_RESET_PLLA_BASE);
+ *ctx++ = readl(car + CLK_RESET_PLLD_MISC);
+ *ctx++ = readl(car + CLK_RESET_PLLD_BASE);
+
for (offs=CLK_RESET_CLK_SOURCE_I2S1;
offs<=CLK_RESET_CLK_SOURCE_OSC; offs+=4) {
@@ -519,6 +539,30 @@ void tegra_clk_resume(void)
temp = readl(car + CLK_RESET_OSC_CTRL) & ~CLK_RESET_OSC_CTRL_MASK;
temp |= *ctx++;
writel(temp, car + CLK_RESET_OSC_CTRL);
+ wmb();
+
+ writel(*ctx++, car + CLK_RESET_PLLC_MISC);
+ temp = *ctx & (~CLK_RESET_PLL_ENABLE_MASK);
+ writel(temp, car + CLK_RESET_PLLC_BASE);
+ wmb();
+ writel(*ctx++, car + CLK_RESET_PLLC_BASE);
+
+ writel(*ctx++, car + CLK_RESET_PLLA_MISC);
+ temp = *ctx & (~CLK_RESET_PLL_ENABLE_MASK);
+ writel(temp, car + CLK_RESET_PLLA_BASE);
+ wmb();
+ writel(*ctx++, car + CLK_RESET_PLLA_BASE);
+
+ writel(*ctx++, car + CLK_RESET_PLLD_MISC);
+ temp = *ctx & (~CLK_RESET_PLL_ENABLE_MASK);
+ writel(temp, car + CLK_RESET_PLLD_BASE);
+ wmb();
+ temp = *ctx++;
+ if (temp & CLK_RESET_PLL_ENABLE_MASK) {
+ writel(temp, car + CLK_RESET_PLLD_BASE);
+ udelay(CLK_RESET_PLL_STAB_LONG_US);
+ } else
+ udelay(CLK_RESET_PLL_STAB_US);
writel(CLK_RESET_CLK_OUT_ENB_L_ALL, car + CLK_RESET_CLK_OUT_ENB_L);
writel(CLK_RESET_CLK_OUT_ENB_H_ALL, car + CLK_RESET_CLK_OUT_ENB_H);
@@ -532,6 +576,7 @@ void tegra_clk_resume(void)
writel(*ctx++, car + offs);
}
wmb();
+ udelay(CLK_RESET_PROPAGATION_US);
offs = CLK_RESET_RST_DEVICES_L;
for (i=0; i<CLK_RESET_RST_DEVICES_NUM; i++)