diff options
Diffstat (limited to 'arch/arm/mach-at91/pm_slowclock.S')
-rw-r--r-- | arch/arm/mach-at91/pm_slowclock.S | 275 |
1 files changed, 141 insertions, 134 deletions
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 92dfb8461392..db5452123f17 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S | |||
@@ -15,15 +15,7 @@ | |||
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
17 | #include <mach/at91_pmc.h> | 17 | #include <mach/at91_pmc.h> |
18 | 18 | #include <mach/at91_ramc.h> | |
19 | #if defined(CONFIG_ARCH_AT91RM9200) | ||
20 | #include <mach/at91rm9200_mc.h> | ||
21 | #elif defined(CONFIG_ARCH_AT91CAP9) \ | ||
22 | || defined(CONFIG_ARCH_AT91SAM9G45) | ||
23 | #include <mach/at91sam9_ddrsdr.h> | ||
24 | #else | ||
25 | #include <mach/at91sam9_sdramc.h> | ||
26 | #endif | ||
27 | 19 | ||
28 | 20 | ||
29 | #ifdef CONFIG_ARCH_AT91SAM9263 | 21 | #ifdef CONFIG_ARCH_AT91SAM9263 |
@@ -47,17 +39,23 @@ | |||
47 | #define PLLALOCK_TIMEOUT 1000 | 39 | #define PLLALOCK_TIMEOUT 1000 |
48 | #define PLLBLOCK_TIMEOUT 1000 | 40 | #define PLLBLOCK_TIMEOUT 1000 |
49 | 41 | ||
42 | pmc .req r0 | ||
43 | sdramc .req r1 | ||
44 | ramc1 .req r2 | ||
45 | memctrl .req r3 | ||
46 | tmp1 .req r4 | ||
47 | tmp2 .req r5 | ||
50 | 48 | ||
51 | /* | 49 | /* |
52 | * Wait until master clock is ready (after switching master clock source) | 50 | * Wait until master clock is ready (after switching master clock source) |
53 | */ | 51 | */ |
54 | .macro wait_mckrdy | 52 | .macro wait_mckrdy |
55 | mov r4, #MCKRDY_TIMEOUT | 53 | mov tmp2, #MCKRDY_TIMEOUT |
56 | 1: sub r4, r4, #1 | 54 | 1: sub tmp2, tmp2, #1 |
57 | cmp r4, #0 | 55 | cmp tmp2, #0 |
58 | beq 2f | 56 | beq 2f |
59 | ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] | 57 | ldr tmp1, [pmc, #AT91_PMC_SR] |
60 | tst r3, #AT91_PMC_MCKRDY | 58 | tst tmp1, #AT91_PMC_MCKRDY |
61 | beq 1b | 59 | beq 1b |
62 | 2: | 60 | 2: |
63 | .endm | 61 | .endm |
@@ -66,12 +64,12 @@ | |||
66 | * Wait until master oscillator has stabilized. | 64 | * Wait until master oscillator has stabilized. |
67 | */ | 65 | */ |
68 | .macro wait_moscrdy | 66 | .macro wait_moscrdy |
69 | mov r4, #MOSCRDY_TIMEOUT | 67 | mov tmp2, #MOSCRDY_TIMEOUT |
70 | 1: sub r4, r4, #1 | 68 | 1: sub tmp2, tmp2, #1 |
71 | cmp r4, #0 | 69 | cmp tmp2, #0 |
72 | beq 2f | 70 | beq 2f |
73 | ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] | 71 | ldr tmp1, [pmc, #AT91_PMC_SR] |
74 | tst r3, #AT91_PMC_MOSCS | 72 | tst tmp1, #AT91_PMC_MOSCS |
75 | beq 1b | 73 | beq 1b |
76 | 2: | 74 | 2: |
77 | .endm | 75 | .endm |
@@ -80,12 +78,12 @@ | |||
80 | * Wait until PLLA has locked. | 78 | * Wait until PLLA has locked. |
81 | */ | 79 | */ |
82 | .macro wait_pllalock | 80 | .macro wait_pllalock |
83 | mov r4, #PLLALOCK_TIMEOUT | 81 | mov tmp2, #PLLALOCK_TIMEOUT |
84 | 1: sub r4, r4, #1 | 82 | 1: sub tmp2, tmp2, #1 |
85 | cmp r4, #0 | 83 | cmp tmp2, #0 |
86 | beq 2f | 84 | beq 2f |
87 | ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] | 85 | ldr tmp1, [pmc, #AT91_PMC_SR] |
88 | tst r3, #AT91_PMC_LOCKA | 86 | tst tmp1, #AT91_PMC_LOCKA |
89 | beq 1b | 87 | beq 1b |
90 | 2: | 88 | 2: |
91 | .endm | 89 | .endm |
@@ -94,80 +92,98 @@ | |||
94 | * Wait until PLLB has locked. | 92 | * Wait until PLLB has locked. |
95 | */ | 93 | */ |
96 | .macro wait_pllblock | 94 | .macro wait_pllblock |
97 | mov r4, #PLLBLOCK_TIMEOUT | 95 | mov tmp2, #PLLBLOCK_TIMEOUT |
98 | 1: sub r4, r4, #1 | 96 | 1: sub tmp2, tmp2, #1 |
99 | cmp r4, #0 | 97 | cmp tmp2, #0 |
100 | beq 2f | 98 | beq 2f |
101 | ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] | 99 | ldr tmp1, [pmc, #AT91_PMC_SR] |
102 | tst r3, #AT91_PMC_LOCKB | 100 | tst tmp1, #AT91_PMC_LOCKB |
103 | beq 1b | 101 | beq 1b |
104 | 2: | 102 | 2: |
105 | .endm | 103 | .endm |
106 | 104 | ||
107 | .text | 105 | .text |
108 | 106 | ||
107 | /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, | ||
108 | * void __iomem *ramc1, int memctrl) | ||
109 | */ | ||
109 | ENTRY(at91_slow_clock) | 110 | ENTRY(at91_slow_clock) |
110 | /* Save registers on stack */ | 111 | /* Save registers on stack */ |
111 | stmfd sp!, {r0 - r12, lr} | 112 | stmfd sp!, {r4 - r12, lr} |
112 | 113 | ||
113 | /* | 114 | /* |
114 | * Register usage: | 115 | * Register usage: |
115 | * R1 = Base address of AT91_PMC | 116 | * R0 = Base address of AT91_PMC |
116 | * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) | 117 | * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) |
117 | * R3 = temporary register | 118 | * R2 = Base address of second RAM Controller or 0 if not present |
119 | * R3 = Memory controller | ||
118 | * R4 = temporary register | 120 | * R4 = temporary register |
119 | * R5 = Base address of second RAM Controller or 0 if not present | 121 | * R5 = temporary register |
120 | */ | 122 | */ |
121 | ldr r1, .at91_va_base_pmc | ||
122 | ldr r2, .at91_va_base_sdramc | ||
123 | ldr r5, .at91_va_base_ramc1 | ||
124 | 123 | ||
125 | /* Drain write buffer */ | 124 | /* Drain write buffer */ |
126 | mov r0, #0 | 125 | mov tmp1, #0 |
127 | mcr p15, 0, r0, c7, c10, 4 | 126 | mcr p15, 0, tmp1, c7, c10, 4 |
127 | |||
128 | cmp memctrl, #AT91_MEMCTRL_MC | ||
129 | bne ddr_sr_enable | ||
128 | 130 | ||
129 | #ifdef CONFIG_ARCH_AT91RM9200 | 131 | /* |
132 | * at91rm9200 Memory controller | ||
133 | */ | ||
130 | /* Put SDRAM in self-refresh mode */ | 134 | /* Put SDRAM in self-refresh mode */ |
131 | mov r3, #1 | 135 | mov tmp1, #1 |
132 | str r3, [r2, #AT91_SDRAMC_SRR] | 136 | str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] |
133 | #elif defined(CONFIG_ARCH_AT91CAP9) \ | 137 | b sdr_sr_done |
134 | || defined(CONFIG_ARCH_AT91SAM9G45) | 138 | |
139 | /* | ||
140 | * DDRSDR Memory controller | ||
141 | */ | ||
142 | ddr_sr_enable: | ||
143 | cmp memctrl, #AT91_MEMCTRL_DDRSDR | ||
144 | bne sdr_sr_enable | ||
135 | 145 | ||
136 | /* prepare for DDRAM self-refresh mode */ | 146 | /* prepare for DDRAM self-refresh mode */ |
137 | ldr r3, [r2, #AT91_DDRSDRC_LPR] | 147 | ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
138 | str r3, .saved_sam9_lpr | 148 | str tmp1, .saved_sam9_lpr |
139 | bic r3, #AT91_DDRSDRC_LPCB | 149 | bic tmp1, #AT91_DDRSDRC_LPCB |
140 | orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH | 150 | orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH |
141 | 151 | ||
142 | /* figure out if we use the second ram controller */ | 152 | /* figure out if we use the second ram controller */ |
143 | cmp r5, #0 | 153 | cmp ramc1, #0 |
144 | ldrne r4, [r5, #AT91_DDRSDRC_LPR] | 154 | ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
145 | strne r4, .saved_sam9_lpr1 | 155 | strne tmp2, .saved_sam9_lpr1 |
146 | bicne r4, #AT91_DDRSDRC_LPCB | 156 | bicne tmp2, #AT91_DDRSDRC_LPCB |
147 | orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH | 157 | orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH |
148 | 158 | ||
149 | /* Enable DDRAM self-refresh mode */ | 159 | /* Enable DDRAM self-refresh mode */ |
150 | str r3, [r2, #AT91_DDRSDRC_LPR] | 160 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
151 | strne r4, [r5, #AT91_DDRSDRC_LPR] | 161 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
152 | #else | 162 | |
163 | b sdr_sr_done | ||
164 | |||
165 | /* | ||
166 | * SDRAMC Memory controller | ||
167 | */ | ||
168 | sdr_sr_enable: | ||
153 | /* Enable SDRAM self-refresh mode */ | 169 | /* Enable SDRAM self-refresh mode */ |
154 | ldr r3, [r2, #AT91_SDRAMC_LPR] | 170 | ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] |
155 | str r3, .saved_sam9_lpr | 171 | str tmp1, .saved_sam9_lpr |
156 | 172 | ||
157 | bic r3, #AT91_SDRAMC_LPCB | 173 | bic tmp1, #AT91_SDRAMC_LPCB |
158 | orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH | 174 | orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH |
159 | str r3, [r2, #AT91_SDRAMC_LPR] | 175 | str tmp1, [sdramc, #AT91_SDRAMC_LPR] |
160 | #endif | ||
161 | 176 | ||
177 | sdr_sr_done: | ||
162 | /* Save Master clock setting */ | 178 | /* Save Master clock setting */ |
163 | ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] | 179 | ldr tmp1, [pmc, #AT91_PMC_MCKR] |
164 | str r3, .saved_mckr | 180 | str tmp1, .saved_mckr |
165 | 181 | ||
166 | /* | 182 | /* |
167 | * Set the Master clock source to slow clock | 183 | * Set the Master clock source to slow clock |
168 | */ | 184 | */ |
169 | bic r3, r3, #AT91_PMC_CSS | 185 | bic tmp1, tmp1, #AT91_PMC_CSS |
170 | str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] | 186 | str tmp1, [pmc, #AT91_PMC_MCKR] |
171 | 187 | ||
172 | wait_mckrdy | 188 | wait_mckrdy |
173 | 189 | ||
@@ -177,61 +193,61 @@ ENTRY(at91_slow_clock) | |||
177 | * | 193 | * |
178 | * See AT91RM9200 errata #27 and #28 for details. | 194 | * See AT91RM9200 errata #27 and #28 for details. |
179 | */ | 195 | */ |
180 | mov r3, #0 | 196 | mov tmp1, #0 |
181 | str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] | 197 | str tmp1, [pmc, #AT91_PMC_MCKR] |
182 | 198 | ||
183 | wait_mckrdy | 199 | wait_mckrdy |
184 | #endif | 200 | #endif |
185 | 201 | ||
186 | /* Save PLLA setting and disable it */ | 202 | /* Save PLLA setting and disable it */ |
187 | ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] | 203 | ldr tmp1, [pmc, #AT91_CKGR_PLLAR] |
188 | str r3, .saved_pllar | 204 | str tmp1, .saved_pllar |
189 | 205 | ||
190 | mov r3, #AT91_PMC_PLLCOUNT | 206 | mov tmp1, #AT91_PMC_PLLCOUNT |
191 | orr r3, r3, #(1 << 29) /* bit 29 always set */ | 207 | orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ |
192 | str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] | 208 | str tmp1, [pmc, #AT91_CKGR_PLLAR] |
193 | 209 | ||
194 | /* Save PLLB setting and disable it */ | 210 | /* Save PLLB setting and disable it */ |
195 | ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] | 211 | ldr tmp1, [pmc, #AT91_CKGR_PLLBR] |
196 | str r3, .saved_pllbr | 212 | str tmp1, .saved_pllbr |
197 | 213 | ||
198 | mov r3, #AT91_PMC_PLLCOUNT | 214 | mov tmp1, #AT91_PMC_PLLCOUNT |
199 | str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] | 215 | str tmp1, [pmc, #AT91_CKGR_PLLBR] |
200 | 216 | ||
201 | /* Turn off the main oscillator */ | 217 | /* Turn off the main oscillator */ |
202 | ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] | 218 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
203 | bic r3, r3, #AT91_PMC_MOSCEN | 219 | bic tmp1, tmp1, #AT91_PMC_MOSCEN |
204 | str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] | 220 | str tmp1, [pmc, #AT91_CKGR_MOR] |
205 | 221 | ||
206 | /* Wait for interrupt */ | 222 | /* Wait for interrupt */ |
207 | mcr p15, 0, r0, c7, c0, 4 | 223 | mcr p15, 0, tmp1, c7, c0, 4 |
208 | 224 | ||
209 | /* Turn on the main oscillator */ | 225 | /* Turn on the main oscillator */ |
210 | ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] | 226 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
211 | orr r3, r3, #AT91_PMC_MOSCEN | 227 | orr tmp1, tmp1, #AT91_PMC_MOSCEN |
212 | str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] | 228 | str tmp1, [pmc, #AT91_CKGR_MOR] |
213 | 229 | ||
214 | wait_moscrdy | 230 | wait_moscrdy |
215 | 231 | ||
216 | /* Restore PLLB setting */ | 232 | /* Restore PLLB setting */ |
217 | ldr r3, .saved_pllbr | 233 | ldr tmp1, .saved_pllbr |
218 | str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] | 234 | str tmp1, [pmc, #AT91_CKGR_PLLBR] |
219 | 235 | ||
220 | tst r3, #(AT91_PMC_MUL & 0xff0000) | 236 | tst tmp1, #(AT91_PMC_MUL & 0xff0000) |
221 | bne 1f | 237 | bne 1f |
222 | tst r3, #(AT91_PMC_MUL & ~0xff0000) | 238 | tst tmp1, #(AT91_PMC_MUL & ~0xff0000) |
223 | beq 2f | 239 | beq 2f |
224 | 1: | 240 | 1: |
225 | wait_pllblock | 241 | wait_pllblock |
226 | 2: | 242 | 2: |
227 | 243 | ||
228 | /* Restore PLLA setting */ | 244 | /* Restore PLLA setting */ |
229 | ldr r3, .saved_pllar | 245 | ldr tmp1, .saved_pllar |
230 | str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] | 246 | str tmp1, [pmc, #AT91_CKGR_PLLAR] |
231 | 247 | ||
232 | tst r3, #(AT91_PMC_MUL & 0xff0000) | 248 | tst tmp1, #(AT91_PMC_MUL & 0xff0000) |
233 | bne 3f | 249 | bne 3f |
234 | tst r3, #(AT91_PMC_MUL & ~0xff0000) | 250 | tst tmp1, #(AT91_PMC_MUL & ~0xff0000) |
235 | beq 4f | 251 | beq 4f |
236 | 3: | 252 | 3: |
237 | wait_pllalock | 253 | wait_pllalock |
@@ -244,11 +260,11 @@ ENTRY(at91_slow_clock) | |||
244 | * | 260 | * |
245 | * See AT91RM9200 errata #27 and #28 for details. | 261 | * See AT91RM9200 errata #27 and #28 for details. |
246 | */ | 262 | */ |
247 | ldr r3, .saved_mckr | 263 | ldr tmp1, .saved_mckr |
248 | tst r3, #AT91_PMC_PRES | 264 | tst tmp1, #AT91_PMC_PRES |
249 | beq 2f | 265 | beq 2f |
250 | and r3, r3, #AT91_PMC_PRES | 266 | and tmp1, tmp1, #AT91_PMC_PRES |
251 | str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] | 267 | str tmp1, [pmc, #AT91_PMC_MCKR] |
252 | 268 | ||
253 | wait_mckrdy | 269 | wait_mckrdy |
254 | #endif | 270 | #endif |
@@ -256,32 +272,45 @@ ENTRY(at91_slow_clock) | |||
256 | /* | 272 | /* |
257 | * Restore master clock setting | 273 | * Restore master clock setting |
258 | */ | 274 | */ |
259 | 2: ldr r3, .saved_mckr | 275 | 2: ldr tmp1, .saved_mckr |
260 | str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] | 276 | str tmp1, [pmc, #AT91_PMC_MCKR] |
261 | 277 | ||
262 | wait_mckrdy | 278 | wait_mckrdy |
263 | 279 | ||
264 | #ifdef CONFIG_ARCH_AT91RM9200 | 280 | /* |
265 | /* Do nothing - self-refresh is automatically disabled. */ | 281 | * at91rm9200 Memory controller |
266 | #elif defined(CONFIG_ARCH_AT91CAP9) \ | 282 | * Do nothing - self-refresh is automatically disabled. |
267 | || defined(CONFIG_ARCH_AT91SAM9G45) | 283 | */ |
284 | cmp memctrl, #AT91_MEMCTRL_MC | ||
285 | beq ram_restored | ||
286 | |||
287 | /* | ||
288 | * DDRSDR Memory controller | ||
289 | */ | ||
290 | cmp memctrl, #AT91_MEMCTRL_DDRSDR | ||
291 | bne sdr_en_restore | ||
268 | /* Restore LPR on AT91 with DDRAM */ | 292 | /* Restore LPR on AT91 with DDRAM */ |
269 | ldr r3, .saved_sam9_lpr | 293 | ldr tmp1, .saved_sam9_lpr |
270 | str r3, [r2, #AT91_DDRSDRC_LPR] | 294 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
271 | 295 | ||
272 | /* if we use the second ram controller */ | 296 | /* if we use the second ram controller */ |
273 | cmp r5, #0 | 297 | cmp ramc1, #0 |
274 | ldrne r4, .saved_sam9_lpr1 | 298 | ldrne tmp2, .saved_sam9_lpr1 |
275 | strne r4, [r5, #AT91_DDRSDRC_LPR] | 299 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
300 | |||
301 | b ram_restored | ||
276 | 302 | ||
277 | #else | 303 | /* |
304 | * SDRAMC Memory controller | ||
305 | */ | ||
306 | sdr_en_restore: | ||
278 | /* Restore LPR on AT91 with SDRAM */ | 307 | /* Restore LPR on AT91 with SDRAM */ |
279 | ldr r3, .saved_sam9_lpr | 308 | ldr tmp1, .saved_sam9_lpr |
280 | str r3, [r2, #AT91_SDRAMC_LPR] | 309 | str tmp1, [sdramc, #AT91_SDRAMC_LPR] |
281 | #endif | ||
282 | 310 | ||
311 | ram_restored: | ||
283 | /* Restore registers, and return */ | 312 | /* Restore registers, and return */ |
284 | ldmfd sp!, {r0 - r12, pc} | 313 | ldmfd sp!, {r4 - r12, pc} |
285 | 314 | ||
286 | 315 | ||
287 | .saved_mckr: | 316 | .saved_mckr: |
@@ -299,27 +328,5 @@ ENTRY(at91_slow_clock) | |||
299 | .saved_sam9_lpr1: | 328 | .saved_sam9_lpr1: |
300 | .word 0 | 329 | .word 0 |
301 | 330 | ||
302 | .at91_va_base_pmc: | ||
303 | .word AT91_VA_BASE_SYS + AT91_PMC | ||
304 | |||
305 | #ifdef CONFIG_ARCH_AT91RM9200 | ||
306 | .at91_va_base_sdramc: | ||
307 | .word AT91_VA_BASE_SYS | ||
308 | #elif defined(CONFIG_ARCH_AT91CAP9) \ | ||
309 | || defined(CONFIG_ARCH_AT91SAM9G45) | ||
310 | .at91_va_base_sdramc: | ||
311 | .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 | ||
312 | #else | ||
313 | .at91_va_base_sdramc: | ||
314 | .word AT91_VA_BASE_SYS + AT91_SDRAMC0 | ||
315 | #endif | ||
316 | |||
317 | .at91_va_base_ramc1: | ||
318 | #if defined(CONFIG_ARCH_AT91SAM9G45) | ||
319 | .word AT91_VA_BASE_SYS + AT91_DDRSDRC1 | ||
320 | #else | ||
321 | .word 0 | ||
322 | #endif | ||
323 | |||
324 | ENTRY(at91_slow_clock_sz) | 331 | ENTRY(at91_slow_clock_sz) |
325 | .word .-at91_slow_clock | 332 | .word .-at91_slow_clock |