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