pm.h (3871B)
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 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 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 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_PAGEMASK, 2 /* SegCtl0 */ 76 LONG_S k0, SSS_SEGCTL0(t1) 77 mfc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */ 78 LONG_S k0, SSS_SEGCTL1(t1) 79 mfc0 k0, CP0_PAGEMASK, 4 /* 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_PAGEMASK, 2 /* SegCtl0 */ 96 LONG_L k0, SSS_SEGCTL1(t1) 97 mtc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */ 98 LONG_L k0, SSS_SEGCTL2(t1) 99 mtc0 k0, CP0_PAGEMASK, 4 /* 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 __wback_cache_all 109 .set push 110 .set noreorder 111 la t1, __wback_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 */ 146struct 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 */