From: Colin Cross Date: Wed, 27 Oct 2010 00:32:13 +0000 (-0700) Subject: ARM: tegra: suspend: Save and restore PLLP in low-level suspend X-Git-Tag: firefly_0821_release~9833^2~140^2~5 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ff7dc25c7f8644c8db0677d73b350640b5111c21;p=firefly-linux-kernel-4.4.55.git ARM: tegra: suspend: Save and restore PLLP in low-level suspend 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 --- 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