ARM: tegra: suspend: Save and restore PLLP in low-level suspend
authorColin Cross <ccross@android.com>
Wed, 27 Oct 2010 00:32:13 +0000 (17:32 -0700)
committerColin Cross <ccross@android.com>
Wed, 27 Oct 2010 00:42:21 +0000 (17:42 -0700)
Save and restore the PLLP registers in the platform suspend code, as
the CPU clock may be sourced from the PLLP registers later, before
the clock resume that used to re-enable PLLP has been called.

Change-Id: I0ffc18d8a7f2d62c544328bd44ca7cf62848bc44
Signed-off-by: Colin Cross <ccross@android.com>
arch/arm/mach-tegra/headsmp-t2.S
arch/arm/mach-tegra/suspend.c

index e25a3597f7fcf56c5f9a9f8a5683bbb4666ce162..9da0ed68e63da3a1769fe6abd3103f3dd72d1d03 100644 (file)
 #define PMC_SCRATCH39  0x138
 #define RST_DEVICES_U  0xc
 
+#define CLK_RESET_PLLX_BASE     0xe0
+#define CLK_RESET_PLLX_MISC     0xe4
+#define CLK_RESET_PLLP_BASE     0xa0
+#define CLK_RESET_PLLP_OUTA     0xa4
+#define CLK_RESET_PLLP_OUTB     0xa8
+#define CLK_RESET_PLLP_MISC     0xac
+
 /*        .section ".cpuinit.text", "ax"*/
 
 .macro poke_ev, val, tmp
@@ -66,26 +73,38 @@ ENDPROC(tegra_secondary_startup)
 #endif
 
 /*
- *     __restart_pllx
+ *     __restart_plls
  *
- *       Loads the saved PLLX parameters from tegra_sctx into PLLX, to
- *       allow it to stabilize while the rest of the CPU state is restored.
+ *       Loads the saved PLLX and PLLP parameters into the PLLs, to
+ *       allow them to stabilize while the rest of the CPU state is restored.
  *       Should be called after the MMU is enabled. Jumps directly
  *       to __cortex_a9_restore
  */
        .align L1_CACHE_SHIFT
-__restart_pllx:
+__restart_plls:
        mov32   r0, tegra_sctx
