Commit aee240e7 authored by Tony Lindgren's avatar Tony Lindgren

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: default avatarTony Lindgren <tony@atomide.com>
parent 3568f5b4
...@@ -22,8 +22,7 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o ...@@ -22,8 +22,7 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
ifeq ($(CONFIG_PM),y) ifeq ($(CONFIG_PM),y)
obj-y += pm.o obj-y += pm.o
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o
obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o
endif endif
......
...@@ -56,7 +56,8 @@ ...@@ -56,7 +56,8 @@
#include <mach/clockdomain.h> #include <mach/clockdomain.h>
static void (*omap2_sram_idle)(void); 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 void (*saved_idle)(void);
static struct powerdomain *mpu_pwrdm; static struct powerdomain *mpu_pwrdm;
...@@ -121,7 +122,9 @@ static void omap2_enter_full_retention(void) ...@@ -121,7 +122,9 @@ static void omap2_enter_full_retention(void)
serial_console_sleep(1); serial_console_sleep(1);
/* Jump to SRAM suspend code */ /* 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: no_sleep:
serial_console_sleep(0); serial_console_sleep(0);
...@@ -534,18 +537,12 @@ int __init omap2_pm_init(void) ...@@ -534,18 +537,12 @@ int __init omap2_pm_init(void)
* These routines need to be in SRAM as that's the only * These routines need to be in SRAM as that's the only
* memory the MPU can see when it wakes up. * memory the MPU can see when it wakes up.
*/ */
if (cpu_is_omap242x()) { if (cpu_is_omap24xx()) {
omap2_sram_idle = omap_sram_push(omap242x_idle_loop_suspend, omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
omap242x_idle_loop_suspend_sz); omap24xx_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);
omap2_sram_suspend = omap_sram_push(omap243x_cpu_suspend, omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
omap243x_cpu_suspend_sz); omap24xx_cpu_suspend_sz);
} }
suspend_set_ops(&omap_pm_ops); suspend_set_ops(&omap_pm_ops);
......
/*
* linux/arch/arm/mach-omap2/sleep.S
*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* (C) Copyright 2006 Nokia Corporation
* Fixed idle loop sleep
* Igor Stoppa <igor.stoppa@nokia.com>
*
* 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 <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/io.h>
#include <mach/pm.h>
#include <mach/omap24xx.h>
#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
...@@ -42,28 +42,30 @@ ...@@ -42,28 +42,30 @@
/* /*
* Forces OMAP into idle state * 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. * for normal idles.
* *
* Note: This code get's copied to internal SRAM at boot. When the OMAP * 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. * 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 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 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
ldmfd sp!, {r0, pc} @ restore regs and return ldmfd sp!, {r0, pc} @ restore regs and return
ENTRY(omap242x_idle_loop_suspend_sz) ENTRY(omap24xx_idle_loop_suspend_sz)
.word . - omap242x_idle_loop_suspend .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 shutdown then ARM shutdown. Upon wake MPU is back on so just restore
* SDRC. * SDRC.
* *
* Input: * Input:
* R0 : DLL ctrl value pre-Sleep * 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 * 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 * 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) ...@@ -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 * The DLL load value is not kept in RETENTION or OFF. It needs to be restored
* at wake * at wake
*/ */
ENTRY(omap242x_cpu_suspend) ENTRY(omap24xx_cpu_suspend)
stmfd sp!, {r0 - r12, lr} @ save registers on stack 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 mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished
nop nop
nop nop
ldr r3, omap2_ocs_sdrc_power @ addr of sdrc power ldr r4, [r2] @ read SDRC_POWER
ldr r4, [r3] @ value of sdrc power
orr r4, r4, #0x40 @ enable self refresh on idle req orr r4, r4, #0x40 @ enable self refresh on idle req
mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) mov r5, #0x2000 @ set delay (DPLL relock + DLL relock)
str r4, [r3] @ make it so str r4, [r2] @ make it so
mov r2, #0 mov r2, #0
nop nop
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
...@@ -100,14 +101,13 @@ loop: ...@@ -100,14 +101,13 @@ loop:
subs r5, r5, #0x1 @ awake, wait just a bit subs r5, r5, #0x1 @ awake, wait just a bit
bne loop 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. 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, A_SDRC0 @ make a clock happen
ldr r4, [r4] ldr r4, [r4] @ read A_SDRC0
nop @ start auto refresh only after clk ok nop @ start auto refresh only after clk ok
movs r0, r0 @ see if DDR or SDR 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 strne r0, [r1] @ rewrite DLLA to force DLL reload
addne r1, r1, #0x8 @ move to DLLB addne r1, r1, #0x8 @ move to DLLB
strne r0, [r1] @ rewrite DLLB to force DLL reload strne r0, [r1] @ rewrite DLLB to force DLL reload
...@@ -119,13 +119,8 @@ loop2: ...@@ -119,13 +119,8 @@ loop2:
/* resume*/ /* resume*/
ldmfd sp!, {r0 - r12, pc} @ restore regs and return ldmfd sp!, {r0 - r12, pc} @ restore regs and return
omap2_ocs_sdrc_power:
.word OMAP242X_SDRC_REGADDR(SDRC_POWER)
A_SDRC0: A_SDRC0:
.word A_SDRC0_V .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
/* /*
* linux/include/mach-omap/pm.h * arch/arm/plat-omap/include/mach/pm.h
* *
* Header file for OMAP Power Management Routines * Header file for OMAP Power Management Routines
* *
...@@ -145,26 +145,23 @@ static inline void omap2_allow_sleep(void) { } ...@@ -145,26 +145,23 @@ static inline void omap2_allow_sleep(void) { }
extern void omap730_cpu_suspend(unsigned short, unsigned short); extern void omap730_cpu_suspend(unsigned short, unsigned short);
extern void omap1510_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 omap1610_cpu_suspend(unsigned short, unsigned short);
extern void omap242x_cpu_suspend(u32 dll_ctrl, u32 cpu_revision); extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
extern void omap243x_cpu_suspend(u32 dll_ctrl, u32 cpu_revision); void __iomem *sdrc_power);
extern void omap34xx_cpu_suspend(u32 *addr, int save_state); extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
extern void omap730_idle_loop_suspend(void); extern void omap730_idle_loop_suspend(void);
extern void omap1510_idle_loop_suspend(void); extern void omap1510_idle_loop_suspend(void);
extern void omap1610_idle_loop_suspend(void); extern void omap1610_idle_loop_suspend(void);
extern void omap242x_idle_loop_suspend(void); extern void omap24xx_idle_loop_suspend(void);
extern void omap243x_idle_loop_suspend(void);
extern unsigned int omap730_cpu_suspend_sz; extern unsigned int omap730_cpu_suspend_sz;
extern unsigned int omap1510_cpu_suspend_sz; extern unsigned int omap1510_cpu_suspend_sz;
extern unsigned int omap1610_cpu_suspend_sz; extern unsigned int omap1610_cpu_suspend_sz;
extern unsigned int omap242x_cpu_suspend_sz; extern unsigned int omap24xx_cpu_suspend_sz;
extern unsigned int omap243x_cpu_suspend_sz;
extern unsigned int omap34xx_cpu_suspend_sz; extern unsigned int omap34xx_cpu_suspend_sz;
extern unsigned int omap730_idle_loop_suspend_sz; extern unsigned int omap730_idle_loop_suspend_sz;
extern unsigned int omap1510_idle_loop_suspend_sz; extern unsigned int omap1510_idle_loop_suspend_sz;
extern unsigned int omap1610_idle_loop_suspend_sz; extern unsigned int omap1610_idle_loop_suspend_sz;
extern unsigned int omap242x_idle_loop_suspend_sz; extern unsigned int omap24xx_idle_loop_suspend_sz;
extern unsigned int omap243x_idle_loop_suspend_sz;
extern unsigned int omap34xx_suspend_sz; extern unsigned int omap34xx_suspend_sz;
#ifdef CONFIG_OMAP_SERIAL_WAKE #ifdef CONFIG_OMAP_SERIAL_WAKE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment