diff --git a/arch/arm/mach-tegra/headsmp-t2.S b/arch/arm/mach-tegra/headsmp-t2.S index e25a3597f7fc..9da0ed68e63d 100644 --- a/arch/arm/mach-tegra/headsmp-t2.S +++ b/arch/arm/mach-tegra/headsmp-t2.S @@ -41,6 +41,13 @@ #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 diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c index 06bafa1c45c6..aef50319852c 100644 --- a/arch/arm/mach-tegra/suspend.c +++ b/arch/arm/mach-tegra/suspend.c @@ -53,15 +53,21 @@ #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