1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (C) 2014 Imagination Technologies Ltd 4 * 5 * PM helper macros for CPU power off (e.g. Suspend-to-RAM). 6 */ 7 8 #ifndef __ASM_PM_H 9 #define __ASM_PM_H 10 11 #ifdef __ASSEMBLY__ 12 13 #include <asm/asm-offsets.h> 14 #include <asm/asm.h> 15 #include <asm/mipsregs.h> 16 #include <asm/regdef.h> 17 18 /* Save CPU state to stack for suspend to RAM */ 19 .macro SUSPEND_SAVE_REGS 20 PTR_SUBU sp, PT_SIZE 21 /* Call preserved GPRs */ 22 LONG_S $16, PT_R16(sp) 23 LONG_S $17, PT_R17(sp) 24 LONG_S $18, PT_R18(sp) 25 LONG_S $19, PT_R19(sp) 26 LONG_S $20, PT_R20(sp) 27 LONG_S $21, PT_R21(sp) 28 LONG_S $22, PT_R22(sp) 29 LONG_S $23, PT_R23(sp) 30 LONG_S $28, PT_R28(sp) 31 LONG_S $30, PT_R30(sp) 32 LONG_S $31, PT_R31(sp) 33 /* A couple of CP0 registers with space in pt_regs */ 34 mfc0 k0, CP0_STATUS 35 LONG_S k0, PT_STATUS(sp) 36 .endm 37 38 /* Restore CPU state from stack after resume from RAM */ 39 .macro RESUME_RESTORE_REGS_RETURN 40 .set push 41 .set noreorder 42 /* A couple of CP0 registers with space in pt_regs */ 43 LONG_L k0, PT_STATUS(sp) 44 mtc0 k0, CP0_STATUS 45 /* Call preserved GPRs */ 46 LONG_L $16, PT_R16(sp) 47 LONG_L $17, PT_R17(sp) 48 LONG_L $18, PT_R18(sp) 49 LONG_L $19, PT_R19(sp) 50 LONG_L $20, PT_R20(sp) 51 LONG_L $21, PT_R21(sp) 52 LONG_L $22, PT_R22(sp) 53 LONG_L $23, PT_R23(sp) 54 LONG_L $28, PT_R28(sp) 55 LONG_L $30, PT_R30(sp) 56 LONG_L $31, PT_R31(sp) 57 /* Pop and return */ 58 jr ra 59 PTR_ADDIU sp, PT_SIZE 60 .set pop 61 .endm 62 63 /* Get address of static suspend state into t1 */ 64 .macro LA_STATIC_SUSPEND 65 PTR_LA t1, mips_static_suspend_state 66 .endm 67 68 /* Save important CPU state for early restoration to global data */ 69 .macro SUSPEND_SAVE_STATIC 70 #ifdef CONFIG_EVA 71 /* 72 * Segment configuration is saved in global data where it can be easily 73 * reloaded without depending on the segment configuration. 74 */ 75 mfc0 k0, CP0_SEGCTL0 76 LONG_S k0, SSS_SEGCTL0(t1) 77 mfc0 k0, CP0_SEGCTL1 78 LONG_S k0, SSS_SEGCTL1(t1) 79 mfc0 k0, CP0_SEGCTL2 80 LONG_S k0, SSS_SEGCTL2(t1) 81 #endif 82 /* save stack pointer (pointing to GPRs) */ 83 LONG_S sp, SSS_SP(t1) 84 .endm 85 86 /* Restore important CPU state early from global data */ 87 .macro RESUME_RESTORE_STATIC 88 #ifdef CONFIG_EVA 89 /* 90 * Segment configuration must be restored prior to any access to 91 * allocated memory, as it may reside outside of the legacy kernel 92 * segments. 93 */ 94 LONG_L k0, SSS_SEGCTL0(t1) 95 mtc0 k0, CP0_SEGCTL0 96 LONG_L k0, SSS_SEGCTL1(t1) 97 mtc0 k0, CP0_SEGCTL1 98 LONG_L k0, SSS_SEGCTL2(t1) 99 mtc0 k0, CP0_SEGCTL2 100 tlbw_use_hazard 101 #endif 102 /* restore stack pointer (pointing to GPRs) */ 103 LONG_L sp, SSS_SP(t1) 104 .endm 105 106 /* flush caches to make sure context has reached memory */ 107 .macro SUSPEND_CACHE_FLUSH 108 .extern __flush_cache_all 109 .set push 110 .set noreorder 111 PTR_LA t1, __flush_cache_all 112 LONG_L t0, 0(t1) 113 jalr t0 114 nop 115 .set pop 116 .endm 117 118 /* Save suspend state and flush data caches to RAM */ 119 .macro SUSPEND_SAVE 120 SUSPEND_SAVE_REGS 121 LA_STATIC_SUSPEND 122 SUSPEND_SAVE_STATIC 123 SUSPEND_CACHE_FLUSH 124 .endm 125 126 /* Restore saved state after resume from RAM and return */ 127 .macro RESUME_RESTORE_RETURN 128 LA_STATIC_SUSPEND 129 RESUME_RESTORE_STATIC 130 RESUME_RESTORE_REGS_RETURN 131 .endm 132 133 #else /* __ASSEMBLY__ */ 134 135 /** 136 * struct mips_static_suspend_state - Core saved CPU state across S2R. 137 * @segctl: CP0 Segment control registers. 138 * @sp: Stack frame where GP register context is saved. 139 * 140 * This structure contains minimal CPU state that must be saved in static kernel 141 * data in order to be able to restore the rest of the state. This includes 142 * segmentation configuration in the case of EVA being enabled, as they must be 143 * restored prior to any kmalloc'd memory being referenced (even the stack 144 * pointer). 145 */ 146 struct mips_static_suspend_state { 147 #ifdef CONFIG_EVA 148 unsigned long segctl[3]; 149 #endif 150 unsigned long sp; 151 }; 152 153 #endif /* !__ASSEMBLY__ */ 154 155 #endif /* __ASM_PM_HELPERS_H */ 156