ARM: at91/dt: sama5d4: fix lcdck clock definition
[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
fb7e197b
JCPV
73/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
74 * void __iomem *ramc1, int memctrl)
75 */
eaad2db0
AV
76ENTRY(at91_slow_clock)
77 /* Save registers on stack */
fb7e197b 78 stmfd sp!, {r4 - r12, lr}
eaad2db0
AV
79
80 /*
81 * Register usage:
8ff12ad3
JCPV
82 * R0 = Base address of AT91_PMC
83 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
84 * R2 = Base address of second RAM Controller or 0 if not present
fb7e197b 85 * R3 = Memory controller
eaad2db0 86 * R4 = temporary register
fb7e197b 87 * R5 = temporary register
eaad2db0 88 */
eaad2db0
AV
89
90 /* Drain write buffer */
0dcfed14
JCPV
91 mov tmp1, #0
92 mcr p15, 0, tmp1, c7, c10, 4
eaad2db0 93
fb7e197b
JCPV
94 cmp memctrl, #AT91_MEMCTRL_MC
95 bne ddr_sr_enable
96
97 /*
98 * at91rm9200 Memory controller
99 */
eaad2db0 100 /* Put SDRAM in self-refresh mode */
0dcfed14 101 mov tmp1, #1
1a269ade 102 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
fb7e197b
JCPV
103 b sdr_sr_done
104
105 /*
106 * DDRSDR Memory controller
107 */
108ddr_sr_enable:
109 cmp memctrl, #AT91_MEMCTRL_DDRSDR
110 bne sdr_sr_enable
eaad2db0 111
02f513a0
PR
112 /* LPDDR1 --> force DDR2 mode during self-refresh */
113 ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR]
114 str tmp1, .saved_sam9_mdr
115 bic tmp1, tmp1, #~AT91_DDRSDRC_MD
116 cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
117 ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
118 biceq tmp1, tmp1, #AT91_DDRSDRC_MD
119 orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
120 streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
121
7dca3343 122 /* prepare for DDRAM self-refresh mode */
0dcfed14
JCPV
123 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
124 str tmp1, .saved_sam9_lpr
125 bic tmp1, #AT91_DDRSDRC_LPCB
126 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
7dca3343
NF
127
128 /* figure out if we use the second ram controller */
0dcfed14 129 cmp ramc1, #0
02f513a0
PR
130 beq ddr_no_2nd_ctrl
131
132 ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
133 str tmp2, .saved_sam9_mdr1
134 bic tmp2, tmp2, #~AT91_DDRSDRC_MD
135 cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
136 ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
137 biceq tmp2, tmp2, #AT91_DDRSDRC_MD
138 orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
139 streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
140
141 ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
142 str tmp2, .saved_sam9_lpr1
143 bic tmp2, #AT91_DDRSDRC_LPCB
144 orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
7dca3343
NF
145
146 /* Enable DDRAM self-refresh mode */
02f513a0
PR
147 str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
148ddr_no_2nd_ctrl:
0dcfed14 149 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
fb7e197b
JCPV
150
151 b sdr_sr_done
152
153 /*
154 * SDRAMC Memory controller
155 */
156sdr_sr_enable:
eaad2db0 157 /* Enable SDRAM self-refresh mode */
0dcfed14
JCPV
158 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
159 str tmp1, .saved_sam9_lpr
eaad2db0 160
0dcfed14
JCPV
161 bic tmp1, #AT91_SDRAMC_LPCB
162 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
163 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
eaad2db0 164
fb7e197b 165sdr_sr_done:
eaad2db0 166 /* Save Master clock setting */
b5514952 167 ldr tmp1, [pmc, #AT91_PMC_MCKR]
0dcfed14 168 str tmp1, .saved_mckr
eaad2db0
AV
169
170 /*
171 * Set the Master clock source to slow clock
172 */
0dcfed14 173 bic tmp1, tmp1, #AT91_PMC_CSS
b5514952 174 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
175
176 wait_mckrdy
177
178#ifdef SLOWDOWN_MASTER_CLOCK
179 /*
180 * Set the Master Clock PRES and MDIV fields.
181 *
182 * See AT91RM9200 errata #27 and #28 for details.
183 */
0dcfed14 184 mov tmp1, #0
b5514952 185 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
186
187 wait_mckrdy
188#endif
189
190 /* Save PLLA setting and disable it */
b5514952 191 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
0dcfed14 192 str tmp1, .saved_pllar
eaad2db0 193
0dcfed14
JCPV
194 mov tmp1, #AT91_PMC_PLLCOUNT
195 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
b5514952 196 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 197
eaad2db0 198 /* Save PLLB setting and disable it */
b5514952 199 ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
0dcfed14 200 str tmp1, .saved_pllbr
eaad2db0 201
0dcfed14 202 mov tmp1, #AT91_PMC_PLLCOUNT
b5514952 203 str tmp1, [pmc, #AT91_CKGR_PLLBR]
eaad2db0 204
eaad2db0 205 /* Turn off the main oscillator */
b5514952 206 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 207 bic tmp1, tmp1, #AT91_PMC_MOSCEN
b5514952 208 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
209
210 /* Wait for interrupt */
0dcfed14 211 mcr p15, 0, tmp1, c7, c0, 4
eaad2db0
AV
212
213 /* Turn on the main oscillator */
b5514952 214 ldr tmp1, [pmc, #AT91_CKGR_MOR]
0dcfed14 215 orr tmp1, tmp1, #AT91_PMC_MOSCEN
b5514952 216 str tmp1, [pmc, #AT91_CKGR_MOR]
eaad2db0
AV
217
218 wait_moscrdy
219
220 /* Restore PLLB setting */
0dcfed14 221 ldr tmp1, .saved_pllbr
b5514952 222 str tmp1, [pmc, #AT91_CKGR_PLLBR]
eaad2db0 223
0dcfed14 224 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 225 bne 1f
0dcfed14 226 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
227 beq 2f
2281:
eaad2db0 229 wait_pllblock
9823f1a8 2302:
eaad2db0
AV
231
232 /* Restore PLLA setting */
0dcfed14 233 ldr tmp1, .saved_pllar
b5514952 234 str tmp1, [pmc, #AT91_CKGR_PLLAR]
eaad2db0 235
0dcfed14 236 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
9823f1a8 237 bne 3f
0dcfed14 238 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
9823f1a8
AL
239 beq 4f
2403:
eaad2db0 241 wait_pllalock
9823f1a8 2424:
eaad2db0
AV
243
244#ifdef SLOWDOWN_MASTER_CLOCK
245 /*
246 * First set PRES if it was not 0,
247 * than set CSS and MDIV fields.
248 *
249 * See AT91RM9200 errata #27 and #28 for details.
250 */
0dcfed14
JCPV
251 ldr tmp1, .saved_mckr
252 tst tmp1, #AT91_PMC_PRES
eaad2db0 253 beq 2f
0dcfed14 254 and tmp1, tmp1, #AT91_PMC_PRES
b5514952 255 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
256
257 wait_mckrdy
258#endif
259
260 /*
261 * Restore master clock setting
262 */
0dcfed14 2632: ldr tmp1, .saved_mckr
b5514952 264 str tmp1, [pmc, #AT91_PMC_MCKR]
eaad2db0
AV
265
266 wait_mckrdy
267
fb7e197b
JCPV
268 /*
269 * at91rm9200 Memory controller
270 * Do nothing - self-refresh is automatically disabled.
271 */
272 cmp memctrl, #AT91_MEMCTRL_MC
273 beq ram_restored
274
275 /*
276 * DDRSDR Memory controller
277 */
278 cmp memctrl, #AT91_MEMCTRL_DDRSDR
279 bne sdr_en_restore
02f513a0
PR
280 /* Restore MDR in case of LPDDR1 */
281 ldr tmp1, .saved_sam9_mdr
282 str tmp1, [sdramc, #AT91_DDRSDRC_MDR]
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 288 cmp ramc1, #0
02f513a0
PR
289 ldrne tmp2, .saved_sam9_mdr1
290 strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
0dcfed14
JCPV
291 ldrne tmp2, .saved_sam9_lpr1
292 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
7dca3343 293
fb7e197b
JCPV
294 b ram_restored
295
296 /*
297 * SDRAMC Memory controller
298 */
299sdr_en_restore:
7dca3343 300 /* Restore LPR on AT91 with SDRAM */
0dcfed14
JCPV
301 ldr tmp1, .saved_sam9_lpr
302 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
eaad2db0 303
fb7e197b 304ram_restored:
eaad2db0 305 /* Restore registers, and return */
fb7e197b 306 ldmfd sp!, {r4 - r12, pc}
eaad2db0
AV
307
308
309.saved_mckr:
310 .word 0
311
312.saved_pllar:
313 .word 0
314
315.saved_pllbr:
316 .word 0
317
318.saved_sam9_lpr:
319 .word 0
320
7dca3343
NF
321.saved_sam9_lpr1:
322 .word 0
323
02f513a0
PR
324.saved_sam9_mdr:
325 .word 0
326
327.saved_sam9_mdr1:
328 .word 0
329
eaad2db0
AV
330ENTRY(at91_slow_clock_sz)
331 .word .-at91_slow_clock
This page took 0.508215 seconds and 5 git commands to generate.