1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Sleep helper for Loongson-3 sleep mode. |
4 | * |
5 | * Author: Huacai Chen <chenhuacai@loongson.cn> |
6 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited |
7 | */ |
8 | |
9 | #include <asm/asm.h> |
10 | #include <asm/asmmacro.h> |
11 | #include <asm/addrspace.h> |
12 | #include <asm/loongarch.h> |
13 | #include <asm/stackframe.h> |
14 | |
15 | /* preparatory stuff */ |
16 | .macro SETUP_SLEEP |
17 | addi.d sp, sp, -PT_SIZE |
18 | st.d $r1, sp, PT_R1 |
19 | st.d $r2, sp, PT_R2 |
20 | st.d $r3, sp, PT_R3 |
21 | st.d $r4, sp, PT_R4 |
22 | st.d $r21, sp, PT_R21 |
23 | st.d $r22, sp, PT_R22 |
24 | st.d $r23, sp, PT_R23 |
25 | st.d $r24, sp, PT_R24 |
26 | st.d $r25, sp, PT_R25 |
27 | st.d $r26, sp, PT_R26 |
28 | st.d $r27, sp, PT_R27 |
29 | st.d $r28, sp, PT_R28 |
30 | st.d $r29, sp, PT_R29 |
31 | st.d $r30, sp, PT_R30 |
32 | st.d $r31, sp, PT_R31 |
33 | |
34 | la.pcrel t0, acpi_saved_sp |
35 | st.d sp, t0, 0 |
36 | .endm |
37 | |
38 | .macro SETUP_WAKEUP |
39 | ld.d $r1, sp, PT_R1 |
40 | ld.d $r2, sp, PT_R2 |
41 | ld.d $r3, sp, PT_R3 |
42 | ld.d $r4, sp, PT_R4 |
43 | ld.d $r21, sp, PT_R21 |
44 | ld.d $r22, sp, PT_R22 |
45 | ld.d $r23, sp, PT_R23 |
46 | ld.d $r24, sp, PT_R24 |
47 | ld.d $r25, sp, PT_R25 |
48 | ld.d $r26, sp, PT_R26 |
49 | ld.d $r27, sp, PT_R27 |
50 | ld.d $r28, sp, PT_R28 |
51 | ld.d $r29, sp, PT_R29 |
52 | ld.d $r30, sp, PT_R30 |
53 | ld.d $r31, sp, PT_R31 |
54 | .endm |
55 | |
56 | .text |
57 | .align 12 |
58 | |
59 | /* Sleep/wakeup code for Loongson-3 */ |
60 | SYM_FUNC_START(loongarch_suspend_enter) |
61 | SETUP_SLEEP |
62 | bl __flush_cache_all |
63 | |
64 | /* Pass RA and SP to BIOS */ |
65 | addi.d a1, sp, 0 |
66 | la.pcrel a0, loongarch_wakeup_start |
67 | la.pcrel t0, loongarch_suspend_addr |
68 | ld.d t0, t0, 0 |
69 | jirl a0, t0, 0 /* Call BIOS's STR sleep routine */ |
70 | |
71 | /* |
72 | * This is where we return upon wakeup. |
73 | * Reload all of the registers and return. |
74 | */ |
75 | SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL) |
76 | li.d t0, CSR_DMW0_INIT # UC, PLV0 |
77 | csrwr t0, LOONGARCH_CSR_DMWIN0 |
78 | li.d t0, CSR_DMW1_INIT # CA, PLV0 |
79 | csrwr t0, LOONGARCH_CSR_DMWIN1 |
80 | |
81 | JUMP_VIRT_ADDR t0, t1 |
82 | |
83 | /* Enable PG */ |
84 | li.w t0, 0xb0 # PLV=0, IE=0, PG=1 |
85 | csrwr t0, LOONGARCH_CSR_CRMD |
86 | |
87 | la.pcrel t0, acpi_saved_sp |
88 | ld.d sp, t0, 0 |
89 | SETUP_WAKEUP |
90 | addi.d sp, sp, PT_SIZE |
91 | jr ra |
92 | SYM_FUNC_END(loongarch_suspend_enter) |
93 | |