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/config.h>
15 #include <linux/linkage.h>
16 #include <asm/assembler.h>
17 #include <asm/hardware.h>
19 #define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
20 #define PWR_CTRL_REG_OFFS 0x44
22 #define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
23 #define MPMC_STATUS_REG_OFFS 0x4
27 ENTRY(pnx4008_cpu_suspend)
28 @this function should be entered in Direct run mode.
30 @ save registers on stack
31 stmfd sp!, {r0 - r6, lr}
33 @ setup Power Manager base address in r4
34 @ and put it's value in r5
35 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
36 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
37 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
38 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
39 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
41 @ setup SDRAM controller base address in r2
42 @ and put it's value in r3
43 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
44 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
45 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
46 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
47 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
49 @ clear SDRAM self-refresh bit latch
50 and r5, r5, #(~(1 << 8))
51 @ clear SDRAM self-refresh bit
52 and r5, r5, #(~(1 << 9))
53 str r5, [r4, #PWR_CTRL_REG_OFFS]
55 @ do save current bit settings in r1
58 @ set SDRAM self-refresh bit
60 str r5, [r4, #PWR_CTRL_REG_OFFS]
62 @ set SDRAM self-refresh bit latch
64 str r5, [r4, #PWR_CTRL_REG_OFFS]
66 @ clear SDRAM self-refresh bit latch
67 and r5, r5, #(~(1 << 8))
68 str r5, [r4, #PWR_CTRL_REG_OFFS]
70 @ clear SDRAM self-refresh bit
71 and r5, r5, #(~(1 << 9))
72 str r5, [r4, #PWR_CTRL_REG_OFFS]
74 @ wait for SDRAM to get into self-refresh mode
75 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
79 @ to prepare SDRAM to get out of self-refresh mode after wakeup
81 str r5, [r4, #PWR_CTRL_REG_OFFS]
85 str r5, [r4, #PWR_CTRL_REG_OFFS]
98 @ coming out of STOP mode into Direct Run mode
99 @ clear STOP mode and SDRAM self-refresh bits
100 str r1, [r4, #PWR_CTRL_REG_OFFS]
102 @ wait for SDRAM to get out self-refresh mode
103 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
107 @ restore regs and return
108 ldmfd sp!, {r0 - r6, pc}
110 ENTRY(pnx4008_cpu_suspend_sz)
111 .word . - pnx4008_cpu_suspend
113 ENTRY(pnx4008_cpu_standby)
114 @ save registers on stack
115 stmfd sp!, {r0 - r6, lr}
117 @ setup Power Manager base address in r4
118 @ and put it's value in r5
119 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
120 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
121 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
122 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
123 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
125 @ setup SDRAM controller base address in r2
126 @ and put it's value in r3
127 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
128 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
129 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
130 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
131 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
133 @ clear SDRAM self-refresh bit latch
134 and r5, r5, #(~(1 << 8))
135 @ clear SDRAM self-refresh bit
136 and r5, r5, #(~(1 << 9))
137 str r5, [r4, #PWR_CTRL_REG_OFFS]
139 @ do save current bit settings in r1
142 @ set SDRAM self-refresh bit
143 orr r5, r5, #(1 << 9)
144 str r5, [r4, #PWR_CTRL_REG_OFFS]
146 @ set SDRAM self-refresh bit latch
147 orr r5, r5, #(1 << 8)
148 str r5, [r4, #PWR_CTRL_REG_OFFS]
150 @ clear SDRAM self-refresh bit latch
151 and r5, r5, #(~(1 << 8))
152 str r5, [r4, #PWR_CTRL_REG_OFFS]
154 @ clear SDRAM self-refresh bit
155 and r5, r5, #(~(1 << 9))
156 str r5, [r4, #PWR_CTRL_REG_OFFS]
158 @ wait for SDRAM to get into self-refresh mode
159 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
163 @ set 'get out of self-refresh mode after wakeup' bit
164 orr r5, r5, #(1 << 7)
165 str r5, [r4, #PWR_CTRL_REG_OFFS]
167 mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
169 @ set SDRAM self-refresh bit latch
170 orr r5, r5, #(1 << 8)
171 str r5, [r4, #PWR_CTRL_REG_OFFS]
173 @ clear SDRAM self-refresh bit latch
174 and r5, r5, #(~(1 << 8))
175 str r5, [r4, #PWR_CTRL_REG_OFFS]
177 @ wait for SDRAM to get out self-refresh mode
178 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
182 @ restore regs and return
183 ldmfd sp!, {r0 - r6, pc}
185 ENTRY(pnx4008_cpu_standby_sz)
186 .word . - pnx4008_cpu_standby
188 ENTRY(pnx4008_cache_clean_invalidate)
189 stmfd sp!, {r0 - r6, lr}
190 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
191 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
193 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
196 ldmfd sp!, {r0 - r6, pc}