blob: a207dea3a1524f0a8b5f8cb20adf746d01fb3bae [file] [log] [blame]
Andrew Victoreaad2db2008-09-21 21:35:18 +01001/*
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 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010014#include <linux/linkage.h>
Boris BREZILLON2edb90a2013-10-11 09:37:45 +020015#include <linux/clk/at91_pmc.h>
Andrew Victoreaad2db2008-09-21 21:35:18 +010016#include <mach/hardware.h>
Jean-Christophe PLAGNIOL-VILLARDf363c402012-02-13 12:58:53 +080017#include <mach/at91_ramc.h>
Andrew Victoreaad2db2008-09-21 21:35:18 +010018
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +010019pmc .req r0
20sdramc .req r1
21ramc1 .req r2
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010022memctrl .req r3
23tmp1 .req r4
24tmp2 .req r5
Andrew Victoreaad2db2008-09-21 21:35:18 +010025
26/*
27 * Wait until master clock is ready (after switching master clock source)
28 */
29 .macro wait_mckrdy
Sylvain Rochetad4a38d2015-02-05 14:00:37 +0800301: ldr tmp1, [pmc, #AT91_PMC_SR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010031 tst tmp1, #AT91_PMC_MCKRDY
Andrew Victoreaad2db2008-09-21 21:35:18 +010032 beq 1b
Andrew Victoreaad2db2008-09-21 21:35:18 +010033 .endm
34
35/*
36 * Wait until master oscillator has stabilized.
37 */
38 .macro wait_moscrdy
Sylvain Rochetad4a38d2015-02-05 14:00:37 +0800391: ldr tmp1, [pmc, #AT91_PMC_SR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010040 tst tmp1, #AT91_PMC_MOSCS
Andrew Victoreaad2db2008-09-21 21:35:18 +010041 beq 1b
Andrew Victoreaad2db2008-09-21 21:35:18 +010042 .endm
43
44/*
45 * Wait until PLLA has locked.
46 */
47 .macro wait_pllalock
Sylvain Rochetad4a38d2015-02-05 14:00:37 +0800481: ldr tmp1, [pmc, #AT91_PMC_SR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010049 tst tmp1, #AT91_PMC_LOCKA
Andrew Victoreaad2db2008-09-21 21:35:18 +010050 beq 1b
Andrew Victoreaad2db2008-09-21 21:35:18 +010051 .endm
52
Andrew Victoreaad2db2008-09-21 21:35:18 +010053 .text
54
Wenyou Yange7b848d2015-03-11 10:08:12 +080055 .arm
56
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010057/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
58 * void __iomem *ramc1, int memctrl)
59 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010060ENTRY(at91_slow_clock)
61 /* Save registers on stack */
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010062 stmfd sp!, {r4 - r12, lr}
Andrew Victoreaad2db2008-09-21 21:35:18 +010063
64 /*
65 * Register usage:
Jean-Christophe PLAGNIOL-VILLARD8ff12ad32012-02-22 17:50:54 +010066 * R0 = Base address of AT91_PMC
67 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
68 * R2 = Base address of second RAM Controller or 0 if not present
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010069 * R3 = Memory controller
Andrew Victoreaad2db2008-09-21 21:35:18 +010070 * R4 = temporary register
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010071 * R5 = temporary register
Andrew Victoreaad2db2008-09-21 21:35:18 +010072 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010073
74 /* Drain write buffer */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010075 mov tmp1, #0
76 mcr p15, 0, tmp1, c7, c10, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +010077
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010078 cmp memctrl, #AT91_MEMCTRL_MC
79 bne ddr_sr_enable
80
81 /*
82 * at91rm9200 Memory controller
83 */
Andrew Victoreaad2db2008-09-21 21:35:18 +010084 /* Put SDRAM in self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +010085 mov tmp1, #1
Jean-Christophe PLAGNIOL-VILLARD1a269ad2011-11-16 02:58:31 +080086 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +010087 b sdr_sr_done
88
89 /*
90 * DDRSDR Memory controller
91 */
92ddr_sr_enable:
93 cmp memctrl, #AT91_MEMCTRL_DDRSDR
94 bne sdr_sr_enable
Andrew Victoreaad2db2008-09-21 21:35:18 +010095
Peter Rosin02f513a2015-02-05 14:02:09 +080096 /* LPDDR1 --> force DDR2 mode during self-refresh */
97 ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR]
98 str tmp1, .saved_sam9_mdr
99 bic tmp1, tmp1, #~AT91_DDRSDRC_MD
100 cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
101 ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
102 biceq tmp1, tmp1, #AT91_DDRSDRC_MD
103 orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
104 streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
105
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100106 /* prepare for DDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100107 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
108 str tmp1, .saved_sam9_lpr
109 bic tmp1, #AT91_DDRSDRC_LPCB
110 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100111
112 /* figure out if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100113 cmp ramc1, #0
Peter Rosin02f513a2015-02-05 14:02:09 +0800114 beq ddr_no_2nd_ctrl
115
116 ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
117 str tmp2, .saved_sam9_mdr1
118 bic tmp2, tmp2, #~AT91_DDRSDRC_MD
119 cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
120 ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
121 biceq tmp2, tmp2, #AT91_DDRSDRC_MD
122 orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
123 streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
124
125 ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
126 str tmp2, .saved_sam9_lpr1
127 bic tmp2, #AT91_DDRSDRC_LPCB
128 orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100129
130 /* Enable DDRAM self-refresh mode */
Peter Rosin02f513a2015-02-05 14:02:09 +0800131 str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
132ddr_no_2nd_ctrl:
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100133 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +0100134
135 b sdr_sr_done
136
137 /*
138 * SDRAMC Memory controller
139 */
140sdr_sr_enable:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100141 /* Enable SDRAM self-refresh mode */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100142 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
143 str tmp1, .saved_sam9_lpr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100144
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100145 bic tmp1, #AT91_SDRAMC_LPCB
146 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
147 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100148
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +0100149sdr_sr_done:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100150 /* Save Master clock setting */
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800151 ldr tmp1, [pmc, #AT91_PMC_MCKR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100152 str tmp1, .saved_mckr
Andrew Victoreaad2db2008-09-21 21:35:18 +0100153
154 /*
155 * Set the Master clock source to slow clock
156 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100157 bic tmp1, tmp1, #AT91_PMC_CSS
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800158 str tmp1, [pmc, #AT91_PMC_MCKR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100159
160 wait_mckrdy
161
Andrew Victoreaad2db2008-09-21 21:35:18 +0100162 /* Save PLLA setting and disable it */
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800163 ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100164 str tmp1, .saved_pllar
Andrew Victoreaad2db2008-09-21 21:35:18 +0100165
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100166 mov tmp1, #AT91_PMC_PLLCOUNT
167 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800168 str tmp1, [pmc, #AT91_CKGR_PLLAR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100169
Andrew Victoreaad2db2008-09-21 21:35:18 +0100170 /* Turn off the main oscillator */
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800171 ldr tmp1, [pmc, #AT91_CKGR_MOR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100172 bic tmp1, tmp1, #AT91_PMC_MOSCEN
Patrice Vilchez59574572015-02-12 10:52:13 +0800173 orr tmp1, tmp1, #AT91_PMC_KEY
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800174 str tmp1, [pmc, #AT91_CKGR_MOR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100175
176 /* Wait for interrupt */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100177 mcr p15, 0, tmp1, c7, c0, 4
Andrew Victoreaad2db2008-09-21 21:35:18 +0100178
179 /* Turn on the main oscillator */
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800180 ldr tmp1, [pmc, #AT91_CKGR_MOR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100181 orr tmp1, tmp1, #AT91_PMC_MOSCEN
Patrice Vilchez59574572015-02-12 10:52:13 +0800182 orr tmp1, tmp1, #AT91_PMC_KEY
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800183 str tmp1, [pmc, #AT91_CKGR_MOR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100184
185 wait_moscrdy
186
Andrew Victoreaad2db2008-09-21 21:35:18 +0100187 /* Restore PLLA setting */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100188 ldr tmp1, .saved_pllar
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800189 str tmp1, [pmc, #AT91_CKGR_PLLAR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100190
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100191 tst tmp1, #(AT91_PMC_MUL & 0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100192 bne 3f
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100193 tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
Anders Larsen9823f1a2010-04-08 11:48:16 +0100194 beq 4f
1953:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100196 wait_pllalock
Anders Larsen9823f1a2010-04-08 11:48:16 +01001974:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100198
Andrew Victoreaad2db2008-09-21 21:35:18 +0100199 /*
200 * Restore master clock setting
201 */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +01002022: ldr tmp1, .saved_mckr
Jean-Christophe PLAGNIOL-VILLARDb5514952011-11-25 09:59:46 +0800203 str tmp1, [pmc, #AT91_PMC_MCKR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100204
205 wait_mckrdy
206
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +0100207 /*
208 * at91rm9200 Memory controller
209 * Do nothing - self-refresh is automatically disabled.
210 */
211 cmp memctrl, #AT91_MEMCTRL_MC
212 beq ram_restored
213
214 /*
215 * DDRSDR Memory controller
216 */
217 cmp memctrl, #AT91_MEMCTRL_DDRSDR
218 bne sdr_en_restore
Peter Rosin02f513a2015-02-05 14:02:09 +0800219 /* Restore MDR in case of LPDDR1 */
220 ldr tmp1, .saved_sam9_mdr
221 str tmp1, [sdramc, #AT91_DDRSDRC_MDR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100222 /* Restore LPR on AT91 with DDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100223 ldr tmp1, .saved_sam9_lpr
224 str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100225
226 /* if we use the second ram controller */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100227 cmp ramc1, #0
Peter Rosin02f513a2015-02-05 14:02:09 +0800228 ldrne tmp2, .saved_sam9_mdr1
229 strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100230 ldrne tmp2, .saved_sam9_lpr1
231 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100232
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +0100233 b ram_restored
234
235 /*
236 * SDRAMC Memory controller
237 */
238sdr_en_restore:
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100239 /* Restore LPR on AT91 with SDRAM */
Jean-Christophe PLAGNIOL-VILLARD0dcfed12012-02-22 17:50:53 +0100240 ldr tmp1, .saved_sam9_lpr
241 str tmp1, [sdramc, #AT91_SDRAMC_LPR]
Andrew Victoreaad2db2008-09-21 21:35:18 +0100242
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +0100243ram_restored:
Andrew Victoreaad2db2008-09-21 21:35:18 +0100244 /* Restore registers, and return */
Jean-Christophe PLAGNIOL-VILLARDfb7e1972012-02-22 17:50:55 +0100245 ldmfd sp!, {r4 - r12, pc}
Andrew Victoreaad2db2008-09-21 21:35:18 +0100246
247
248.saved_mckr:
249 .word 0
250
251.saved_pllar:
252 .word 0
253
Andrew Victoreaad2db2008-09-21 21:35:18 +0100254.saved_sam9_lpr:
255 .word 0
256
Nicolas Ferre7dca3342010-06-21 14:59:27 +0100257.saved_sam9_lpr1:
258 .word 0
259
Peter Rosin02f513a2015-02-05 14:02:09 +0800260.saved_sam9_mdr:
261 .word 0
262
263.saved_sam9_mdr1:
264 .word 0
265
Andrew Victoreaad2db2008-09-21 21:35:18 +0100266ENTRY(at91_slow_clock_sz)
267 .word .-at91_slow_clock