]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blob - arch/mips/alchemy/common/sleeper.S
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152
[mirror_ubuntu-eoan-kernel.git] / arch / mips / alchemy / common / sleeper.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright 2002 Embedded Edge, LLC
4 * Author: dan@embeddededge.com
5 *
6 * Sleep helper for Au1xxx sleep mode.
7 */
8
9 #include <asm/asm.h>
10 #include <asm/mipsregs.h>
11 #include <asm/regdef.h>
12 #include <asm/stackframe.h>
13
14 .extern __flush_cache_all
15
16 .text
17 .set noreorder
18 .set noat
19 .align 5
20
21
22 /* preparatory stuff */
23 .macro SETUP_SLEEP
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)
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)
40 sw $26, PT_R26(sp)
41 sw $27, PT_R27(sp)
42 sw $28, PT_R28(sp)
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
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
60 /* Now set up the scratch registers so the boot rom will
61 * return to this point upon wakeup.
62 * sys_scratch0 : SP
63 * sys_scratch1 : RA
64 */
65 lui t3, 0xb190 /* sys_xxx */
66 sw sp, 0x0018(t3)
67 la k0, alchemy_sleep_wakeup /* resume path */
68 sw k0, 0x001c(t3)
69 .endm
70
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 */
93 la t0, 1f
94 .set arch=r4000
95 cache 0x14, 0(t0)
96 cache 0x14, 32(t0)
97 cache 0x14, 64(t0)
98 cache 0x14, 96(t0)
99 .set mips0
100
101 1: lui a0, 0xb400 /* mem_xxx */
102 sw zero, 0x001c(a0) /* Precharge */
103 sync
104 sw zero, 0x0020(a0) /* Auto Refresh */
105 sync
106 sw zero, 0x0030(a0) /* Sleep */
107 sync
108
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
120 .set arch=r4000
121 cache 0x14, 0(t0)
122 cache 0x14, 32(t0)
123 cache 0x14, 64(t0)
124 cache 0x14, 96(t0)
125 .set mips0
126
127 1: lui a0, 0xb400 /* mem_xxx */
128 sw zero, 0x08c0(a0) /* Precharge */
129 sync
130 sw zero, 0x08d0(a0) /* Self Refresh */
131 sync
132
133 /* wait for sdram to enter self-refresh mode */
134 lui t0, 0x0100
135 2: lw t1, 0x0850(a0) /* mem_sdstat */
136 and t2, t1, t0
137 beq t2, zero, 2b
138 nop
139
140 /* disable SDRAM clocks */
141 lui t0, 0xcfff
142 ori t0, t0, 0xffff
143 lw t1, 0x0840(a0) /* mem_sdconfiga */
144 and t1, t0, t1 /* clear CE[1:0] */
145 sw t1, 0x0840(a0) /* mem_sdconfiga */
146 sync
147
148 DO_SLEEP
149
150 END(alchemy_sleep_au1550)
151
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
162 .set arch=r4000
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
225
226 /* This is where we return upon wakeup.
227 * Reload all of the registers and return.
228 */
229 LEAF(alchemy_sleep_wakeup)
230 lw k0, 0x20(sp)
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
238
239 /* We need to catch the early Alchemy SOCs with
240 * the write-only Config[OD] bit and set it back to one...
241 */
242 jal au1x00_fixup_config_od
243 nop
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)
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)
259 lw $26, PT_R26(sp)
260 lw $27, PT_R27(sp)
261 lw $28, PT_R28(sp)
262 lw $30, PT_R30(sp)
263 lw $31, PT_R31(sp)
264 jr ra
265 addiu sp, PT_SIZE
266 END(alchemy_sleep_wakeup)