]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/arm/mach-at91/pm_slowclock.S
Linux 4.0-rc1
[mirror_ubuntu-bionic-kernel.git] / arch / arm / mach-at91 / pm_slowclock.S
CommitLineData
eaad2db0
AV
1/*
2 * arch/arm/mach-at91/pm_slow_clock.S
3 *
4 * Copyright (C) 2006 Savin Zlobec
5 *
6 * AT91SAM9 support:
7 * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/linkage.h>
2edb90ae 16#include <linux/clk/at91_pmc.h>
eaad2db0 17#include <mach/hardware.h>
f363c407 18#include <mach/at91_ramc.h>
eaad2db0 19
eaad2db0
AV
20/*
21 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
22 * clock during suspend by adjusting its prescalar and divisor.
23 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
24 * are errata regarding adjusting the prescalar and divisor.
25 */
26#undef SLOWDOWN_MASTER_CLOCK
27
28#define MCKRDY_TIMEOUT 1000
29#define MOSCRDY_TIMEOUT 1000
30#define PLLALOCK_TIMEOUT 1000
31#define PLLBLOCK_TIMEOUT 1000
32
8ff12ad3
JCPV
33pmc .req r0
34sdramc .req r1
35ramc1 .req r2
fb7e197b
JCPV
36memctrl .req r3
37tmp1 .req r4
38tmp2 .req r5
eaad2db0
AV
39
40/*
41 * Wait until master clock is ready (after switching master clock source)
42 */
43 .macro wait_mckrdy
0dcfed14
JCPV
44 mov tmp2, #MCKRDY_TIMEOUT
451: sub tmp2, tmp2, #1
46 cmp tmp2, #0
eaad2db0 47 beq 2f
b5514952 48 ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 49 tst tmp1, #AT91_PMC_MCKRDY
eaad2db0
AV
50 beq 1b
512:
52 .endm
53
54/*
55 * Wait until master oscillator has stabilized.
56 */
57 .macro wait_moscrdy
0dcfed14
JCPV
58 mov tmp2, #MOSCRDY_TIMEOUT
591: sub tmp2, tmp2, #1
60 cmp tmp2, #0
eaad2db0 61 beq 2f
b5514952 62 ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 63 tst tmp1, #AT91_PMC_MOSCS
eaad2db0
AV
64 beq 1b
652:
66 .endm
67
68/*
69 * Wait until PLLA has locked.
70 */
71 .macro wait_pllalock
0dcfed14
JCPV
72 mov tmp2, #PLLALOCK_TIMEOUT
731: sub tmp2, tmp2, #1
74 cmp tmp2, #0
eaad2db0 75 beq 2f
b5514952 76 ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 77 tst tmp1, #AT91_PMC_LOCKA
eaad2db0
AV
78 beq 1b
792:
80 .endm
81
82/*
83 * Wait until PLLB has locked.
84 */
85 .macro wait_pllblock
0dcfed14
JCPV
86 mov tmp2, #PLLBLOCK_TIMEOUT
871: sub tmp2, tmp2, #1
88 cmp tmp2, #0
eaad2db0 89 beq 2f
b5514952 90 ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 91 tst tmp1, #AT91_PMC_LOCKB
eaad2db0
AV
92 beq 1b
932:
94 .endm
95
96 .text
97
fb7e197b
JCPV
98/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
99 * void __iomem *ramc1, int memctrl)
100 */
eaad2db0
AV
101ENTRY(at91_slow_clock)
102 /* Save registers on stack */
fb7e197b 103 stmfd sp!, {r4 - r12, lr}
eaad2db0
AV
104
105 /*
106 * Register usage:
8ff12ad3
JCPV
107 * R0 = Base address of AT91_PMC
108 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
109 * R2 = Base address of second RAM Controller or 0 if not present
fb7e197b 110 * R3 = Memory controller
eaad2db0 111 * R4 = temporary register
fb7e197b 112 * R5 = temporary register
eaad2db0 113 */
eaad2db0
AV
114
115 /* Drain write buffer */
0dcfed14
JCPV
116 mov tmp1, #0
117 mcr p15, 0, tmp1, c7, c10, 4
eaad2db0 118
fb7e197b
JCPV
119 cmp memctrl, #AT91_MEMCTRL_MC
120 bne ddr_sr_enable
121
122 /*
123 * at91rm9200 Memory controller
124 */
eaad2db0 125 /* Put SDRAM in self-refresh mode */
0dcfed14 126 mov tmp1, #1
1a269ade 127 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
fb7e197b
JCPV
128 b sdr_sr_done
129
130 /*
131 * DDRSDR Memory controller
132 */
133ddr_sr_enable:
134 cmp memctrl, #AT91_MEMCTRL_DDRSDR
135 bne sdr_sr_enable
eaad2db0 136
7dca3343 137 /* prepare for DDRAM self-refresh mode */
0dcfed14
JCPV
138 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
139 str tmp1, .saved_sam9_lpr
140 bic tmp1, #AT91_DDRSDRC_LPCB
141 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
7dca3343
NF
142
143 /* figure out if we use the second ram controller */
0dcfed14
JCPV
144 cmp ramc1, #0
145 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
146 strne tmp2, .saved_sam9_lpr1
147 bicne tmp2, #AT91_DDRSDRC_LPCB
148 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
7dca3343
NF
149
150 /* Enable DDRAM self-refresh mode */
0dcfed14
JCPV
151 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
152 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
fb7e197b
JCPV
153
154 b sdr_sr_done
155
156 /*
157 * SDRAMC Memory controller
158 */
159sdr_sr_enable:
eaad2db0 160 /* Enable SDRAM self-refresh mode */
0dcfed14
JCPV
161 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
162 str tmp1, .saved_sam9_lpr
eaad2db0 163
0dcfed14
JCPV
164 bic tmp1, #AT91_SDRAMC_LPCB
165 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
166 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
eaad2db0 167
fb7e197b 168sdr_sr_done:
eaad2db0 169 /* Save Master clock setting */
b5514952 170 ldr tmp1, [pmc, #AT91_PMC_MCKR]
0dcfed14 171 str tmp1, .saved_mckr
eaad2db0
AV
172
173 /*
174 * Set the Master clock source to slow clock
175 */
0dcfed14 176 bic tmp1, tmp1, #AT91_PMC_CSS
b5514952 177 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
178
179 wait_mckrdy
180
181#ifdef SLOWDOWN_MASTER_CLOCK
182 /*
183 * Set the Master Clock PRES and MDIV fields.
184 *
185 * See AT91RM9200 errata #27 and #28 for details.
186 */
0dcfed14 187 mov tmp1, #0
b5514952 188 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
189
190 wait_mckrdy
191#endif
192
193 /* Save PLLA setting and disable it */
b5514952 194 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
0dcfed14 195 str tmp1, .saved_pllar
eaad2db0 196
0dcfed14
JCPV
197 mov tmp1, #AT91_PMC_PLLCOUNT
198 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
b5514952 199 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 200
eaad2db0 201 /* Save PLLB setting and disable it */
b5514952 202 ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
0dcfed14 203 str tmp1, .saved_pllbr
eaad2db0 204
0dcfed14 205 mov tmp1, #AT91_PMC_PLLCOUNT
b5514952 206 str tmp1, [pmc, #AT91_CKGR_PLLBR]
eaad2db0 207
eaad2db0 208 /* Turn off the main oscillator */
b5514952 209 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 210 bic tmp1, tmp1, #AT91_PMC_MOSCEN
b5514952 211 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
212
213 /* Wait for interrupt */
0dcfed14 214 mcr p15, 0, tmp1, c7, c0, 4
eaad2db0
AV
215
216 /* Turn on the main oscillator */
b5514952 217 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 218 orr tmp1, tmp1, #AT91_PMC_MOSCEN
b5514952 219 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
220
221 wait_moscrdy
222
223 /* Restore PLLB setting */
0dcfed14 224 ldr tmp1, .saved_pllbr
b5514952 225 str tmp1, [pmc, #AT91_CKGR_PLLBR]
eaad2db0 226
0dcfed14 227 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 228 bne 1f
0dcfed14 229 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
230 beq 2f
2311:
eaad2db0 232 wait_pllblock
9823f1a8 2332:
eaad2db0
AV
234
235 /* Restore PLLA setting */
0dcfed14 236 ldr tmp1, .saved_pllar
b5514952 237 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 238
0dcfed14 239 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 240 bne 3f
0dcfed14 241 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
242 beq 4f
2433:
eaad2db0 244 wait_pllalock
9823f1a8 2454:
eaad2db0
AV
246
247#ifdef SLOWDOWN_MASTER_CLOCK
248 /*
249 * First set PRES if it was not 0,
250 * than set CSS and MDIV fields.
251 *
252 * See AT91RM9200 errata #27 and #28 for details.
253 */
0dcfed14
JCPV
254 ldr tmp1, .saved_mckr
255 tst tmp1, #AT91_PMC_PRES
eaad2db0 256 beq 2f
0dcfed14 257 and tmp1, tmp1, #AT91_PMC_PRES
b5514952 258 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
259
260 wait_mckrdy
261#endif
262
263 /*
264 * Restore master clock setting
265 */
0dcfed14 2662: ldr tmp1, .saved_mckr
b5514952 267 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
268
269 wait_mckrdy
270
fb7e197b
JCPV
271 /*
272 * at91rm9200 Memory controller
273 * Do nothing - self-refresh is automatically disabled.
274 */
275 cmp memctrl, #AT91_MEMCTRL_MC
276 beq ram_restored
277
278 /*
279 * DDRSDR Memory controller
280 */
281 cmp memctrl, #AT91_MEMCTRL_DDRSDR
282 bne sdr_en_restore
7dca3343 283 /* Restore LPR on AT91 with DDRAM */
0dcfed14
JCPV
284 ldr tmp1, .saved_sam9_lpr
285 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
7dca3343
NF
286
287 /* if we use the second ram controller */
0dcfed14
JCPV
288 cmp ramc1, #0
289 ldrne tmp2, .saved_sam9_lpr1
290 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
7dca3343 291
fb7e197b
JCPV
292 b ram_restored
293
294 /*
295 * SDRAMC Memory controller
296 */
297sdr_en_restore:
7dca3343 298 /* Restore LPR on AT91 with SDRAM */
0dcfed14
JCPV
299 ldr tmp1, .saved_sam9_lpr
300 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
eaad2db0 301
fb7e197b 302ram_restored:
eaad2db0 303 /* Restore registers, and return */
fb7e197b 304 ldmfd sp!, {r4 - r12, pc}
eaad2db0
AV
305
306
307.saved_mckr:
308 .word 0
309
310.saved_pllar:
311 .word 0
312
313.saved_pllbr:
314 .word 0
315
316.saved_sam9_lpr:
317 .word 0
318
7dca3343
NF
319.saved_sam9_lpr1:
320 .word 0
321
eaad2db0
AV
322ENTRY(at91_slow_clock_sz)
323 .word .-at91_slow_clock