Merge tag 'for-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux...
[deliverable/linux.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
8ff12ad3
JCPV
28pmc .req r0
29sdramc .req r1
30ramc1 .req r2
fb7e197b
JCPV
31memctrl .req r3
32tmp1 .req r4
33tmp2 .req r5
eaad2db0
AV
34
35/*
36 * Wait until master clock is ready (after switching master clock source)
37 */
38 .macro wait_mckrdy
ad4a38d2 391: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 40 tst tmp1, #AT91_PMC_MCKRDY
eaad2db0 41 beq 1b
eaad2db0
AV
42 .endm
43
44/*
45 * Wait until master oscillator has stabilized.
46 */
47 .macro wait_moscrdy
ad4a38d2 481: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 49 tst tmp1, #AT91_PMC_MOSCS
eaad2db0 50 beq 1b
eaad2db0
AV
51 .endm
52
53/*
54 * Wait until PLLA has locked.
55 */
56 .macro wait_pllalock
ad4a38d2 571: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 58 tst tmp1, #AT91_PMC_LOCKA
eaad2db0 59 beq 1b
eaad2db0
AV
60 .endm
61
62/*
63 * Wait until PLLB has locked.
64 */
65 .macro wait_pllblock
ad4a38d2 661: ldr tmp1, [pmc, #AT91_PMC_SR]
0dcfed14 67 tst tmp1, #AT91_PMC_LOCKB
eaad2db0 68 beq 1b
eaad2db0
AV
69 .endm
70
71 .text
72
e7b848d7
WY
73 .arm
74
fb7e197b
JCPV
75/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
76 * void __iomem *ramc1, int memctrl)
77 */
eaad2db0
AV
78ENTRY(at91_slow_clock)
79 /* Save registers on stack */
fb7e197b 80 stmfd sp!, {r4 - r12, lr}
eaad2db0
AV
81
82 /*
83 * Register usage:
8ff12ad3
JCPV
84 * R0 = Base address of AT91_PMC
85 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
86 * R2 = Base address of second RAM Controller or 0 if not present
fb7e197b 87 * R3 = Memory controller
eaad2db0 88 * R4 = temporary register
fb7e197b 89 * R5 = temporary register
eaad2db0 90 */
eaad2db0
AV
91
92 /* Drain write buffer */
0dcfed14
JCPV
93 mov tmp1, #0
94 mcr p15, 0, tmp1, c7, c10, 4
eaad2db0 95
fb7e197b
JCPV
96 cmp memctrl, #AT91_MEMCTRL_MC
97 bne ddr_sr_enable
98
99 /*
100 * at91rm9200 Memory controller
101 */
eaad2db0 102 /* Put SDRAM in self-refresh mode */
0dcfed14 103 mov tmp1, #1
1a269ade 104 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
fb7e197b
JCPV
105 b sdr_sr_done
106
107 /*
108 * DDRSDR Memory controller
109 */
110ddr_sr_enable:
111 cmp memctrl, #AT91_MEMCTRL_DDRSDR
112 bne sdr_sr_enable
eaad2db0 113
02f513a0
PR
114 /* LPDDR1 --> force DDR2 mode during self-refresh */
115 ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR]
116 str tmp1, .saved_sam9_mdr
117 bic tmp1, tmp1, #~AT91_DDRSDRC_MD
118 cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
119 ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
120 biceq tmp1, tmp1, #AT91_DDRSDRC_MD
121 orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
122 streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
123
7dca3343 124 /* prepare for DDRAM self-refresh mode */
0dcfed14
JCPV
125 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
126 str tmp1, .saved_sam9_lpr
127 bic tmp1, #AT91_DDRSDRC_LPCB
128 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
7dca3343
NF
129
130 /* figure out if we use the second ram controller */
0dcfed14 131 cmp ramc1, #0
02f513a0
PR
132 beq ddr_no_2nd_ctrl
133
134 ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
135 str tmp2, .saved_sam9_mdr1
136 bic tmp2, tmp2, #~AT91_DDRSDRC_MD
137 cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
138 ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
139 biceq tmp2, tmp2, #AT91_DDRSDRC_MD
140 orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
141 streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
142
143 ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
144 str tmp2, .saved_sam9_lpr1
145 bic tmp2, #AT91_DDRSDRC_LPCB
146 orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
7dca3343
NF
147
148 /* Enable DDRAM self-refresh mode */
02f513a0
PR
149 str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
150ddr_no_2nd_ctrl:
0dcfed14 151 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
fb7e197b
JCPV
152
153 b sdr_sr_done
154
155 /*
156 * SDRAMC Memory controller
157 */
158sdr_sr_enable:
eaad2db0 159 /* Enable SDRAM self-refresh mode */
0dcfed14
JCPV
160 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
161 str tmp1, .saved_sam9_lpr
eaad2db0 162
0dcfed14
JCPV
163 bic tmp1, #AT91_SDRAMC_LPCB
164 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
165 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
eaad2db0 166
fb7e197b 167sdr_sr_done:
eaad2db0 168 /* Save Master clock setting */
b5514952 169 ldr tmp1, [pmc, #AT91_PMC_MCKR]
0dcfed14 170 str tmp1, .saved_mckr
eaad2db0
AV
171
172 /*
173 * Set the Master clock source to slow clock
174 */
0dcfed14 175 bic tmp1, tmp1, #AT91_PMC_CSS
b5514952 176 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
177
178 wait_mckrdy
179
180#ifdef SLOWDOWN_MASTER_CLOCK
181 /*
182 * Set the Master Clock PRES and MDIV fields.
183 *
184 * See AT91RM9200 errata #27 and #28 for details.
185 */
0dcfed14 186 mov tmp1, #0
b5514952 187 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
188
189 wait_mckrdy
190#endif
191
192 /* Save PLLA setting and disable it */
b5514952 193 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
0dcfed14 194 str tmp1, .saved_pllar
eaad2db0 195
0dcfed14
JCPV
196 mov tmp1, #AT91_PMC_PLLCOUNT
197 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
b5514952 198 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 199
eaad2db0 200 /* Save PLLB setting and disable it */
b5514952 201 ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
0dcfed14 202 str tmp1, .saved_pllbr
eaad2db0 203
0dcfed14 204 mov tmp1, #AT91_PMC_PLLCOUNT
b5514952 205 str tmp1, [pmc, #AT91_CKGR_PLLBR]
eaad2db0 206
eaad2db0 207 /* Turn off the main oscillator */
b5514952 208 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 209 bic tmp1, tmp1, #AT91_PMC_MOSCEN
5957457a 210 orr tmp1, tmp1, #AT91_PMC_KEY
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
5957457a 219 orr tmp1, tmp1, #AT91_PMC_KEY
b5514952 220 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
221
222 wait_moscrdy
223
224 /* Restore PLLB setting */
0dcfed14 225 ldr tmp1, .saved_pllbr
b5514952 226 str tmp1, [pmc, #AT91_CKGR_PLLBR]
eaad2db0 227
0dcfed14 228 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 229 bne 1f
0dcfed14 230 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
231 beq 2f
2321:
eaad2db0 233 wait_pllblock
9823f1a8 2342:
eaad2db0
AV
235
236 /* Restore PLLA setting */
0dcfed14 237 ldr tmp1, .saved_pllar
b5514952 238 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 239
0dcfed14 240 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 241 bne 3f
0dcfed14 242 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
243 beq 4f
2443:
eaad2db0 245 wait_pllalock
9823f1a8 2464:
eaad2db0
AV
247
248#ifdef SLOWDOWN_MASTER_CLOCK
249 /*
250 * First set PRES if it was not 0,
251 * than set CSS and MDIV fields.
252 *
253 * See AT91RM9200 errata #27 and #28 for details.
254 */
0dcfed14
JCPV
255 ldr tmp1, .saved_mckr
256 tst tmp1, #AT91_PMC_PRES
eaad2db0 257 beq 2f
0dcfed14 258 and tmp1, tmp1, #AT91_PMC_PRES
b5514952 259 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
260
261 wait_mckrdy
262#endif
263
264 /*
265 * Restore master clock setting
266 */
0dcfed14 2672: ldr tmp1, .saved_mckr
b5514952 268 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
269
270 wait_mckrdy
271
fb7e197b
JCPV
272 /*
273 * at91rm9200 Memory controller
274 * Do nothing - self-refresh is automatically disabled.
275 */
276 cmp memctrl, #AT91_MEMCTRL_MC
277 beq ram_restored
278
279 /*
280 * DDRSDR Memory controller
281 */
282 cmp memctrl, #AT91_MEMCTRL_DDRSDR
283 bne sdr_en_restore
02f513a0
PR
284 /* Restore MDR in case of LPDDR1 */
285 ldr tmp1, .saved_sam9_mdr
286 str tmp1, [sdramc, #AT91_DDRSDRC_MDR]
7dca3343 287 /* Restore LPR on AT91 with DDRAM */
0dcfed14
JCPV
288 ldr tmp1, .saved_sam9_lpr
289 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
7dca3343
NF
290
291 /* if we use the second ram controller */
0dcfed14 292 cmp ramc1, #0
02f513a0
PR
293 ldrne tmp2, .saved_sam9_mdr1
294 strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
0dcfed14
JCPV
295 ldrne tmp2, .saved_sam9_lpr1
296 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
7dca3343 297
fb7e197b
JCPV
298 b ram_restored
299
300 /*
301 * SDRAMC Memory controller
302 */
303sdr_en_restore:
7dca3343 304 /* Restore LPR on AT91 with SDRAM */
0dcfed14
JCPV
305 ldr tmp1, .saved_sam9_lpr
306 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
eaad2db0 307
fb7e197b 308ram_restored:
eaad2db0 309 /* Restore registers, and return */
fb7e197b 310 ldmfd sp!, {r4 - r12, pc}
eaad2db0
AV
311
312
313.saved_mckr:
314 .word 0
315
316.saved_pllar:
317 .word 0
318
319.saved_pllbr:
320 .word 0
321
322.saved_sam9_lpr:
323 .word 0
324
7dca3343
NF
325.saved_sam9_lpr1:
326 .word 0
327
02f513a0
PR
328.saved_sam9_mdr:
329 .word 0
330
331.saved_sam9_mdr1:
332 .word 0
333
eaad2db0
AV
334ENTRY(at91_slow_clock_sz)
335 .word .-at91_slow_clock
This page took 0.385876 seconds and 5 git commands to generate.