aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-02-22 11:50:55 -0500
committerNicolas Ferre <nicolas.ferre@atmel.com>2012-02-23 08:57:56 -0500
commitfb7e197bec45f15299315ed14292f09086d90a0b (patch)
tree1b57707d7b0a9cd2533c1db057487b1ad1692860
parentf363c407b42c467d06675c852e55f26adb959915 (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.h9
-rw-r--r--arch/arm/mach-at91/pm.c15
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S66
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)
188EXPORT_SYMBOL(at91_suspend_entering_slow_clock); 188EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
189 189
190 190
191static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1); 191static 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
194extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1); 195extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
196 void __iomem *ramc1, int memctrl);
195extern u32 at91_slow_clock_sz; 197extern 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 @@
42pmc .req r0 42pmc .req r0
43sdramc .req r1 43sdramc .req r1
44ramc1 .req r2 44ramc1 .req r2
45tmp1 .req r3 45memctrl .req r3
46tmp2 .req r4 46tmp1 .req r4
47tmp2 .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 */
107ENTRY(at91_slow_clock) 110ENTRY(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 */
142ddr_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 */
168sdr_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
177sdr_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 */
306sdr_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
311ram_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: