Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/alchemy/common/sleeper.S
26481 views
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
/*
3
* Copyright 2002 Embedded Edge, LLC
4
* Author: [email protected]
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)
267
268