xref: /openbmc/linux/arch/mips/alchemy/common/sleeper.S (revision 37002bc6)
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 */
88LEAF(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
1011:	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
111END(alchemy_sleep_au1000)
112
113/* sleep code for Au1550/Au1200 memory controller type */
114LEAF(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
1271:	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
1352:	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
150END(alchemy_sleep_au1550)
151
152/* sleepcode for Au1300 memory controller type */
153LEAF(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
1641:	cache	0x14, 0(t0)
165	subu	t2, t2, 32
166	bgez	t2, 1b
167	 addu	t0, t0, 32
168
169	.set	mips0
170
1712:	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
2083:	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
2214:
222
223END(alchemy_sleep_au1300)
224
225
226	/* This is where we return upon wakeup.
227	 * Reload all of the registers and return.
228	 */
229LEAF(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
266END(alchemy_sleep_wakeup)
267