Loading...
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 */
150struct 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 */
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 */