diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-02-22 11:50:55 -0500 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-02-23 08:57:56 -0500 |
commit | fb7e197bec45f15299315ed14292f09086d90a0b (patch) | |
tree | 1b57707d7b0a9cd2533c1db057487b1ad1692860 | |
parent | f363c407b42c467d06675c852e55f26adb959915 (diff) |
ARM: at91/pm_slowclock: add runtime detection of memory contoller
This will allow to have all SoC in one kernel image.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91_ramc.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm_slowclock.S | 66 |
3 files changed, 68 insertions, 22 deletions
diff --git a/arch/arm/mach-at91/include/mach/at91_ramc.h b/arch/arm/mach-at91/include/mach/at91_ramc.h index 3155499e2ea3..d8aeb278614e 100644 --- a/arch/arm/mach-at91/include/mach/at91_ramc.h +++ b/arch/arm/mach-at91/include/mach/at91_ramc.h | |||
@@ -21,11 +21,12 @@ extern void __iomem *at91_ramc_base[]; | |||
21 | .extern at91_ramc_base | 21 | .extern at91_ramc_base |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #ifdef CONFIG_ARCH_AT91RM9200 | 24 | #define AT91_MEMCTRL_MC 0 |
25 | #include <mach/at91rm9200_mc.h> | 25 | #define AT91_MEMCTRL_SDRAMC 1 |
26 | #else | 26 | #define AT91_MEMCTRL_DDRSDR 2 |
27 | |||
28 | #include <mach/at91rm9200_sdramc.h> | ||
27 | #include <mach/at91sam9_ddrsdr.h> | 29 | #include <mach/at91sam9_ddrsdr.h> |
28 | #include <mach/at91sam9_sdramc.h> | 30 | #include <mach/at91sam9_sdramc.h> |
29 | #endif | ||
30 | 31 | ||
31 | #endif /* __AT91_RAMC_H__ */ | 32 | #endif /* __AT91_RAMC_H__ */ |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 46dbb7e1339c..2793591c73c0 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -188,10 +188,12 @@ int at91_suspend_entering_slow_clock(void) | |||
188 | EXPORT_SYMBOL(at91_suspend_entering_slow_clock); | 188 | EXPORT_SYMBOL(at91_suspend_entering_slow_clock); |
189 | 189 | ||
190 | 190 | ||
191 | static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1); | 191 | static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, |
192 | void __iomem *ramc1, int memctrl); | ||
192 | 193 | ||
193 | #ifdef CONFIG_AT91_SLOW_CLOCK | 194 | #ifdef CONFIG_AT91_SLOW_CLOCK |
194 | extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1); | 195 | extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, |
196 | void __iomem *ramc1, int memctrl); | ||
195 | extern u32 at91_slow_clock_sz; | 197 | extern u32 at91_slow_clock_sz; |
196 | #endif | 198 | #endif |
197 | 199 | ||
@@ -241,11 +243,18 @@ static int at91_pm_enter(suspend_state_t state) | |||
241 | * turning off the main oscillator; reverse on wakeup. | 243 | * turning off the main oscillator; reverse on wakeup. |
242 | */ | 244 | */ |
243 | if (slow_clock) { | 245 | if (slow_clock) { |
246 | int memctrl = AT91_MEMCTRL_SDRAMC; | ||
247 | |||
248 | if (cpu_is_at91rm9200()) | ||
249 | memctrl = AT91_MEMCTRL_MC; | ||
250 | else if (cpu_is_at91sam9g45()) | ||
251 | memctrl = AT91_MEMCTRL_DDRSDR; | ||
244 | #ifdef CONFIG_AT91_SLOW_CLOCK | 252 | #ifdef CONFIG_AT91_SLOW_CLOCK |
245 | /* copy slow_clock handler to SRAM, and call it */ | 253 | /* copy slow_clock handler to SRAM, and call it */ |
246 | memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); | 254 | memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); |
247 | #endif | 255 | #endif |
248 | slow_clock(at91_pmc_base, at91_ramc_base[0], at91_ramc_base[1]); | 256 | slow_clock(at91_pmc_base, at91_ramc_base[0], |
257 | at91_ramc_base[1], memctrl); | ||
249 | break; | 258 | break; |
250 | } else { | 259 | } else { |
251 | pr_info("AT91: PM - no slow clock mode enabled ...\n"); | 260 | pr_info("AT91: PM - no slow clock mode enabled ...\n"); |
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index a2835a81bc84..2c46010953c2 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S | |||
@@ -42,8 +42,9 @@ | |||
42 | pmc .req r0 | 42 | pmc .req r0 |
43 | sdramc .req r1 | 43 | sdramc .req r1 |
44 | ramc1 .req r2 | 44 | ramc1 .req r2 |
45 | tmp1 .req r3 | 45 | memctrl .req r3 |
46 | tmp2 .req r4 | 46 | tmp1 .req r4 |
47 | tmp2 .req r5 | ||
47 | 48 | ||
48 | /* | 49 | /* |
49 | * Wait until master clock is ready (after switching master clock source) | 50 | * Wait until master clock is ready (after switching master clock source) |
@@ -103,29 +104,44 @@ tmp2 .req r4 | |||
103 | 104 | ||
104 | .text | 105 | .text |
105 | 106 | ||
106 | /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */ | 107 | /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, |
108 | * void __iomem *ramc1, int memctrl) | ||
109 | */ | ||
107 | ENTRY(at91_slow_clock) | 110 | ENTRY(at91_slow_clock) |
108 | /* Save registers on stack */ | 111 | /* Save registers on stack */ |
109 | stmfd sp!, {r3 - r12, lr} | 112 | stmfd sp!, {r4 - r12, lr} |
110 | 113 | ||
111 | /* | 114 | /* |
112 | * Register usage: | 115 | * Register usage: |
113 | * R0 = Base address of AT91_PMC | 116 | * R0 = Base address of AT91_PMC |
114 | * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) | 117 | * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) |
115 | * R2 = Base address of second RAM Controller or 0 if not present | 118 | * R2 = Base address of second RAM Controller or 0 if not present |
116 | * R3 = temporary register | 119 | * R3 = Memory controller |
117 | * R4 = temporary register | 120 | * R4 = temporary register |
121 | * R5 = temporary register | ||
118 | */ | 122 | */ |
119 | 123 | ||
120 | /* Drain write buffer */ | 124 | /* Drain write buffer */ |
121 | mov tmp1, #0 | 125 | mov tmp1, #0 |
122 | mcr p15, 0, tmp1, c7, c10, 4 | 126 | mcr p15, 0, tmp1, c7, c10, 4 |
123 | 127 | ||
124 | #ifdef CONFIG_ARCH_AT91RM9200 | 128 | cmp memctrl, #AT91_MEMCTRL_MC |
129 | bne ddr_sr_enable | ||
130 | |||
131 | /* | ||
132 | * at91rm9200 Memory controller | ||
133 | */ | ||
125 | /* Put SDRAM in self-refresh mode */ | 134 | /* Put SDRAM in self-refresh mode */ |
126 | mov tmp1, #1 | 135 | mov tmp1, #1 |
127 | str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] | 136 | str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] |
128 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | 137 | b sdr_sr_done |
138 | |||
139 | /* | ||
140 | * DDRSDR Memory controller | ||
141 | */ | ||
142 | ddr_sr_enable: | ||
143 | cmp memctrl, #AT91_MEMCTRL_DDRSDR | ||
144 | bne sdr_sr_enable | ||
129 | 145 | ||
130 | /* prepare for DDRAM self-refresh mode */ | 146 | /* prepare for DDRAM self-refresh mode */ |
131 | ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] | 147 | ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
@@ -143,7 +159,13 @@ ENTRY(at91_slow_clock) | |||
143 | /* Enable DDRAM self-refresh mode */ | 159 | /* Enable DDRAM self-refresh mode */ |
144 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] | 160 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
145 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | 161 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
146 | #else | 162 | |
163 | b sdr_sr_done | ||
164 | |||
165 | /* | ||
166 | * SDRAMC Memory controller | ||
167 | */ | ||
168 | sdr_sr_enable: | ||
147 | /* Enable SDRAM self-refresh mode */ | 169 | /* Enable SDRAM self-refresh mode */ |
148 | ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] | 170 | ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] |
149 | str tmp1, .saved_sam9_lpr | 171 | str tmp1, .saved_sam9_lpr |
@@ -151,8 +173,8 @@ ENTRY(at91_slow_clock) | |||
151 | bic tmp1, #AT91_SDRAMC_LPCB | 173 | bic tmp1, #AT91_SDRAMC_LPCB |
152 | orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH | 174 | orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH |
153 | str tmp1, [sdramc, #AT91_SDRAMC_LPR] | 175 | str tmp1, [sdramc, #AT91_SDRAMC_LPR] |
154 | #endif | ||
155 | 176 | ||
177 | sdr_sr_done: | ||
156 | /* Save Master clock setting */ | 178 | /* Save Master clock setting */ |
157 | ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)] | 179 | ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)] |
158 | str tmp1, .saved_mckr | 180 | str tmp1, .saved_mckr |
@@ -255,9 +277,18 @@ ENTRY(at91_slow_clock) | |||
255 | 277 | ||
256 | wait_mckrdy | 278 | wait_mckrdy |
257 | 279 | ||
258 | #ifdef CONFIG_ARCH_AT91RM9200 | 280 | /* |
259 | /* Do nothing - self-refresh is automatically disabled. */ | 281 | * at91rm9200 Memory controller |
260 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | 282 | * Do nothing - self-refresh is automatically disabled. |
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 | ||
261 | /* Restore LPR on AT91 with DDRAM */ | 292 | /* Restore LPR on AT91 with DDRAM */ |
262 | ldr tmp1, .saved_sam9_lpr | 293 | ldr tmp1, .saved_sam9_lpr |
263 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] | 294 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
@@ -267,14 +298,19 @@ ENTRY(at91_slow_clock) | |||
267 | ldrne tmp2, .saved_sam9_lpr1 | 298 | ldrne tmp2, .saved_sam9_lpr1 |
268 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | 299 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
269 | 300 | ||
270 | #else | 301 | b ram_restored |
302 | |||
303 | /* | ||
304 | * SDRAMC Memory controller | ||
305 | */ | ||
306 | sdr_en_restore: | ||
271 | /* Restore LPR on AT91 with SDRAM */ | 307 | /* Restore LPR on AT91 with SDRAM */ |
272 | ldr tmp1, .saved_sam9_lpr | 308 | ldr tmp1, .saved_sam9_lpr |
273 | str tmp1, [sdramc, #AT91_SDRAMC_LPR] | 309 | str tmp1, [sdramc, #AT91_SDRAMC_LPR] |
274 | #endif | ||
275 | 310 | ||
311 | ram_restored: | ||
276 | /* Restore registers, and return */ | 312 | /* Restore registers, and return */ |
277 | ldmfd sp!, {r3 - r12, pc} | 313 | ldmfd sp!, {r4 - r12, pc} |
278 | 314 | ||
279 | 315 | ||
280 | .saved_mckr: | 316 | .saved_mckr: |