arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / powerpc / platforms / 52xx / lite5200_sleep.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/linkage.h>
3
4 #include <asm/reg.h>
5 #include <asm/ppc_asm.h>
6 #include <asm/processor.h>
7 #include <asm/cache.h>
8
9
10 #define SDRAM_CTRL      0x104
11 #define SC_MODE_EN      (1<<31)
12 #define SC_CKE          (1<<30)
13 #define SC_REF_EN       (1<<28)
14 #define SC_SOFT_PRE     (1<<1)
15
16 #define GPIOW_GPIOE     0xc00
17 #define GPIOW_DDR       0xc08
18 #define GPIOW_DVO       0xc0c
19
20 #define CDM_CE          0x214
21 #define CDM_SDRAM       (1<<3)
22
23
24 /* helpers... beware: r10 and r4 are overwritten */
25 #define SAVE_SPRN(reg, addr)            \
26         mfspr   r10, SPRN_##reg;        \
27         stw     r10, ((addr)*4)(r4);
28
29 #define LOAD_SPRN(reg, addr)            \
30         lwz     r10, ((addr)*4)(r4);    \
31         mtspr   SPRN_##reg, r10;        \
32         sync;                           \
33         isync;
34
35
36         .data
37 registers:
38         .space 0x5c*4
39         .text
40
41 /* ---------------------------------------------------------------------- */
42 /* low-power mode with help of M68HLC908QT1 */
43
44         .globl lite5200_low_power
45 lite5200_low_power:
46
47         mr      r7, r3  /* save SRAM va */
48         mr      r8, r4  /* save MBAR va */
49
50         /* setup wakeup address for u-boot at physical location 0x0 */
51         lis     r3, CONFIG_KERNEL_START@h
52         lis     r4, lite5200_wakeup@h
53         ori     r4, r4, lite5200_wakeup@l
54         sub     r4, r4, r3
55         stw     r4, 0(r3)
56
57
58         /*
59          * save stuff BDI overwrites
60          * 0xf0 (0xe0->0x100 gets overwritten when BDI connected;
61          *   even when CONFIG_BDI_SWITCH is disabled and MMU XLAT commented; heisenbug?))
62          * WARNING: self-refresh doesn't seem to work when BDI2000 is connected,
63          *   possibly because BDI sets SDRAM registers before wakeup code does
64          */
65         lis     r4, registers@h
66         ori     r4, r4, registers@l
67         lwz     r10, 0xf0(r3)
68         stw     r10, (0x1d*4)(r4)
69
70         /* save registers to r4 [destroys r10] */
71         SAVE_SPRN(LR, 0x1c)
72         bl      save_regs
73
74         /* flush caches [destroys r3, r4] */
75         bl      flush_data_cache
76
77
78         /* copy code to sram */
79         mr      r4, r7
80         li      r3, (sram_code_end - sram_code)/4
81         mtctr   r3
82         lis     r3, sram_code@h
83         ori     r3, r3, sram_code@l
84 1:
85         lwz     r5, 0(r3)
86         stw     r5, 0(r4)
87         addi    r3, r3, 4
88         addi    r4, r4, 4
89         bdnz    1b
90
91         /* get tb_ticks_per_usec */
92         lis     r3, tb_ticks_per_usec@h
93         lwz     r11, tb_ticks_per_usec@l(r3)
94
95         /* disable I and D caches */
96         mfspr   r3, SPRN_HID0
97         ori     r3, r3, HID0_ICE | HID0_DCE
98         xori    r3, r3, HID0_ICE | HID0_DCE
99         sync; isync;
100         mtspr   SPRN_HID0, r3
101         sync; isync;
102
103         /* jump to sram */
104         mtlr    r7
105         blrl
106         /* doesn't return */
107
108
109 sram_code:
110         /* self refresh */
111         lwz     r4, SDRAM_CTRL(r8)
112
113         /* send NOP (precharge) */
114         oris    r4, r4, SC_MODE_EN@h    /* mode_en */
115         stw     r4, SDRAM_CTRL(r8)
116         sync
117
118         ori     r4, r4, SC_SOFT_PRE     /* soft_pre */
119         stw     r4, SDRAM_CTRL(r8)
120         sync
121         xori    r4, r4, SC_SOFT_PRE
122
123         xoris   r4, r4, SC_MODE_EN@h    /* !mode_en */
124         stw     r4, SDRAM_CTRL(r8)
125         sync
126
127         /* delay (for NOP to finish) */
128         li      r12, 1
129         bl      udelay
130
131         /*
132          * mode_en must not be set when enabling self-refresh
133          * send AR with CKE low (self-refresh)
134          */
135         oris    r4, r4, (SC_REF_EN | SC_CKE)@h
136         xoris   r4, r4, (SC_CKE)@h      /* ref_en !cke */
137         stw     r4, SDRAM_CTRL(r8)
138         sync
139
140         /* delay (after !CKE there should be two cycles) */
141         li      r12, 1
142         bl      udelay
143
144         /* disable clock */
145         lwz     r4, CDM_CE(r8)
146         ori     r4, r4, CDM_SDRAM
147         xori    r4, r4, CDM_SDRAM
148         stw     r4, CDM_CE(r8)
149         sync
150
151         /* delay a bit */
152         li      r12, 1
153         bl      udelay
154
155
156         /* turn off with QT chip */
157         li      r4, 0x02
158         stb     r4, GPIOW_GPIOE(r8)     /* enable gpio_wkup1 */
159         sync
160
161         stb     r4, GPIOW_DVO(r8)       /* "output" high */
162         sync
163         stb     r4, GPIOW_DDR(r8)       /* output */
164         sync
165         stb     r4, GPIOW_DVO(r8)       /* output high */
166         sync
167
168         /* 10uS delay */
169         li      r12, 10
170         bl      udelay
171
172         /* turn off */
173         li      r4, 0
174         stb     r4, GPIOW_DVO(r8)       /* output low */
175         sync
176
177         /* wait until we're offline */
178   1:
179         b       1b
180
181
182         /* local udelay in sram is needed */
183 SYM_FUNC_START_LOCAL(udelay)
184         /* r11 - tb_ticks_per_usec, r12 - usecs, overwrites r13 */
185         mullw   r12, r12, r11
186         mftb    r13     /* start */
187         add     r12, r13, r12 /* end */
188     1:
189         mftb    r13     /* current */
190         cmp     cr0, r13, r12
191         blt     1b
192         blr
193 SYM_FUNC_END(udelay)
194
195 sram_code_end:
196
197
198
199 /* uboot jumps here on resume */
200 lite5200_wakeup:
201         bl      restore_regs
202
203
204         /* HIDs, MSR */
205         LOAD_SPRN(HID1, 0x19)
206         LOAD_SPRN(HID2, 0x1a)
207
208
209         /* address translation is tricky (see turn_on_mmu) */
210         mfmsr   r10
211         ori     r10, r10, MSR_DR | MSR_IR
212
213
214         mtspr   SPRN_SRR1, r10
215         lis     r10, mmu_on@h
216         ori     r10, r10, mmu_on@l
217         mtspr   SPRN_SRR0, r10
218         sync
219         rfi
220 mmu_on:
221         /* kernel offset (r4 is still set from restore_registers) */
222         addis   r4, r4, CONFIG_KERNEL_START@h
223
224
225         /* restore MSR */
226         lwz     r10, (4*0x1b)(r4)
227         mtmsr   r10
228         sync; isync;
229
230         /* invalidate caches */
231         mfspr   r10, SPRN_HID0
232         ori     r5, r10, HID0_ICFI | HID0_DCI
233         mtspr   SPRN_HID0, r5   /* invalidate caches */
234         sync; isync;
235         mtspr   SPRN_HID0, r10
236         sync; isync;
237
238         /* enable caches */
239         lwz     r10, (4*0x18)(r4)
240         mtspr   SPRN_HID0, r10  /* restore (enable caches, DPM) */
241         /* ^ this has to be after address translation set in MSR */
242         sync
243         isync
244
245
246         /* restore 0xf0 (BDI2000) */
247         lis     r3, CONFIG_KERNEL_START@h
248         lwz     r10, (0x1d*4)(r4)
249         stw     r10, 0xf0(r3)
250
251         LOAD_SPRN(LR, 0x1c)
252
253
254         blr
255 _ASM_NOKPROBE_SYMBOL(lite5200_wakeup)
256
257
258 /* ---------------------------------------------------------------------- */
259 /* boring code: helpers */
260
261 /* save registers */
262 #define SAVE_BAT(n, addr)               \
263         SAVE_SPRN(DBAT##n##L, addr);    \
264         SAVE_SPRN(DBAT##n##U, addr+1);  \
265         SAVE_SPRN(IBAT##n##L, addr+2);  \
266         SAVE_SPRN(IBAT##n##U, addr+3);
267
268 #define SAVE_SR(n, addr)                \
269         mfsr    r10, n;                 \
270         stw     r10, ((addr)*4)(r4);
271
272 #define SAVE_4SR(n, addr)       \
273         SAVE_SR(n, addr);       \
274         SAVE_SR(n+1, addr+1);   \
275         SAVE_SR(n+2, addr+2);   \
276         SAVE_SR(n+3, addr+3);
277
278 SYM_FUNC_START_LOCAL(save_regs)
279         stw     r0, 0(r4)
280         stw     r1, 0x4(r4)
281         stw     r2, 0x8(r4)
282         stmw    r11, 0xc(r4) /* 0xc -> 0x5f, (0x18*4-1) */
283
284         SAVE_SPRN(HID0, 0x18)
285         SAVE_SPRN(HID1, 0x19)
286         SAVE_SPRN(HID2, 0x1a)
287         mfmsr   r10
288         stw     r10, (4*0x1b)(r4)
289         /*SAVE_SPRN(LR, 0x1c) have to save it before the call */
290         /* 0x1d reserved by 0xf0 */
291         SAVE_SPRN(RPA,   0x1e)
292         SAVE_SPRN(SDR1,  0x1f)
293
294         /* save MMU regs */
295         SAVE_BAT(0, 0x20)
296         SAVE_BAT(1, 0x24)
297         SAVE_BAT(2, 0x28)
298         SAVE_BAT(3, 0x2c)
299         SAVE_BAT(4, 0x30)
300         SAVE_BAT(5, 0x34)
301         SAVE_BAT(6, 0x38)
302         SAVE_BAT(7, 0x3c)
303
304         SAVE_4SR(0, 0x40)
305         SAVE_4SR(4, 0x44)
306         SAVE_4SR(8, 0x48)
307         SAVE_4SR(12, 0x4c)
308
309         SAVE_SPRN(SPRG0, 0x50)
310         SAVE_SPRN(SPRG1, 0x51)
311         SAVE_SPRN(SPRG2, 0x52)
312         SAVE_SPRN(SPRG3, 0x53)
313         SAVE_SPRN(SPRG4, 0x54)
314         SAVE_SPRN(SPRG5, 0x55)
315         SAVE_SPRN(SPRG6, 0x56)
316         SAVE_SPRN(SPRG7, 0x57)
317
318         SAVE_SPRN(IABR,  0x58)
319         SAVE_SPRN(DABR,  0x59)
320         SAVE_SPRN(TBRL,  0x5a)
321         SAVE_SPRN(TBRU,  0x5b)
322
323         blr
324 SYM_FUNC_END(save_regs)
325
326
327 /* restore registers */
328 #define LOAD_BAT(n, addr)               \
329         LOAD_SPRN(DBAT##n##L, addr);    \
330         LOAD_SPRN(DBAT##n##U, addr+1);  \
331         LOAD_SPRN(IBAT##n##L, addr+2);  \
332         LOAD_SPRN(IBAT##n##U, addr+3);
333
334 #define LOAD_SR(n, addr)                \
335         lwz     r10, ((addr)*4)(r4);    \
336         mtsr    n, r10;
337
338 #define LOAD_4SR(n, addr)       \
339         LOAD_SR(n, addr);       \
340         LOAD_SR(n+1, addr+1);   \
341         LOAD_SR(n+2, addr+2);   \
342         LOAD_SR(n+3, addr+3);
343
344 SYM_FUNC_START_LOCAL(restore_regs)
345         lis     r4, registers@h
346         ori     r4, r4, registers@l
347
348         /* MMU is not up yet */
349         subis   r4, r4, CONFIG_KERNEL_START@h
350
351         lwz     r0, 0(r4)
352         lwz     r1, 0x4(r4)
353         lwz     r2, 0x8(r4)
354         lmw     r11, 0xc(r4)
355
356         /*
357          * these are a bit tricky
358          *
359          * 0x18 - HID0
360          * 0x19 - HID1
361          * 0x1a - HID2
362          * 0x1b - MSR
363          * 0x1c - LR
364          * 0x1d - reserved by 0xf0 (BDI2000)
365          */
366         LOAD_SPRN(RPA,   0x1e);
367         LOAD_SPRN(SDR1,  0x1f);
368
369         /* restore MMU regs */
370         LOAD_BAT(0, 0x20)
371         LOAD_BAT(1, 0x24)
372         LOAD_BAT(2, 0x28)
373         LOAD_BAT(3, 0x2c)
374         LOAD_BAT(4, 0x30)
375         LOAD_BAT(5, 0x34)
376         LOAD_BAT(6, 0x38)
377         LOAD_BAT(7, 0x3c)
378
379         LOAD_4SR(0, 0x40)
380         LOAD_4SR(4, 0x44)
381         LOAD_4SR(8, 0x48)
382         LOAD_4SR(12, 0x4c)
383
384         /* rest of regs */
385         LOAD_SPRN(SPRG0, 0x50);
386         LOAD_SPRN(SPRG1, 0x51);
387         LOAD_SPRN(SPRG2, 0x52);
388         LOAD_SPRN(SPRG3, 0x53);
389         LOAD_SPRN(SPRG4, 0x54);
390         LOAD_SPRN(SPRG5, 0x55);
391         LOAD_SPRN(SPRG6, 0x56);
392         LOAD_SPRN(SPRG7, 0x57);
393
394         LOAD_SPRN(IABR,  0x58);
395         LOAD_SPRN(DABR,  0x59);
396         LOAD_SPRN(TBWL,  0x5a); /* these two have separate R/W regs */
397         LOAD_SPRN(TBWU,  0x5b);
398
399         blr
400 _ASM_NOKPROBE_SYMBOL(restore_regs)
401 SYM_FUNC_END(restore_regs)
402
403
404
405 /* cache flushing code. copied from arch/ppc/boot/util.S */
406 #define NUM_CACHE_LINES (128*8)
407
408 /*
409  * Flush data cache
410  * Do this by just reading lots of stuff into the cache.
411  */
412 SYM_FUNC_START_LOCAL(flush_data_cache)
413         lis     r3,CONFIG_KERNEL_START@h
414         ori     r3,r3,CONFIG_KERNEL_START@l
415         li      r4,NUM_CACHE_LINES
416         mtctr   r4
417 1:
418         lwz     r4,0(r3)
419         addi    r3,r3,L1_CACHE_BYTES    /* Next line, please */
420         bdnz    1b
421         blr
422 SYM_FUNC_END(flush_data_cache)