diff options
Diffstat (limited to 'arch/sh/kernel/cpu/shmobile/sleep.S')
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/sleep.S | 155 |
1 files changed, 105 insertions, 50 deletions
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S index baf2d7d46b05..a439e6c7824f 100644 --- a/arch/sh/kernel/cpu/shmobile/sleep.S +++ b/arch/sh/kernel/cpu/shmobile/sleep.S | |||
@@ -16,19 +16,52 @@ | |||
16 | #include <asm/asm-offsets.h> | 16 | #include <asm/asm-offsets.h> |
17 | #include <asm/suspend.h> | 17 | #include <asm/suspend.h> |
18 | 18 | ||
19 | /* | ||
20 | * Kernel mode register usage, see entry.S: | ||
21 | * k0 scratch | ||
22 | * k1 scratch | ||
23 | * k4 scratch | ||
24 | */ | ||
25 | #define k0 r0 | ||
26 | #define k1 r1 | ||
27 | #define k4 r4 | ||
28 | |||
19 | /* manage self-refresh and enter standby mode. | 29 | /* manage self-refresh and enter standby mode. |
20 | * this code will be copied to on-chip memory and executed from there. | 30 | * this code will be copied to on-chip memory and executed from there. |
21 | */ | 31 | */ |
22 | 32 | ||
23 | .balign 4096,0,4096 | 33 | .balign 4096,0,4096 |
24 | ENTRY(sh_mobile_standby) | 34 | ENTRY(sh_mobile_standby) |
35 | |||
36 | /* save original vbr */ | ||
37 | stc vbr, r1 | ||
38 | mova saved_vbr, r0 | ||
39 | mov.l r1, @r0 | ||
40 | |||
41 | /* point vbr to our on-chip memory page */ | ||
42 | ldc r5, vbr | ||
43 | |||
44 | /* save return address */ | ||
45 | mova saved_spc, r0 | ||
46 | sts pr, r5 | ||
47 | mov.l r5, @r0 | ||
48 | |||
49 | /* save sr */ | ||
50 | mova saved_sr, r0 | ||
51 | stc sr, r5 | ||
52 | mov.l r5, @r0 | ||
53 | |||
54 | /* save mode flags */ | ||
55 | mova saved_mode, r0 | ||
56 | mov.l r4, @r0 | ||
57 | |||
58 | /* put mode flags in r0 */ | ||
25 | mov r4, r0 | 59 | mov r4, r0 |
26 | 60 | ||
27 | tst #SUSP_SH_SF, r0 | 61 | tst #SUSP_SH_SF, r0 |
28 | bt skip_set_sf | 62 | bt skip_set_sf |
29 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 | 63 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 |
30 | /* DBSC: put memory in self-refresh mode */ | 64 | /* DBSC: put memory in self-refresh mode */ |
31 | |||
32 | mov.l dben_reg, r4 | 65 | mov.l dben_reg, r4 |
33 | mov.l dben_data0, r1 | 66 | mov.l dben_data0, r1 |
34 | mov.l r1, @r4 | 67 | mov.l r1, @r4 |
@@ -60,14 +93,6 @@ ENTRY(sh_mobile_standby) | |||
60 | #endif | 93 | #endif |
61 | 94 | ||
62 | skip_set_sf: | 95 | skip_set_sf: |
63 | tst #SUSP_SH_SLEEP, r0 | ||
64 | bt test_standby | ||
65 | |||
66 | /* set mode to "sleep mode" */ | ||
67 | bra do_sleep | ||
68 | mov #0x00, r1 | ||
69 | |||
70 | test_standby: | ||
71 | tst #SUSP_SH_STANDBY, r0 | 96 | tst #SUSP_SH_STANDBY, r0 |
72 | bt test_rstandby | 97 | bt test_rstandby |
73 | 98 | ||
@@ -85,77 +110,107 @@ test_rstandby: | |||
85 | 110 | ||
86 | test_ustandby: | 111 | test_ustandby: |
87 | tst #SUSP_SH_USTANDBY, r0 | 112 | tst #SUSP_SH_USTANDBY, r0 |
88 | bt done_sleep | 113 | bt force_sleep |
89 | 114 | ||
90 | /* set mode to "u-standby mode" */ | 115 | /* set mode to "u-standby mode" */ |
91 | mov #0x10, r1 | 116 | bra do_sleep |
117 | mov #0x10, r1 | ||
92 | 118 | ||
93 | /* fall-through */ | 119 | force_sleep: |
120 | |||
121 | /* set mode to "sleep mode" */ | ||
122 | mov #0x00, r1 | ||
94 | 123 | ||
95 | do_sleep: | 124 | do_sleep: |
96 | /* setup and enter selected standby mode */ | 125 | /* setup and enter selected standby mode */ |
97 | mov.l 5f, r4 | 126 | mov.l 5f, r4 |
98 | mov.l r1, @r4 | 127 | mov.l r1, @r4 |
128 | again: | ||
99 | sleep | 129 | sleep |
130 | bra again | ||
131 | nop | ||
132 | |||
133 | restore_jump_vbr: | ||
134 | /* setup spc with return address to c code */ | ||
135 | mov.l saved_spc, k0 | ||
136 | ldc k0, spc | ||
137 | |||
138 | /* restore vbr */ | ||
139 | mov.l saved_vbr, k0 | ||
140 | ldc k0, vbr | ||
141 | |||
142 | /* setup ssr with saved sr */ | ||
143 | mov.l saved_sr, k0 | ||
144 | ldc k0, ssr | ||
145 | |||
146 | /* get mode flags */ | ||
147 | mov.l saved_mode, k0 | ||
100 | 148 | ||
101 | done_sleep: | 149 | done_sleep: |
102 | /* reset standby mode to sleep mode */ | 150 | /* reset standby mode to sleep mode */ |
103 | mov.l 5f, r4 | 151 | mov.l 5f, k4 |
104 | mov #0x00, r1 | 152 | mov #0x00, k1 |
105 | mov.l r1, @r4 | 153 | mov.l k1, @k4 |
106 | 154 | ||
107 | tst #SUSP_SH_SF, r0 | 155 | tst #SUSP_SH_SF, k0 |
108 | bt skip_restore_sf | 156 | bt skip_restore_sf |
109 | 157 | ||
110 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 | 158 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 |
111 | /* DBSC: put memory in auto-refresh mode */ | 159 | /* DBSC: put memory in auto-refresh mode */ |
160 | mov.l dbrfpdn0_reg, k4 | ||
161 | mov.l dbrfpdn0_data0, k1 | ||
162 | mov.l k1, @k4 | ||
112 | 163 | ||
113 | mov.l dbrfpdn0_reg, r4 | 164 | nop /* sleep 140 ns */ |
114 | mov.l dbrfpdn0_data0, r1 | ||
115 | mov.l r1, @r4 | ||
116 | |||
117 | /* sleep 140 ns */ | ||
118 | nop | ||
119 | nop | 165 | nop |
120 | nop | 166 | nop |
121 | nop | 167 | nop |
122 | 168 | ||
123 | mov.l dbcmdcnt_reg, r4 | 169 | mov.l dbcmdcnt_reg, k4 |
124 | mov.l dbcmdcnt_data0, r1 | 170 | mov.l dbcmdcnt_data0, k1 |
125 | mov.l r1, @r4 | 171 | mov.l k1, @k4 |
126 | 172 | ||
127 | mov.l dbcmdcnt_reg, r4 | 173 | mov.l dbcmdcnt_reg, k4 |
128 | mov.l dbcmdcnt_data1, r1 | 174 | mov.l dbcmdcnt_data1, k1 |
129 | mov.l r1, @r4 | 175 | mov.l k1, @k4 |
130 | 176 | ||
131 | mov.l dben_reg, r4 | 177 | mov.l dben_reg, k4 |
132 | mov.l dben_data1, r1 | 178 | mov.l dben_data1, k1 |
133 | mov.l r1, @r4 | 179 | mov.l k1, @k4 |
134 | 180 | ||
135 | mov.l dbrfpdn0_reg, r4 | 181 | mov.l dbrfpdn0_reg, k4 |
136 | mov.l dbrfpdn0_data2, r1 | 182 | mov.l dbrfpdn0_data2, k1 |
137 | mov.l r1, @r4 | 183 | mov.l k1, @k4 |
138 | #else | 184 | #else |
139 | /* SBSC: set auto-refresh mode */ | 185 | /* SBSC: set auto-refresh mode */ |
140 | mov.l 1f, r4 | 186 | mov.l 1f, k4 |
141 | mov.l @r4, r2 | 187 | mov.l @k4, k0 |
142 | mov.l 4f, r3 | 188 | mov.l 4f, k1 |
143 | and r3, r2 | 189 | and k1, k0 |
144 | mov.l r2, @r4 | 190 | mov.l k0, @k4 |
145 | mov.l 6f, r4 | 191 | mov.l 6f, k4 |
146 | mov.l 7f, r1 | 192 | mov.l 8f, k0 |
147 | mov.l 8f, r2 | 193 | mov.l @k4, k1 |
148 | mov.l @r4, r3 | 194 | mov #-1, k4 |
149 | mov #-1, r4 | 195 | add k4, k1 |
150 | add r4, r3 | 196 | or k1, k0 |
151 | or r2, r3 | 197 | mov.l 7f, k1 |
152 | mov.l r3, @r1 | 198 | mov.l k0, @k1 |
153 | #endif | 199 | #endif |
154 | skip_restore_sf: | 200 | skip_restore_sf: |
155 | rts | 201 | /* jump to vbr vector */ |
202 | mov.l saved_vbr, k0 | ||
203 | mov.l offset_vbr, k4 | ||
204 | add k4, k0 | ||
205 | jmp @k0 | ||
156 | nop | 206 | nop |
157 | 207 | ||
158 | .balign 4 | 208 | .balign 4 |
209 | saved_mode: .long 0 | ||
210 | saved_spc: .long 0 | ||
211 | saved_sr: .long 0 | ||
212 | saved_vbr: .long 0 | ||
213 | offset_vbr: .long 0x600 | ||
159 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 | 214 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 |
160 | dben_reg: .long 0xfd000010 /* DBEN */ | 215 | dben_reg: .long 0xfd000010 /* DBEN */ |
161 | dben_data0: .long 0 | 216 | dben_data0: .long 0 |
@@ -178,12 +233,12 @@ dbcmdcnt_data1: .long 4 | |||
178 | 7: .long 0xfe400018 /* RTCNT */ | 233 | 7: .long 0xfe400018 /* RTCNT */ |
179 | 8: .long 0xa55a0000 | 234 | 8: .long 0xa55a0000 |
180 | 235 | ||
236 | |||
181 | /* interrupt vector @ 0x600 */ | 237 | /* interrupt vector @ 0x600 */ |
182 | .balign 0x400,0,0x400 | 238 | .balign 0x400,0,0x400 |
183 | .long 0xdeadbeef | 239 | .long 0xdeadbeef |
184 | .balign 0x200,0,0x200 | 240 | .balign 0x200,0,0x200 |
185 | /* sh7722 will end up here in sleep mode */ | 241 | bra restore_jump_vbr |
186 | rte | ||
187 | nop | 242 | nop |
188 | sh_mobile_standby_end: | 243 | sh_mobile_standby_end: |
189 | 244 | ||