2 * linux/arch/arm/mach-pnx4008/sleep.S
4 * PNX4008 support for STOP mode and SDRAM self-refresh
6 * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <mach/hardware.h>
18 #define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
19 #define PWR_CTRL_REG_OFFS 0x44
21 #define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
22 #define MPMC_STATUS_REG_OFFS 0x4
26 ENTRY(pnx4008_cpu_suspend)
27 @this function should be entered in Direct run mode.
29 @ save registers on stack
30 stmfd sp!, {r0 - r6, lr}
32 @ setup Power Manager base address in r4
33 @ and put it's value in r5
34 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
35 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
36 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
37 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
38 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
40 @ setup SDRAM controller base address in r2
41 @ and put it's value in r3
42 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
43 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
44 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
45 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
46 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
48 @ clear SDRAM self-refresh bit latch
49 and r5, r5, #(~(1 << 8))
50 @ clear SDRAM self-refresh bit
51 and r5, r5, #(~(1 << 9))
52 str r5, [r4, #PWR_CTRL_REG_OFFS]
54 @ do save current bit settings in r1
57 @ set SDRAM self-refresh bit
59 str r5, [r4, #PWR_CTRL_REG_OFFS]
61 @ set SDRAM self-refresh bit latch
63 str r5, [r4, #PWR_CTRL_REG_OFFS]
65 @ clear SDRAM self-refresh bit latch
66 and r5, r5, #(~(1 << 8))
67 str r5, [r4, #PWR_CTRL_REG_OFFS]
69 @ clear SDRAM self-refresh bit
70 and r5, r5, #(~(1 << 9))
71 str r5, [r4, #PWR_CTRL_REG_OFFS]
73 @ wait for SDRAM to get into self-refresh mode
74 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
78 @ to prepare SDRAM to get out of self-refresh mode after wakeup
80 str r5, [r4, #PWR_CTRL_REG_OFFS]
84 str r5, [r4, #PWR_CTRL_REG_OFFS]
97 @ coming out of STOP mode into Direct Run mode
98 @ clear STOP mode and SDRAM self-refresh bits
99 str r1, [r4, #PWR_CTRL_REG_OFFS]
101 @ wait for SDRAM to get out self-refresh mode
102 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
106 @ restore regs and return
107 ldmfd sp!, {r0 - r6, pc}
109 ENTRY(pnx4008_cpu_suspend_sz)
110 .word . - pnx4008_cpu_suspend
112 ENTRY(pnx4008_cpu_standby)
113 @ save registers on stack
114 stmfd sp!, {r0 - r6, lr}
116 @ setup Power Manager base address in r4
117 @ and put it's value in r5
118 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
119 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
120 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
121 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
122 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
124 @ setup SDRAM controller base address in r2
125 @ and put it's value in r3
126 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
127 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
128 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
129 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
130 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
132 @ clear SDRAM self-refresh bit latch
133 and r5, r5, #(~(1 << 8))
134 @ clear SDRAM self-refresh bit
135 and r5, r5, #(~(1 << 9))
136 str r5, [r4, #PWR_CTRL_REG_OFFS]
138 @ do save current bit settings in r1
141 @ set SDRAM self-refresh bit
142 orr r5, r5, #(1 << 9)
143 str r5, [r4, #PWR_CTRL_REG_OFFS]
145 @ set SDRAM self-refresh bit latch
146 orr r5, r5, #(1 << 8)
147 str r5, [r4, #PWR_CTRL_REG_OFFS]
149 @ clear SDRAM self-refresh bit latch
150 and r5, r5, #(~(1 << 8))
151 str r5, [r4, #PWR_CTRL_REG_OFFS]
153 @ clear SDRAM self-refresh bit
154 and r5, r5, #(~(1 << 9))
155 str r5, [r4, #PWR_CTRL_REG_OFFS]
157 @ wait for SDRAM to get into self-refresh mode
158 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
162 @ set 'get out of self-refresh mode after wakeup' bit
163 orr r5, r5, #(1 << 7)
164 str r5, [r4, #PWR_CTRL_REG_OFFS]
166 mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
168 @ set SDRAM self-refresh bit latch
169 orr r5, r5, #(1 << 8)
170 str r5, [r4, #PWR_CTRL_REG_OFFS]
172 @ clear SDRAM self-refresh bit latch
173 and r5, r5, #(~(1 << 8))
174 str r5, [r4, #PWR_CTRL_REG_OFFS]
176 @ wait for SDRAM to get out self-refresh mode
177 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
181 @ restore regs and return
182 ldmfd sp!, {r0 - r6, pc}
184 ENTRY(pnx4008_cpu_standby_sz)
185 .word . - pnx4008_cpu_standby
187 ENTRY(pnx4008_cache_clean_invalidate)
188 stmfd sp!, {r0 - r6, lr}
189 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
190 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
192 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
195 ldmfd sp!, {r0 - r6, pc}