-       ldr     r1, [r0, #0x8]  @ pllx_base
-       ldr     r2, [r0, #0xC]  @ pllx_misc
        mov32   r3, (TEGRA_CLK_RESET_BASE-IO_PPSB_PHYS+IO_PPSB_VIRT)
        mov32   r4, (TEGRA_TMRUS_BASE-IO_PPSB_PHYS+IO_PPSB_VIRT)
-       str     r2, [r3, #0xe4] @ pllx_misc
-       str     r1, [r3, #0xe0] @ pllx_base
-       /* record the time that PLLX will be stable */
+
+       ldr     r1, [r0, #0x0]  @ pllx_misc
+       ldr     r2, [r0, #0x4]  @ pllx_base
+       str     r1, [r3, #CLK_RESET_PLLX_MISC]
+       str     r2, [r3, #CLK_RESET_PLLX_BASE]
+
+       ldr     r1, [r0, #0x8]  @ pllp_misc
+       ldr     r2, [r0, #0xc]  @ pllp_base
+       str     r1, [r3, #CLK_RESET_PLLP_MISC]
+       str     r2, [r3, #CLK_RESET_PLLP_BASE]
+
+       ldr     r1, [r0, #0x10] @ pllp_outa
+       ldr     r2, [r0, #0x14] @ pllp_outb
+       str     r1, [r3, #CLK_RESET_PLLP_OUTA]
+       str     r2, [r3, #CLK_RESET_PLLP_OUTB]
+
+       /* record the time that PLLX and PLLP will be stable */
        ldr     r1, [r4]
        add     r1, r1, #300
-       str     r1, [r0, #0x10]
+       str     r1, [r0, #0x18] @ pll_timeout
        /* FIXME: need to record actual power transition here */
        mov     r0, #0
        b       __cortex_a9_l2x0_restart
@@ -156,7 +175,7 @@ ENDPROC(tegra_lp2_startup)
 __tegra_lp2_data:
        .long   .
        .long   tegra_pgd_phys
-       .long   __restart_pllx
+       .long   __restart_plls
        .size   __tegra_lp2_data, . - __tegra_lp2_data
 
 #ifdef CONFIG_HOTPLUG_CPU
index 06bafa1c45c637b7f44cc2d8c4194f330bff639a..aef50319852c5a7d1a82cb7a20e15c0aa604a5a4 100644 (file)
 #include "board.h"
 #include "power.h"
 
-/* NOTE: only add elements to the end of this structure, since the assembly
- * code uses hard-coded offsets */
-struct suspend_context
-{
+struct suspend_context {
+       /*
+        * The next 7 values are referenced by offset in __restart_plls
+        * in headsmp-t2.S, and should not be moved
+        */
+       u32 pllx_misc;
+       u32 pllx_base;
+       u32 pllp_misc;
+       u32 pllp_base;
+       u32 pllp_outa;
+       u32 pllp_outb;
+       u32 pll_timeout;
+
        u32 cpu_burst;
        u32 clk_csite_src;
-       u32 pllx_base;
-       u32 pllx_misc;
-       u32 pllx_timeout;
        u32 twd_ctrl;
        u32 twd_load;
        u32 cclk_divider;
@@ -101,6 +107,11 @@ static void __iomem *tmrus = IO_ADDRESS(TEGRA_TMRUS_BASE);
 #define CLK_RESET_PLLM_BASE    0x90
 #define CLK_RESET_PLLX_BASE    0xe0
 #define CLK_RESET_PLLX_MISC    0xe4
+#define CLK_RESET_PLLP_BASE    0xa0
+#define CLK_RESET_PLLP_OUTA    0xa4
+#define CLK_RESET_PLLP_OUTB    0xa8
+#define CLK_RESET_PLLP_MISC    0xac
+
 #define CLK_RESET_SOURCE_CSITE 0x1d4
 
 
@@ -256,7 +267,7 @@ static noinline void restore_cpu_complex(void)
        BUG_ON(readl(clk_rst + CLK_RESET_PLLX_BASE) != tegra_sctx.pllx_base);
 
        if (tegra_sctx.pllx_base & (1<<30)) {
-               while (readl(tmrus)-tegra_sctx.pllx_timeout >= 0x80000000UL)
+               while (readl(tmrus)-tegra_sctx.pll_timeout >= 0x80000000UL)
                        cpu_relax();
        }
        writel(tegra_sctx.cclk_divider, clk_rst + CLK_RESET_CCLK_DIVIDER);
@@ -295,6 +306,10 @@ static noinline void suspend_cpu_complex(void)
        tegra_sctx.cpu_burst = readl(clk_rst + CLK_RESET_CCLK_BURST);
        tegra_sctx.pllx_base = readl(clk_rst + CLK_RESET_PLLX_BASE);
        tegra_sctx.pllx_misc = readl(clk_rst + CLK_RESET_PLLX_MISC);
+       tegra_sctx.pllp_base = readl(clk_rst + CLK_RESET_PLLP_BASE);
+       tegra_sctx.pllp_outa = readl(clk_rst + CLK_RESET_PLLP_OUTA);
+       tegra_sctx.pllp_outb = readl(clk_rst + CLK_RESET_PLLP_OUTB);
+       tegra_sctx.pllp_misc = readl(clk_rst + CLK_RESET_PLLP_MISC);
        tegra_sctx.cclk_divider = readl(clk_rst + CLK_RESET_CCLK_DIVIDER);
 
 #ifdef CONFIG_HAVE_ARM_TWD