From aee240e7a8d8dbd92e7e548b3f8f85c361394273 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sat, 23 Aug 2008 15:17:21 -0700 Subject: [PATCH] ARM: OMAP: Combine sleep242x.S and sleep243x.S and fix error for SDR We can pass the addresses for SDRC_DDLA_CTRL and SDRC_POWER to the omap24xx_cpu_suspend instead of loading the values since the only difference between 242x and 243x is the address of these registers. Also call omap2_sram_suspend with the value of SDRC_DLLA_CTRL instead of the address as that's what omap24xx_cpu_suspend expects to determine between DDR and SDR. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/pm24xx.c | 23 ++- arch/arm/mach-omap2/sleep243x.S | 131 ------------------ .../mach-omap2/{sleep242x.S => sleep24xx.S} | 39 +++--- arch/arm/plat-omap/include/mach/pm.h | 15 +- 5 files changed, 34 insertions(+), 177 deletions(-) delete mode 100644 arch/arm/mach-omap2/sleep243x.S rename arch/arm/mach-omap2/{sleep242x.S => sleep24xx.S} (80%) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 0e982d3dfdb..d89b7cbb097 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -22,8 +22,7 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o ifeq ($(CONFIG_PM),y) obj-y += pm.o obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o -obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o -obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o +obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o endif diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 5c7612069d3..60ff04f3f4c 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -56,7 +56,8 @@ #include static void (*omap2_sram_idle)(void); -static void (*omap2_sram_suspend)(void __iomem *dllctrl); +static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, + void __iomem *sdrc_power); static void (*saved_idle)(void); static struct powerdomain *mpu_pwrdm; @@ -121,7 +122,9 @@ static void omap2_enter_full_retention(void) serial_console_sleep(1); /* Jump to SRAM suspend code */ - omap2_sram_suspend(OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL)); + omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), + OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), + OMAP_SDRC_REGADDR(SDRC_POWER)); no_sleep: serial_console_sleep(0); @@ -534,18 +537,12 @@ int __init omap2_pm_init(void) * These routines need to be in SRAM as that's the only * memory the MPU can see when it wakes up. */ - if (cpu_is_omap242x()) { - omap2_sram_idle = omap_sram_push(omap242x_idle_loop_suspend, - omap242x_idle_loop_suspend_sz); - - omap2_sram_suspend = omap_sram_push(omap242x_cpu_suspend, - omap242x_cpu_suspend_sz); - } else { - omap2_sram_idle = omap_sram_push(omap243x_idle_loop_suspend, - omap243x_idle_loop_suspend_sz); + if (cpu_is_omap24xx()) { + omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, + omap24xx_idle_loop_suspend_sz); - omap2_sram_suspend = omap_sram_push(omap243x_cpu_suspend, - omap243x_cpu_suspend_sz); + omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, + omap24xx_cpu_suspend_sz); } suspend_set_ops(&omap_pm_ops); diff --git a/arch/arm/mach-omap2/sleep243x.S b/arch/arm/mach-omap2/sleep243x.S deleted file mode 100644 index e39ab556177..00000000000 --- a/arch/arm/mach-omap2/sleep243x.S +++ /dev/null @@ -1,131 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/sleep.S - * - * (C) Copyright 2004 - * Texas Instruments, - * Richard Woodruff - * - * (C) Copyright 2006 Nokia Corporation - * Fixed idle loop sleep - * Igor Stoppa - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include - -#include "sdrc.h" - -/* First address of reserved address space? apparently valid for OMAP2 & 3 */ -#define A_SDRC0_V (0xC0000000) - - .text - -/* - * Forces OMAP into idle state - * - * omap243x_idle_loop_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - */ -ENTRY(omap243x_idle_loop_suspend) - stmfd sp!, {r0, lr} @ save registers on stack - mov r0, #0x0 @ clear for mrc call - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt - ldmfd sp!, {r0, pc} @ restore regs and return - -ENTRY(omap243x_idle_loop_suspend_sz) - .word . - omap243x_idle_loop_suspend - -/* - * omap243x_cpu_suspend() - Forces OMAP into deep sleep state by completing - * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore - * SDRC. - * - * Input: - * R0 : DLL ctrl value pre-Sleep - * - * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on - * when we get called, but the DLL probably isn't. We will wait a bit more in - * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even - * if in unlocked mode. - * - * For less than 242x-ES2.2 upon wake from a sleep mode where the external - * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz - * clock can pass into the PRCM can cause problems at DSP and IVA. - * To work around this the code will switch to the 32kHz source prior to sleep. - * Post sleep we will shift back to using the DPLL. Apparently, - * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait - * 3x12MHz + 3x32kHz clocks for a full switch. - * - * The DLL load value is not kept in RETENTION or OFF. It needs to be restored - * at wake - */ -ENTRY(omap243x_cpu_suspend) - stmfd sp!, {r0 - r12, lr} @ save registers on stack - mov r3, #0x0 @ clear for mrc call - mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished - nop - nop - ldr r3, omap2_ocs_sdrc_power @ addr of sdrc power - ldr r4, [r3] @ value of sdrc power - orr r4, r4, #0x40 @ enable self refresh on idle req - mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) - str r4, [r3] @ make it so - mov r2, #0 - nop - mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt - nop -loop: - subs r5, r5, #0x1 @ awake, wait just a bit - bne loop - - /* The DPLL has on before we take the DDR out of self refresh */ - bic r4, r4, #0x40 @ now clear self refresh bit. - str r4, [r3] @ put vlaue back. - ldr r4, A_SDRC0 @ make a clock happen - ldr r4, [r4] - nop @ start auto refresh only after clk ok - movs r0, r0 @ see if DDR or SDR - ldrne r1, omap2_ocs_sdrc_dlla_ctrl @ get addr of DLL ctrl - strne r0, [r1] @ rewrite DLLA to force DLL reload - addne r1, r1, #0x8 @ move to DLLB - strne r0, [r1] @ rewrite DLLB to force DLL reload - - mov r5, #0x1000 -loop2: - subs r5, r5, #0x1 - bne loop2 - /* resume*/ - ldmfd sp!, {r0 - r12, pc} @ restore regs and return - -omap2_ocs_sdrc_power: - .word OMAP243X_SDRC_REGADDR(SDRC_POWER) -A_SDRC0: - .word A_SDRC0_V -omap2_ocs_sdrc_dlla_ctrl: - .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) - -ENTRY(omap243x_cpu_suspend_sz) - .word . - omap243x_cpu_suspend - diff --git a/arch/arm/mach-omap2/sleep242x.S b/arch/arm/mach-omap2/sleep24xx.S similarity index 80% rename from arch/arm/mach-omap2/sleep242x.S rename to arch/arm/mach-omap2/sleep24xx.S index 5e38ab7822b..43336b93b21 100644 --- a/arch/arm/mach-omap2/sleep242x.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -42,28 +42,30 @@ /* * Forces OMAP into idle state * - * omap242x_idle_loop_suspend() - This bit of code just executes the WFI + * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI * for normal idles. * * Note: This code get's copied to internal SRAM at boot. When the OMAP * wakes up it continues execution at the point it went to sleep. */ -ENTRY(omap242x_idle_loop_suspend) +ENTRY(omap24xx_idle_loop_suspend) stmfd sp!, {r0, lr} @ save registers on stack - mov r0, #0x0 @ clear for mrc call + mov r0, #0 @ clear for mcr setup mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt ldmfd sp!, {r0, pc} @ restore regs and return -ENTRY(omap242x_idle_loop_suspend_sz) - .word . - omap242x_idle_loop_suspend +ENTRY(omap24xx_idle_loop_suspend_sz) + .word . - omap24xx_idle_loop_suspend /* - * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing + * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore * SDRC. * * Input: * R0 : DLL ctrl value pre-Sleep + * R1 : SDRC_DLLA_CTRL + * R2 : SDRC_POWER * * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on * when we get called, but the DLL probably isn't. We will wait a bit more in @@ -81,17 +83,16 @@ ENTRY(omap242x_idle_loop_suspend_sz) * The DLL load value is not kept in RETENTION or OFF. It needs to be restored * at wake */ -ENTRY(omap242x_cpu_suspend) +ENTRY(omap24xx_cpu_suspend) stmfd sp!, {r0 - r12, lr} @ save registers on stack - mov r3, #0x0 @ clear for mrc call + mov r3, #0x0 @ clear for mcr call mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished nop nop - ldr r3, omap2_ocs_sdrc_power @ addr of sdrc power - ldr r4, [r3] @ value of sdrc power + ldr r4, [r2] @ read SDRC_POWER orr r4, r4, #0x40 @ enable self refresh on idle req mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) - str r4, [r3] @ make it so + str r4, [r2] @ make it so mov r2, #0 nop mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt @@ -100,14 +101,13 @@ loop: subs r5, r5, #0x1 @ awake, wait just a bit bne loop - /* The DPLL has on before we take the DDR out of self refresh */ + /* The DPLL has to be on before we take the DDR out of self refresh */ bic r4, r4, #0x40 @ now clear self refresh bit. - str r4, [r3] @ put vlaue back. + str r4, [r2] @ write to SDRC_POWER ldr r4, A_SDRC0 @ make a clock happen - ldr r4, [r4] + ldr r4, [r4] @ read A_SDRC0 nop @ start auto refresh only after clk ok movs r0, r0 @ see if DDR or SDR - ldrne r1, omap2_ocs_sdrc_dlla_ctrl @ get addr of DLL ctrl strne r0, [r1] @ rewrite DLLA to force DLL reload addne r1, r1, #0x8 @ move to DLLB strne r0, [r1] @ rewrite DLLB to force DLL reload @@ -119,13 +119,8 @@ loop2: /* resume*/ ldmfd sp!, {r0 - r12, pc} @ restore regs and return -omap2_ocs_sdrc_power: - .word OMAP242X_SDRC_REGADDR(SDRC_POWER) A_SDRC0: .word A_SDRC0_V -omap2_ocs_sdrc_dlla_ctrl: - .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) - -ENTRY(omap242x_cpu_suspend_sz) - .word . - omap242x_cpu_suspend +ENTRY(omap24xx_cpu_suspend_sz) + .word . - omap24xx_cpu_suspend diff --git a/arch/arm/plat-omap/include/mach/pm.h b/arch/arm/plat-omap/include/mach/pm.h index 713bcc9e143..5a1f3db6e69 100644 --- a/arch/arm/plat-omap/include/mach/pm.h +++ b/arch/arm/plat-omap/include/mach/pm.h @@ -1,5 +1,5 @@ /* - * linux/include/mach-omap/pm.h + * arch/arm/plat-omap/include/mach/pm.h * * Header file for OMAP Power Management Routines * @@ -145,26 +145,23 @@ static inline void omap2_allow_sleep(void) { } extern void omap730_cpu_suspend(unsigned short, unsigned short); extern void omap1510_cpu_suspend(unsigned short, unsigned short); extern void omap1610_cpu_suspend(unsigned short, unsigned short); -extern void omap242x_cpu_suspend(u32 dll_ctrl, u32 cpu_revision); -extern void omap243x_cpu_suspend(u32 dll_ctrl, u32 cpu_revision); +extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, + void __iomem *sdrc_power); extern void omap34xx_cpu_suspend(u32 *addr, int save_state); extern void omap730_idle_loop_suspend(void); extern void omap1510_idle_loop_suspend(void); extern void omap1610_idle_loop_suspend(void); -extern void omap242x_idle_loop_suspend(void); -extern void omap243x_idle_loop_suspend(void); +extern void omap24xx_idle_loop_suspend(void); extern unsigned int omap730_cpu_suspend_sz; extern unsigned int omap1510_cpu_suspend_sz; extern unsigned int omap1610_cpu_suspend_sz; -extern unsigned int omap242x_cpu_suspend_sz; -extern unsigned int omap243x_cpu_suspend_sz; +extern unsigned int omap24xx_cpu_suspend_sz; extern unsigned int omap34xx_cpu_suspend_sz; extern unsigned int omap730_idle_loop_suspend_sz; extern unsigned int omap1510_idle_loop_suspend_sz; extern unsigned int omap1610_idle_loop_suspend_sz; -extern unsigned int omap242x_idle_loop_suspend_sz; -extern unsigned int omap243x_idle_loop_suspend_sz; +extern unsigned int omap24xx_idle_loop_suspend_sz; extern unsigned int omap34xx_suspend_sz; #ifdef CONFIG_OMAP_SERIAL_WAKE -- 2.41.0