Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
1da177e4 LT |
2 | /* |
3 | * Copyright 2002 Embedded Edge, LLC | |
4 | * Author: dan@embeddededge.com | |
5 | * | |
6 | * Sleep helper for Au1xxx sleep mode. | |
1da177e4 | 7 | */ |
ce28f94c | 8 | |
1da177e4 LT |
9 | #include <asm/asm.h> |
10 | #include <asm/mipsregs.h> | |
1da177e4 LT |
11 | #include <asm/regdef.h> |
12 | #include <asm/stackframe.h> | |
13 | ||
564365b0 ML |
14 | .extern __flush_cache_all |
15 | ||
1da177e4 | 16 | .text |
564365b0 ML |
17 | .set noreorder |
18 | .set noat | |
1da177e4 LT |
19 | .align 5 |
20 | ||
2e93d1ec ML |
21 | |
22 | /* preparatory stuff */ | |
23 | .macro SETUP_SLEEP | |
1da177e4 LT |
24 | subu sp, PT_SIZE |
25 | sw $1, PT_R1(sp) | |
26 | sw $2, PT_R2(sp) | |
27 | sw $3, PT_R3(sp) | |
28 | sw $4, PT_R4(sp) | |
29 | sw $5, PT_R5(sp) | |
30 | sw $6, PT_R6(sp) | |
31 | sw $7, PT_R7(sp) | |
1da177e4 LT |
32 | sw $16, PT_R16(sp) |
33 | sw $17, PT_R17(sp) | |
34 | sw $18, PT_R18(sp) | |
35 | sw $19, PT_R19(sp) | |
36 | sw $20, PT_R20(sp) | |
37 | sw $21, PT_R21(sp) | |
38 | sw $22, PT_R22(sp) | |
39 | sw $23, PT_R23(sp) | |
1da177e4 LT |
40 | sw $26, PT_R26(sp) |
41 | sw $27, PT_R27(sp) | |
42 | sw $28, PT_R28(sp) | |
1da177e4 LT |
43 | sw $30, PT_R30(sp) |
44 | sw $31, PT_R31(sp) | |
45 | mfc0 k0, CP0_STATUS | |
46 | sw k0, 0x20(sp) | |
47 | mfc0 k0, CP0_CONTEXT | |
48 | sw k0, 0x1c(sp) | |
49 | mfc0 k0, CP0_PAGEMASK | |
50 | sw k0, 0x18(sp) | |
51 | mfc0 k0, CP0_CONFIG | |
52 | sw k0, 0x14(sp) | |
53 | ||
564365b0 ML |
54 | /* flush caches to make sure context is in memory */ |
55 | la t1, __flush_cache_all | |
56 | lw t0, 0(t1) | |
57 | jalr t0 | |
58 | nop | |
59 | ||
1da177e4 LT |
60 | /* Now set up the scratch registers so the boot rom will |
61 | * return to this point upon wakeup. | |
564365b0 ML |
62 | * sys_scratch0 : SP |
63 | * sys_scratch1 : RA | |
1da177e4 | 64 | */ |
564365b0 ML |
65 | lui t3, 0xb190 /* sys_xxx */ |
66 | sw sp, 0x0018(t3) | |
2e93d1ec | 67 | la k0, alchemy_sleep_wakeup /* resume path */ |
564365b0 | 68 | sw k0, 0x001c(t3) |
2e93d1ec | 69 | .endm |
1da177e4 | 70 | |
2e93d1ec ML |
71 | .macro DO_SLEEP |
72 | /* put power supply and processor to sleep */ | |
73 | sw zero, 0x0078(t3) /* sys_slppwr */ | |
74 | sync | |
75 | sw zero, 0x007c(t3) /* sys_sleep */ | |
76 | sync | |
77 | nop | |
78 | nop | |
79 | nop | |
80 | nop | |
81 | nop | |
82 | nop | |
83 | nop | |
84 | nop | |
85 | .endm | |
86 | ||
87 | /* sleep code for Au1000/Au1100/Au1500 memory controller type */ | |
88 | LEAF(alchemy_sleep_au1000) | |
89 | ||
90 | SETUP_SLEEP | |
91 | ||
92 | /* cache following instructions, as memory gets put to sleep */ | |
564365b0 | 93 | la t0, 1f |
a809d460 | 94 | .set arch=r4000 |
e8c7c482 RB |
95 | cache 0x14, 0(t0) |
96 | cache 0x14, 32(t0) | |
97 | cache 0x14, 64(t0) | |
98 | cache 0x14, 96(t0) | |
1da177e4 LT |
99 | .set mips0 |
100 | ||
70342287 RB |
101 | 1: lui a0, 0xb400 /* mem_xxx */ |
102 | sw zero, 0x001c(a0) /* Precharge */ | |
564365b0 ML |
103 | sync |
104 | sw zero, 0x0020(a0) /* Auto Refresh */ | |
105 | sync | |
70342287 | 106 | sw zero, 0x0030(a0) /* Sleep */ |
564365b0 | 107 | sync |
564365b0 | 108 | |
2e93d1ec ML |
109 | DO_SLEEP |
110 | ||
111 | END(alchemy_sleep_au1000) | |
112 | ||
113 | /* sleep code for Au1550/Au1200 memory controller type */ | |
114 | LEAF(alchemy_sleep_au1550) | |
115 | ||
116 | SETUP_SLEEP | |
117 | ||
118 | /* cache following instructions, as memory gets put to sleep */ | |
119 | la t0, 1f | |
a809d460 | 120 | .set arch=r4000 |
2e93d1ec ML |
121 | cache 0x14, 0(t0) |
122 | cache 0x14, 32(t0) | |
123 | cache 0x14, 64(t0) | |
124 | cache 0x14, 96(t0) | |
125 | .set mips0 | |
126 | ||
70342287 RB |
127 | 1: lui a0, 0xb400 /* mem_xxx */ |
128 | sw zero, 0x08c0(a0) /* Precharge */ | |
1da177e4 | 129 | sync |
564365b0 ML |
130 | sw zero, 0x08d0(a0) /* Self Refresh */ |
131 | sync | |
132 | ||
133 | /* wait for sdram to enter self-refresh mode */ | |
70342287 RB |
134 | lui t0, 0x0100 |
135 | 2: lw t1, 0x0850(a0) /* mem_sdstat */ | |
564365b0 ML |
136 | and t2, t1, t0 |
137 | beq t2, zero, 2b | |
138 | nop | |
1da177e4 | 139 | |
564365b0 ML |
140 | /* disable SDRAM clocks */ |
141 | lui t0, 0xcfff | |
142 | ori t0, t0, 0xffff | |
70342287 RB |
143 | lw t1, 0x0840(a0) /* mem_sdconfiga */ |
144 | and t1, t0, t1 /* clear CE[1:0] */ | |
145 | sw t1, 0x0840(a0) /* mem_sdconfiga */ | |
1da177e4 | 146 | sync |
564365b0 | 147 | |
2e93d1ec ML |
148 | DO_SLEEP |
149 | ||
150 | END(alchemy_sleep_au1550) | |
151 | ||
809f36c6 ML |
152 | /* sleepcode for Au1300 memory controller type */ |
153 | LEAF(alchemy_sleep_au1300) | |
154 | ||
155 | SETUP_SLEEP | |
156 | ||
157 | /* cache following instructions, as memory gets put to sleep */ | |
158 | la t0, 2f | |
159 | la t1, 4f | |
160 | subu t2, t1, t0 | |
161 | ||
a809d460 | 162 | .set arch=r4000 |
809f36c6 ML |
163 | |
164 | 1: cache 0x14, 0(t0) | |
165 | subu t2, t2, 32 | |
166 | bgez t2, 1b | |
167 | addu t0, t0, 32 | |
168 | ||
169 | .set mips0 | |
170 | ||
171 | 2: lui a0, 0xb400 /* mem_xxx */ | |
172 | ||
173 | /* disable all ports in mem_sdportcfga */ | |
174 | sw zero, 0x868(a0) /* mem_sdportcfga */ | |
175 | sync | |
176 | ||
177 | /* disable ODT */ | |
178 | li t0, 0x03010000 | |
179 | sw t0, 0x08d8(a0) /* mem_sdcmd0 */ | |
180 | sw t0, 0x08dc(a0) /* mem_sdcmd1 */ | |
181 | sync | |
182 | ||
183 | /* precharge */ | |
184 | li t0, 0x23000400 | |
185 | sw t0, 0x08dc(a0) /* mem_sdcmd1 */ | |
186 | sw t0, 0x08d8(a0) /* mem_sdcmd0 */ | |
187 | sync | |
188 | ||
189 | /* auto refresh */ | |
190 | sw zero, 0x08c8(a0) /* mem_sdautoref */ | |
191 | sync | |
192 | ||
193 | /* block access to the DDR */ | |
194 | lw t0, 0x0848(a0) /* mem_sdconfigb */ | |
195 | li t1, (1 << 7 | 0x3F) | |
196 | or t0, t0, t1 | |
197 | sw t0, 0x0848(a0) /* mem_sdconfigb */ | |
198 | sync | |
199 | ||
200 | /* issue the Self Refresh command */ | |
201 | li t0, 0x10000000 | |
202 | sw t0, 0x08dc(a0) /* mem_sdcmd1 */ | |
203 | sw t0, 0x08d8(a0) /* mem_sdcmd0 */ | |
204 | sync | |
205 | ||
206 | /* wait for sdram to enter self-refresh mode */ | |
207 | lui t0, 0x0300 | |
208 | 3: lw t1, 0x0850(a0) /* mem_sdstat */ | |
209 | and t2, t1, t0 | |
210 | bne t2, t0, 3b | |
211 | nop | |
212 | ||
213 | /* disable SDRAM clocks */ | |
214 | li t0, ~(3<<28) | |
215 | lw t1, 0x0840(a0) /* mem_sdconfiga */ | |
216 | and t1, t1, t0 /* clear CE[1:0] */ | |
217 | sw t1, 0x0840(a0) /* mem_sdconfiga */ | |
218 | sync | |
219 | ||
220 | DO_SLEEP | |
221 | 4: | |
222 | ||
223 | END(alchemy_sleep_au1300) | |
224 | ||
1da177e4 LT |
225 | |
226 | /* This is where we return upon wakeup. | |
227 | * Reload all of the registers and return. | |
228 | */ | |
2e93d1ec ML |
229 | LEAF(alchemy_sleep_wakeup) |
230 | lw k0, 0x20(sp) | |
1da177e4 LT |
231 | mtc0 k0, CP0_STATUS |
232 | lw k0, 0x1c(sp) | |
233 | mtc0 k0, CP0_CONTEXT | |
234 | lw k0, 0x18(sp) | |
235 | mtc0 k0, CP0_PAGEMASK | |
236 | lw k0, 0x14(sp) | |
237 | mtc0 k0, CP0_CONFIG | |
9370b351 | 238 | |
564365b0 | 239 | /* We need to catch the early Alchemy SOCs with |
9370b351 SS |
240 | * the write-only Config[OD] bit and set it back to one... |
241 | */ | |
242 | jal au1x00_fixup_config_od | |
564365b0 | 243 | nop |
1da177e4 LT |
244 | lw $1, PT_R1(sp) |
245 | lw $2, PT_R2(sp) | |
246 | lw $3, PT_R3(sp) | |
247 | lw $4, PT_R4(sp) | |
248 | lw $5, PT_R5(sp) | |
249 | lw $6, PT_R6(sp) | |
250 | lw $7, PT_R7(sp) | |
1da177e4 LT |
251 | lw $16, PT_R16(sp) |
252 | lw $17, PT_R17(sp) | |
253 | lw $18, PT_R18(sp) | |
254 | lw $19, PT_R19(sp) | |
255 | lw $20, PT_R20(sp) | |
256 | lw $21, PT_R21(sp) | |
257 | lw $22, PT_R22(sp) | |
258 | lw $23, PT_R23(sp) | |
1da177e4 LT |
259 | lw $26, PT_R26(sp) |
260 | lw $27, PT_R27(sp) | |
261 | lw $28, PT_R28(sp) | |
1da177e4 LT |
262 | lw $30, PT_R30(sp) |
263 | lw $31, PT_R31(sp) | |
1da177e4 | 264 | jr ra |
564365b0 | 265 | addiu sp, PT_SIZE |
2e93d1ec | 266 | END(alchemy_sleep_wakeup) |