blob: fea1e17a3650aace27cf69dcac4b520e6041dc75 [file] [log] [blame]
Vitaly Wool78818e42006-05-16 11:54:37 +01001/*
2 * linux/arch/arm/mach-pnx4008/sleep.S
3 *
4 * PNX4008 support for STOP mode and SDRAM self-refresh
5 *
6 * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
7 *
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
11 * or implied.
12 */
13
Vitaly Wool78818e42006-05-16 11:54:37 +010014#include <linux/linkage.h>
15#include <asm/assembler.h>
16#include <asm/hardware.h>
17
18#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
19#define PWR_CTRL_REG_OFFS 0x44
20
21#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
22#define MPMC_STATUS_REG_OFFS 0x4
23
24 .text
25
26ENTRY(pnx4008_cpu_suspend)
27 @this function should be entered in Direct run mode.
28
29 @ save registers on stack
30 stmfd sp!, {r0 - r6, lr}
31
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]
39
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
47
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]
53
54 @ do save current bit settings in r1
55 mov r1, r5
56
57 @ set SDRAM self-refresh bit
58 orr r5, r5, #(1 << 9)
59 str r5, [r4, #PWR_CTRL_REG_OFFS]
60
61 @ set SDRAM self-refresh bit latch
62 orr r5, r5, #(1 << 8)
63 str r5, [r4, #PWR_CTRL_REG_OFFS]
64
65 @ clear SDRAM self-refresh bit latch
66 and r5, r5, #(~(1 << 8))
67 str r5, [r4, #PWR_CTRL_REG_OFFS]
68
69 @ clear SDRAM self-refresh bit
70 and r5, r5, #(~(1 << 9))
71 str r5, [r4, #PWR_CTRL_REG_OFFS]
72
73 @ wait for SDRAM to get into self-refresh mode
742: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
75 tst r3, #(1 << 2)
76 beq 2b
77
78 @ to prepare SDRAM to get out of self-refresh mode after wakeup
79 orr r5, r5, #(1 << 7)
80 str r5, [r4, #PWR_CTRL_REG_OFFS]
81
82 @ do enter stop mode
83 orr r5, r5, #(1 << 0)
84 str r5, [r4, #PWR_CTRL_REG_OFFS]
85 nop
86 nop
87 nop
88 nop
89 nop
90 nop
91 nop
92 nop
93 nop
94
95 @ sleeping now...
96
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]
100
101 @ wait for SDRAM to get out self-refresh mode
1023: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
103 tst r3, #5
104 bne 3b
105
106 @ restore regs and return
107 ldmfd sp!, {r0 - r6, pc}
108
109ENTRY(pnx4008_cpu_suspend_sz)
110 .word . - pnx4008_cpu_suspend
111
112ENTRY(pnx4008_cpu_standby)
113 @ save registers on stack
114 stmfd sp!, {r0 - r6, lr}
115
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]
123
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
131
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]
137
138 @ do save current bit settings in r1
139 mov r1, r5
140
141 @ set SDRAM self-refresh bit
142 orr r5, r5, #(1 << 9)
143 str r5, [r4, #PWR_CTRL_REG_OFFS]
144
145 @ set SDRAM self-refresh bit latch
146 orr r5, r5, #(1 << 8)
147 str r5, [r4, #PWR_CTRL_REG_OFFS]
148
149 @ clear SDRAM self-refresh bit latch
150 and r5, r5, #(~(1 << 8))
151 str r5, [r4, #PWR_CTRL_REG_OFFS]
152
153 @ clear SDRAM self-refresh bit
154 and r5, r5, #(~(1 << 9))
155 str r5, [r4, #PWR_CTRL_REG_OFFS]
156
157 @ wait for SDRAM to get into self-refresh mode
1582: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
159 tst r3, #(1 << 2)
160 beq 2b
161
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]
165
166 mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
167
168 @ set SDRAM self-refresh bit latch
169 orr r5, r5, #(1 << 8)
170 str r5, [r4, #PWR_CTRL_REG_OFFS]
171
172 @ clear SDRAM self-refresh bit latch
173 and r5, r5, #(~(1 << 8))
174 str r5, [r4, #PWR_CTRL_REG_OFFS]
175
176 @ wait for SDRAM to get out self-refresh mode
1773: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
178 tst r3, #5
179 bne 3b
180
181 @ restore regs and return
182 ldmfd sp!, {r0 - r6, pc}
183
184ENTRY(pnx4008_cpu_standby_sz)
185 .word . - pnx4008_cpu_standby
186
187ENTRY(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
191#else
1921: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
193 bne 1b
194#endif
195 ldmfd sp!, {r0 - r6, pc}