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