xref: /openbmc/linux/arch/mips/alchemy/common/sleeper.S (revision 8fa5723aa7e053d498336b48448b292fc2e0458b)
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	.text
19	.set	macro
20	.set	noat
21	.align	5
22
23/* Save all of the processor general registers and go to sleep.
24 * A wakeup condition will get us back here to restore the registers.
25 */
26LEAF(save_and_sleep)
27
28	subu	sp, PT_SIZE
29	sw	$1, PT_R1(sp)
30	sw	$2, PT_R2(sp)
31	sw	$3, PT_R3(sp)
32	sw	$4, PT_R4(sp)
33	sw	$5, PT_R5(sp)
34	sw	$6, PT_R6(sp)
35	sw	$7, PT_R7(sp)
36	sw	$8, PT_R8(sp)
37	sw	$9, PT_R9(sp)
38	sw	$10, PT_R10(sp)
39	sw	$11, PT_R11(sp)
40	sw	$12, PT_R12(sp)
41	sw	$13, PT_R13(sp)
42	sw	$14, PT_R14(sp)
43	sw	$15, PT_R15(sp)
44	sw	$16, PT_R16(sp)
45	sw	$17, PT_R17(sp)
46	sw	$18, PT_R18(sp)
47	sw	$19, PT_R19(sp)
48	sw	$20, PT_R20(sp)
49	sw	$21, PT_R21(sp)
50	sw	$22, PT_R22(sp)
51	sw	$23, PT_R23(sp)
52	sw	$24, PT_R24(sp)
53	sw	$25, PT_R25(sp)
54	sw	$26, PT_R26(sp)
55	sw	$27, PT_R27(sp)
56	sw	$28, PT_R28(sp)
57	sw	$29, PT_R29(sp)
58	sw	$30, PT_R30(sp)
59	sw	$31, PT_R31(sp)
60	mfc0	k0, CP0_STATUS
61	sw	k0, 0x20(sp)
62	mfc0	k0, CP0_CONTEXT
63	sw	k0, 0x1c(sp)
64	mfc0	k0, CP0_PAGEMASK
65	sw	k0, 0x18(sp)
66	mfc0	k0, CP0_CONFIG
67	sw	k0, 0x14(sp)
68
69	/* Now set up the scratch registers so the boot rom will
70	 * return to this point upon wakeup.
71	 */
72	la	k0, 1f
73	lui	k1, 0xb190
74	ori	k1, 0x18
75	sw	sp, 0(k1)
76	ori 	k1, 0x1c
77	sw	k0, 0(k1)
78
79/* Put SDRAM into self refresh.  Preload instructions into cache,
80 * issue a precharge, then auto refresh, then sleep commands to it.
81 */
82	la	t0, sdsleep
83	.set	mips3
84	cache	0x14, 0(t0)
85	cache	0x14, 32(t0)
86	cache	0x14, 64(t0)
87	cache	0x14, 96(t0)
88	.set	mips0
89
90sdsleep:
91	lui 	k0, 0xb400
92	sw	zero, 0x001c(k0)	/* Precharge */
93	sw	zero, 0x0020(k0)	/* Auto refresh */
94	sw	zero, 0x0030(k0)	/* SDRAM sleep */
95	sync
96
97	lui 	k1, 0xb190
98	sw	zero, 0x0078(k1)	/* get ready  to sleep */
99	sync
100	sw	zero, 0x007c(k1)	/* Put processor to sleep */
101	sync
102
103	/* This is where we return upon wakeup.
104	 * Reload all of the registers and return.
105	 */
1061:	nop
107	lw	k0, 0x20(sp)
108	mtc0	k0, CP0_STATUS
109	lw	k0, 0x1c(sp)
110	mtc0	k0, CP0_CONTEXT
111	lw	k0, 0x18(sp)
112	mtc0	k0, CP0_PAGEMASK
113	lw	k0, 0x14(sp)
114	mtc0	k0, CP0_CONFIG
115
116	/* We need to catch the ealry Alchemy SOCs with
117	 * the write-only Config[OD] bit and set it back to one...
118	 */
119	jal	au1x00_fixup_config_od
120	lw	$1, PT_R1(sp)
121	lw	$2, PT_R2(sp)
122	lw	$3, PT_R3(sp)
123	lw	$4, PT_R4(sp)
124	lw	$5, PT_R5(sp)
125	lw	$6, PT_R6(sp)
126	lw	$7, PT_R7(sp)
127	lw	$8, PT_R8(sp)
128	lw	$9, PT_R9(sp)
129	lw	$10, PT_R10(sp)
130	lw	$11, PT_R11(sp)
131	lw	$12, PT_R12(sp)
132	lw	$13, PT_R13(sp)
133	lw	$14, PT_R14(sp)
134	lw	$15, PT_R15(sp)
135	lw	$16, PT_R16(sp)
136	lw	$17, PT_R17(sp)
137	lw	$18, PT_R18(sp)
138	lw	$19, PT_R19(sp)
139	lw	$20, PT_R20(sp)
140	lw	$21, PT_R21(sp)
141	lw	$22, PT_R22(sp)
142	lw	$23, PT_R23(sp)
143	lw	$24, PT_R24(sp)
144	lw	$25, PT_R25(sp)
145	lw	$26, PT_R26(sp)
146	lw	$27, PT_R27(sp)
147	lw	$28, PT_R28(sp)
148	lw	$29, PT_R29(sp)
149	lw	$30, PT_R30(sp)
150	lw	$31, PT_R31(sp)
151	addiu	sp, PT_SIZE
152
153	jr	ra
154END(save_and_sleep)
155