xref: /openbmc/linux/arch/mips/alchemy/common/sleeper.S (revision b04b4f78)
1/*
2 * Copyright 2002 Embedded Edge, LLC
3 * Author: dan@embeddededge.com
4 *
5 * Sleep helper for Au1xxx sleep mode.
6 *
7 * This program is free software; you can redistribute	it and/or modify it
8 * under  the terms of	the GNU General	 Public License as published by the
9 * Free Software Foundation;  either version 2 of the  License, or (at your
10 * option) any later version.
11 */
12
13#include <asm/asm.h>
14#include <asm/mipsregs.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
18	.extern __flush_cache_all
19
20	.text
21	.set noreorder
22	.set noat
23	.align	5
24
25/* Save all of the processor general registers and go to sleep.
26 * A wakeup condition will get us back here to restore the registers.
27 */
28LEAF(au1xxx_save_and_sleep)
29	subu	sp, PT_SIZE
30	sw	$1, PT_R1(sp)
31	sw	$2, PT_R2(sp)
32	sw	$3, PT_R3(sp)
33	sw	$4, PT_R4(sp)
34	sw	$5, PT_R5(sp)
35	sw	$6, PT_R6(sp)
36	sw	$7, PT_R7(sp)
37	sw	$16, PT_R16(sp)
38	sw	$17, PT_R17(sp)
39	sw	$18, PT_R18(sp)
40	sw	$19, PT_R19(sp)
41	sw	$20, PT_R20(sp)
42	sw	$21, PT_R21(sp)
43	sw	$22, PT_R22(sp)
44	sw	$23, PT_R23(sp)
45	sw	$26, PT_R26(sp)
46	sw	$27, PT_R27(sp)
47	sw	$28, PT_R28(sp)
48	sw	$30, PT_R30(sp)
49	sw	$31, PT_R31(sp)
50	mfc0	k0, CP0_STATUS
51	sw	k0, 0x20(sp)
52	mfc0	k0, CP0_CONTEXT
53	sw	k0, 0x1c(sp)
54	mfc0	k0, CP0_PAGEMASK
55	sw	k0, 0x18(sp)
56	mfc0	k0, CP0_CONFIG
57	sw	k0, 0x14(sp)
58
59	/* flush caches to make sure context is in memory */
60	la	t1, __flush_cache_all
61	lw	t0, 0(t1)
62	jalr	t0
63	 nop
64
65	/* Now set up the scratch registers so the boot rom will
66	 * return to this point upon wakeup.
67	 * sys_scratch0 : SP
68	 * sys_scratch1 : RA
69	 */
70	lui	t3, 0xb190		/* sys_xxx */
71	sw	sp, 0x0018(t3)
72	la	k0, 3f			/* resume path */
73	sw	k0, 0x001c(t3)
74
75	/* Put SDRAM into self refresh:  Preload instructions into cache,
76	 * issue a precharge, auto/self refresh, then sleep commands to it.
77	 */
78	la	t0, 1f
79	.set	mips3
80	cache	0x14, 0(t0)
81	cache	0x14, 32(t0)
82	cache	0x14, 64(t0)
83	cache	0x14, 96(t0)
84	.set	mips0
85
861:	lui 	a0, 0xb400		/* mem_xxx */
87#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) ||	\
88    defined(CONFIG_SOC_AU1500)
89	sw	zero, 0x001c(a0) 	/* Precharge */
90	sync
91	sw	zero, 0x0020(a0)	/* Auto Refresh */
92	sync
93	sw	zero, 0x0030(a0)  	/* Sleep */
94	sync
95#endif
96
97#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
98	sw	zero, 0x08c0(a0) 	/* Precharge */
99	sync
100	sw	zero, 0x08d0(a0)	/* Self Refresh */
101	sync
102
103	/* wait for sdram to enter self-refresh mode */
104	lui 	t0, 0x0100
1052:	lw 	t1, 0x0850(a0)		/* mem_sdstat */
106	and	t2, t1, t0
107	beq	t2, zero, 2b
108	 nop
109
110	/* disable SDRAM clocks */
111	lui	t0, 0xcfff
112	ori	t0, t0, 0xffff
113	lw 	t1, 0x0840(a0)		/* mem_sdconfiga */
114	and 	t1, t0, t1		/* clear CE[1:0] */
115	sw 	t1, 0x0840(a0)		/* mem_sdconfiga */
116	sync
117#endif
118
119	/* put power supply and processor to sleep */
120	sw	zero, 0x0078(t3)	/* sys_slppwr */
121	sync
122	sw	zero, 0x007c(t3)	/* sys_sleep */
123	sync
124	nop
125	nop
126	nop
127	nop
128	nop
129	nop
130	nop
131	nop
132
133	/* This is where we return upon wakeup.
134	 * Reload all of the registers and return.
135	 */
1363:	lw	k0, 0x20(sp)
137	mtc0	k0, CP0_STATUS
138	lw	k0, 0x1c(sp)
139	mtc0	k0, CP0_CONTEXT
140	lw	k0, 0x18(sp)
141	mtc0	k0, CP0_PAGEMASK
142	lw	k0, 0x14(sp)
143	mtc0	k0, CP0_CONFIG
144
145	/* We need to catch the early Alchemy SOCs with
146	 * the write-only Config[OD] bit and set it back to one...
147	 */
148	jal	au1x00_fixup_config_od
149	 nop
150	lw	$1, PT_R1(sp)
151	lw	$2, PT_R2(sp)
152	lw	$3, PT_R3(sp)
153	lw	$4, PT_R4(sp)
154	lw	$5, PT_R5(sp)
155	lw	$6, PT_R6(sp)
156	lw	$7, PT_R7(sp)
157	lw	$16, PT_R16(sp)
158	lw	$17, PT_R17(sp)
159	lw	$18, PT_R18(sp)
160	lw	$19, PT_R19(sp)
161	lw	$20, PT_R20(sp)
162	lw	$21, PT_R21(sp)
163	lw	$22, PT_R22(sp)
164	lw	$23, PT_R23(sp)
165	lw	$26, PT_R26(sp)
166	lw	$27, PT_R27(sp)
167	lw	$28, PT_R28(sp)
168	lw	$30, PT_R30(sp)
169	lw	$31, PT_R31(sp)
170	jr	ra
171	 addiu	sp, PT_SIZE
172END(au1xxx_save_and_sleep)
173