Linux-libre 5.4.49-gnu
[librecmc/linux-libre.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)