diff options
author | Andrew Victor <andrew@sanpeople.com> | 2007-02-05 05:42:07 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-02-08 09:50:56 -0500 |
commit | 9d0412680e6c7b685ee466842047bcfb924d6dc5 (patch) | |
tree | c79300964ef1aca5d24571696f95e76b37c14679 /arch/arm/mach-at91/clock.c | |
parent | a93d48cc6019f84394b31d10c0d830a3b71696be (diff) |
[ARM] 4124/1: Rename mach-at91rm9200 and arch-at91rm9200 directories
Now that Linux includes support for the Atmel AT91SAM9260 and
AT91SAM9261 processors in addition to the original Atmel AT91RM9200
(with support for more AT91 processors pending), the "mach-at91rm9200"
and "arch-at91rm9200" directories should be renamed to indicate their
more generic nature.
The following git commands should be run BEFORE applying this patch:
git-mv arch/arm/mach-at91rm9200 arch/arm/mach-at91
git-mv include/asm-arm/arch-at91rm9200 include/asm-arm/arch-at91
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-at91/clock.c')
-rw-r--r-- | arch/arm/mach-at91/clock.c | 644 |
1 files changed, 644 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c new file mode 100644 index 000000000000..baab095f6e32 --- /dev/null +++ b/arch/arm/mach-at91/clock.c | |||
@@ -0,0 +1,644 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/clock.c | ||
3 | * | ||
4 | * Copyright (C) 2005 David Brownell | ||
5 | * Copyright (C) 2005 Ivan Kokshaysky | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/fs.h> | ||
17 | #include <linux/debugfs.h> | ||
18 | #include <linux/seq_file.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/clk.h> | ||
25 | |||
26 | #include <asm/semaphore.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/mach-types.h> | ||
29 | |||
30 | #include <asm/hardware.h> | ||
31 | #include <asm/arch/at91_pmc.h> | ||
32 | #include <asm/arch/cpu.h> | ||
33 | |||
34 | #include "clock.h" | ||
35 | |||
36 | |||
37 | /* | ||
38 | * There's a lot more which can be done with clocks, including cpufreq | ||
39 | * integration, slow clock mode support (for system suspend), letting | ||
40 | * PLLB be used at other rates (on boards that don't need USB), etc. | ||
41 | */ | ||
42 | |||
43 | #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) | ||
44 | #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) | ||
45 | #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) | ||
46 | #define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) | ||
47 | |||
48 | |||
49 | static LIST_HEAD(clocks); | ||
50 | static DEFINE_SPINLOCK(clk_lock); | ||
51 | |||
52 | static u32 at91_pllb_usb_init; | ||
53 | |||
54 | /* | ||
55 | * Four primary clock sources: two crystal oscillators (32K, main), and | ||
56 | * two PLLs. PLLA usually runs the master clock; and PLLB must run at | ||
57 | * 48 MHz (unless no USB function clocks are needed). The main clock and | ||
58 | * both PLLs are turned off to run in "slow clock mode" (system suspend). | ||
59 | */ | ||
60 | static struct clk clk32k = { | ||
61 | .name = "clk32k", | ||
62 | .rate_hz = AT91_SLOW_CLOCK, | ||
63 | .users = 1, /* always on */ | ||
64 | .id = 0, | ||
65 | .type = CLK_TYPE_PRIMARY, | ||
66 | }; | ||
67 | static struct clk main_clk = { | ||
68 | .name = "main", | ||
69 | .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ | ||
70 | .id = 1, | ||
71 | .type = CLK_TYPE_PRIMARY, | ||
72 | }; | ||
73 | static struct clk plla = { | ||
74 | .name = "plla", | ||
75 | .parent = &main_clk, | ||
76 | .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ | ||
77 | .id = 2, | ||
78 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, | ||
79 | }; | ||
80 | |||
81 | static void pllb_mode(struct clk *clk, int is_on) | ||
82 | { | ||
83 | u32 value; | ||
84 | |||
85 | if (is_on) { | ||
86 | is_on = AT91_PMC_LOCKB; | ||
87 | value = at91_pllb_usb_init; | ||
88 | } else | ||
89 | value = 0; | ||
90 | |||
91 | // REVISIT: Add work-around for AT91RM9200 Errata #26 ? | ||
92 | at91_sys_write(AT91_CKGR_PLLBR, value); | ||
93 | |||
94 | do { | ||
95 | cpu_relax(); | ||
96 | } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); | ||
97 | } | ||
98 | |||
99 | static struct clk pllb = { | ||
100 | .name = "pllb", | ||
101 | .parent = &main_clk, | ||
102 | .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ | ||
103 | .mode = pllb_mode, | ||
104 | .id = 3, | ||
105 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, | ||
106 | }; | ||
107 | |||
108 | static void pmc_sys_mode(struct clk *clk, int is_on) | ||
109 | { | ||
110 | if (is_on) | ||
111 | at91_sys_write(AT91_PMC_SCER, clk->pmc_mask); | ||
112 | else | ||
113 | at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); | ||
114 | } | ||
115 | |||
116 | /* USB function clocks (PLLB must be 48 MHz) */ | ||
117 | static struct clk udpck = { | ||
118 | .name = "udpck", | ||
119 | .parent = &pllb, | ||
120 | .mode = pmc_sys_mode, | ||
121 | }; | ||
122 | static struct clk uhpck = { | ||
123 | .name = "uhpck", | ||
124 | .parent = &pllb, | ||
125 | .mode = pmc_sys_mode, | ||
126 | }; | ||
127 | |||
128 | |||
129 | /* | ||
130 | * The master clock is divided from the CPU clock (by 1-4). It's used for | ||
131 | * memory, interfaces to on-chip peripherals, the AIC, and sometimes more | ||
132 | * (e.g baud rate generation). It's sourced from one of the primary clocks. | ||
133 | */ | ||
134 | static struct clk mck = { | ||
135 | .name = "mck", | ||
136 | .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ | ||
137 | }; | ||
138 | |||
139 | static void pmc_periph_mode(struct clk *clk, int is_on) | ||
140 | { | ||
141 | if (is_on) | ||
142 | at91_sys_write(AT91_PMC_PCER, clk->pmc_mask); | ||
143 | else | ||
144 | at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); | ||
145 | } | ||
146 | |||
147 | static struct clk __init *at91_css_to_clk(unsigned long css) | ||
148 | { | ||
149 | switch (css) { | ||
150 | case AT91_PMC_CSS_SLOW: | ||
151 | return &clk32k; | ||
152 | case AT91_PMC_CSS_MAIN: | ||
153 | return &main_clk; | ||
154 | case AT91_PMC_CSS_PLLA: | ||
155 | return &plla; | ||
156 | case AT91_PMC_CSS_PLLB: | ||
157 | return &pllb; | ||
158 | } | ||
159 | |||
160 | return NULL; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Associate a particular clock with a function (eg, "uart") and device. | ||
165 | * The drivers can then request the same 'function' with several different | ||
166 | * devices and not care about which clock name to use. | ||
167 | */ | ||
168 | void __init at91_clock_associate(const char *id, struct device *dev, const char *func) | ||
169 | { | ||
170 | struct clk *clk = clk_get(NULL, id); | ||
171 | |||
172 | if (!dev || !clk || !IS_ERR(clk_get(dev, func))) | ||
173 | return; | ||
174 | |||
175 | clk->function = func; | ||
176 | clk->dev = dev; | ||
177 | } | ||
178 | |||
179 | /* clocks cannot be de-registered no refcounting necessary */ | ||
180 | struct clk *clk_get(struct device *dev, const char *id) | ||
181 | { | ||
182 | struct clk *clk; | ||
183 | |||
184 | list_for_each_entry(clk, &clocks, node) { | ||
185 | if (strcmp(id, clk->name) == 0) | ||
186 | return clk; | ||
187 | if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) | ||
188 | return clk; | ||
189 | } | ||
190 | |||
191 | return ERR_PTR(-ENOENT); | ||
192 | } | ||
193 | EXPORT_SYMBOL(clk_get); | ||
194 | |||
195 | void clk_put(struct clk *clk) | ||
196 | { | ||
197 | } | ||
198 | EXPORT_SYMBOL(clk_put); | ||
199 | |||
200 | static void __clk_enable(struct clk *clk) | ||
201 | { | ||
202 | if (clk->parent) | ||
203 | __clk_enable(clk->parent); | ||
204 | if (clk->users++ == 0 && clk->mode) | ||
205 | clk->mode(clk, 1); | ||
206 | } | ||
207 | |||
208 | int clk_enable(struct clk *clk) | ||
209 | { | ||
210 | unsigned long flags; | ||
211 | |||
212 | spin_lock_irqsave(&clk_lock, flags); | ||
213 | __clk_enable(clk); | ||
214 | spin_unlock_irqrestore(&clk_lock, flags); | ||
215 | return 0; | ||
216 | } | ||
217 | EXPORT_SYMBOL(clk_enable); | ||
218 | |||
219 | static void __clk_disable(struct clk *clk) | ||
220 | { | ||
221 | BUG_ON(clk->users == 0); | ||
222 | if (--clk->users == 0 && clk->mode) | ||
223 | clk->mode(clk, 0); | ||
224 | if (clk->parent) | ||
225 | __clk_disable(clk->parent); | ||
226 | } | ||
227 | |||
228 | void clk_disable(struct clk *clk) | ||
229 | { | ||
230 | unsigned long flags; | ||
231 | |||
232 | spin_lock_irqsave(&clk_lock, flags); | ||
233 | __clk_disable(clk); | ||
234 | spin_unlock_irqrestore(&clk_lock, flags); | ||
235 | } | ||
236 | EXPORT_SYMBOL(clk_disable); | ||
237 | |||
238 | unsigned long clk_get_rate(struct clk *clk) | ||
239 | { | ||
240 | unsigned long flags; | ||
241 | unsigned long rate; | ||
242 | |||
243 | spin_lock_irqsave(&clk_lock, flags); | ||
244 | for (;;) { | ||
245 | rate = clk->rate_hz; | ||
246 | if (rate || !clk->parent) | ||
247 | break; | ||
248 | clk = clk->parent; | ||
249 | } | ||
250 | spin_unlock_irqrestore(&clk_lock, flags); | ||
251 | return rate; | ||
252 | } | ||
253 | EXPORT_SYMBOL(clk_get_rate); | ||
254 | |||
255 | /*------------------------------------------------------------------------*/ | ||
256 | |||
257 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
258 | |||
259 | /* | ||
260 | * For now, only the programmable clocks support reparenting (MCK could | ||
261 | * do this too, with care) or rate changing (the PLLs could do this too, | ||
262 | * ditto MCK but that's more for cpufreq). Drivers may reparent to get | ||
263 | * a better rate match; we don't. | ||
264 | */ | ||
265 | |||
266 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
267 | { | ||
268 | unsigned long flags; | ||
269 | unsigned prescale; | ||
270 | unsigned long actual; | ||
271 | |||
272 | if (!clk_is_programmable(clk)) | ||
273 | return -EINVAL; | ||
274 | spin_lock_irqsave(&clk_lock, flags); | ||
275 | |||
276 | actual = clk->parent->rate_hz; | ||
277 | for (prescale = 0; prescale < 7; prescale++) { | ||
278 | if (actual && actual <= rate) | ||
279 | break; | ||
280 | actual >>= 1; | ||
281 | } | ||
282 | |||
283 | spin_unlock_irqrestore(&clk_lock, flags); | ||
284 | return (prescale < 7) ? actual : -ENOENT; | ||
285 | } | ||
286 | EXPORT_SYMBOL(clk_round_rate); | ||
287 | |||
288 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
289 | { | ||
290 | unsigned long flags; | ||
291 | unsigned prescale; | ||
292 | unsigned long actual; | ||
293 | |||
294 | if (!clk_is_programmable(clk)) | ||
295 | return -EINVAL; | ||
296 | if (clk->users) | ||
297 | return -EBUSY; | ||
298 | spin_lock_irqsave(&clk_lock, flags); | ||
299 | |||
300 | actual = clk->parent->rate_hz; | ||
301 | for (prescale = 0; prescale < 7; prescale++) { | ||
302 | if (actual && actual <= rate) { | ||
303 | u32 pckr; | ||
304 | |||
305 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | ||
306 | pckr &= AT91_PMC_CSS_PLLB; /* clock selection */ | ||
307 | pckr |= prescale << 2; | ||
308 | at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); | ||
309 | clk->rate_hz = actual; | ||
310 | break; | ||
311 | } | ||
312 | actual >>= 1; | ||
313 | } | ||
314 | |||
315 | spin_unlock_irqrestore(&clk_lock, flags); | ||
316 | return (prescale < 7) ? actual : -ENOENT; | ||
317 | } | ||
318 | EXPORT_SYMBOL(clk_set_rate); | ||
319 | |||
320 | struct clk *clk_get_parent(struct clk *clk) | ||
321 | { | ||
322 | return clk->parent; | ||
323 | } | ||
324 | EXPORT_SYMBOL(clk_get_parent); | ||
325 | |||
326 | int clk_set_parent(struct clk *clk, struct clk *parent) | ||
327 | { | ||
328 | unsigned long flags; | ||
329 | |||
330 | if (clk->users) | ||
331 | return -EBUSY; | ||
332 | if (!clk_is_primary(parent) || !clk_is_programmable(clk)) | ||
333 | return -EINVAL; | ||
334 | spin_lock_irqsave(&clk_lock, flags); | ||
335 | |||
336 | clk->rate_hz = parent->rate_hz; | ||
337 | clk->parent = parent; | ||
338 | at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id); | ||
339 | |||
340 | spin_unlock_irqrestore(&clk_lock, flags); | ||
341 | return 0; | ||
342 | } | ||
343 | EXPORT_SYMBOL(clk_set_parent); | ||
344 | |||
345 | /* establish PCK0..PCK3 parentage and rate */ | ||
346 | static void init_programmable_clock(struct clk *clk) | ||
347 | { | ||
348 | struct clk *parent; | ||
349 | u32 pckr; | ||
350 | |||
351 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | ||
352 | parent = at91_css_to_clk(pckr & AT91_PMC_CSS); | ||
353 | clk->parent = parent; | ||
354 | clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); | ||
355 | } | ||
356 | |||
357 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ | ||
358 | |||
359 | /*------------------------------------------------------------------------*/ | ||
360 | |||
361 | #ifdef CONFIG_DEBUG_FS | ||
362 | |||
363 | static int at91_clk_show(struct seq_file *s, void *unused) | ||
364 | { | ||
365 | u32 scsr, pcsr, sr; | ||
366 | struct clk *clk; | ||
367 | unsigned i; | ||
368 | |||
369 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); | ||
370 | seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); | ||
371 | |||
372 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); | ||
373 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); | ||
374 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); | ||
375 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); | ||
376 | |||
377 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); | ||
378 | for (i = 0; i < 4; i++) | ||
379 | seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i))); | ||
380 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); | ||
381 | |||
382 | seq_printf(s, "\n"); | ||
383 | |||
384 | list_for_each_entry(clk, &clocks, node) { | ||
385 | char *state; | ||
386 | |||
387 | if (clk->mode == pmc_sys_mode) | ||
388 | state = (scsr & clk->pmc_mask) ? "on" : "off"; | ||
389 | else if (clk->mode == pmc_periph_mode) | ||
390 | state = (pcsr & clk->pmc_mask) ? "on" : "off"; | ||
391 | else if (clk->pmc_mask) | ||
392 | state = (sr & clk->pmc_mask) ? "on" : "off"; | ||
393 | else if (clk == &clk32k || clk == &main_clk) | ||
394 | state = "on"; | ||
395 | else | ||
396 | state = ""; | ||
397 | |||
398 | seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", | ||
399 | clk->name, clk->users, state, clk_get_rate(clk), | ||
400 | clk->parent ? clk->parent->name : ""); | ||
401 | } | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int at91_clk_open(struct inode *inode, struct file *file) | ||
406 | { | ||
407 | return single_open(file, at91_clk_show, NULL); | ||
408 | } | ||
409 | |||
410 | static struct file_operations at91_clk_operations = { | ||
411 | .open = at91_clk_open, | ||
412 | .read = seq_read, | ||
413 | .llseek = seq_lseek, | ||
414 | .release = single_release, | ||
415 | }; | ||
416 | |||
417 | static int __init at91_clk_debugfs_init(void) | ||
418 | { | ||
419 | /* /sys/kernel/debug/at91_clk */ | ||
420 | (void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | postcore_initcall(at91_clk_debugfs_init); | ||
425 | |||
426 | #endif | ||
427 | |||
428 | /*------------------------------------------------------------------------*/ | ||
429 | |||
430 | /* Register a new clock */ | ||
431 | int __init clk_register(struct clk *clk) | ||
432 | { | ||
433 | if (clk_is_peripheral(clk)) { | ||
434 | clk->parent = &mck; | ||
435 | clk->mode = pmc_periph_mode; | ||
436 | list_add_tail(&clk->node, &clocks); | ||
437 | } | ||
438 | else if (clk_is_sys(clk)) { | ||
439 | clk->parent = &mck; | ||
440 | clk->mode = pmc_sys_mode; | ||
441 | |||
442 | list_add_tail(&clk->node, &clocks); | ||
443 | } | ||
444 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
445 | else if (clk_is_programmable(clk)) { | ||
446 | clk->mode = pmc_sys_mode; | ||
447 | init_programmable_clock(clk); | ||
448 | list_add_tail(&clk->node, &clocks); | ||
449 | } | ||
450 | #endif | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | |||
456 | /*------------------------------------------------------------------------*/ | ||
457 | |||
458 | static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) | ||
459 | { | ||
460 | unsigned mul, div; | ||
461 | |||
462 | div = reg & 0xff; | ||
463 | mul = (reg >> 16) & 0x7ff; | ||
464 | if (div && mul) { | ||
465 | freq /= div; | ||
466 | freq *= mul + 1; | ||
467 | } else | ||
468 | freq = 0; | ||
469 | |||
470 | return freq; | ||
471 | } | ||
472 | |||
473 | static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) | ||
474 | { | ||
475 | if (pll == &pllb && (reg & AT91_PMC_USB96M)) | ||
476 | return freq / 2; | ||
477 | else | ||
478 | return freq; | ||
479 | } | ||
480 | |||
481 | static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) | ||
482 | { | ||
483 | unsigned i, div = 0, mul = 0, diff = 1 << 30; | ||
484 | unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; | ||
485 | |||
486 | /* PLL output max 240 MHz (or 180 MHz per errata) */ | ||
487 | if (out_freq > 240000000) | ||
488 | goto fail; | ||
489 | |||
490 | for (i = 1; i < 256; i++) { | ||
491 | int diff1; | ||
492 | unsigned input, mul1; | ||
493 | |||
494 | /* | ||
495 | * PLL input between 1MHz and 32MHz per spec, but lower | ||
496 | * frequences seem necessary in some cases so allow 100K. | ||
497 | */ | ||
498 | input = main_freq / i; | ||
499 | if (input < 100000) | ||
500 | continue; | ||
501 | if (input > 32000000) | ||
502 | continue; | ||
503 | |||
504 | mul1 = out_freq / input; | ||
505 | if (mul1 > 2048) | ||
506 | continue; | ||
507 | if (mul1 < 2) | ||
508 | goto fail; | ||
509 | |||
510 | diff1 = out_freq - input * mul1; | ||
511 | if (diff1 < 0) | ||
512 | diff1 = -diff1; | ||
513 | if (diff > diff1) { | ||
514 | diff = diff1; | ||
515 | div = i; | ||
516 | mul = mul1; | ||
517 | if (diff == 0) | ||
518 | break; | ||
519 | } | ||
520 | } | ||
521 | if (i == 256 && diff > (out_freq >> 5)) | ||
522 | goto fail; | ||
523 | return ret | ((mul - 1) << 16) | div; | ||
524 | fail: | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * Several unused clocks may be active. Turn them off. | ||
530 | */ | ||
531 | static void __init at91_periphclk_reset(void) | ||
532 | { | ||
533 | unsigned long reg; | ||
534 | struct clk *clk; | ||
535 | |||
536 | reg = at91_sys_read(AT91_PMC_PCSR); | ||
537 | |||
538 | list_for_each_entry(clk, &clocks, node) { | ||
539 | if (clk->mode != pmc_periph_mode) | ||
540 | continue; | ||
541 | |||
542 | if (clk->users > 0) | ||
543 | reg &= ~clk->pmc_mask; | ||
544 | } | ||
545 | |||
546 | at91_sys_write(AT91_PMC_PCDR, reg); | ||
547 | } | ||
548 | |||
549 | static struct clk *const standard_pmc_clocks[] __initdata = { | ||
550 | /* four primary clocks */ | ||
551 | &clk32k, | ||
552 | &main_clk, | ||
553 | &plla, | ||
554 | &pllb, | ||
555 | |||
556 | /* PLLB children (USB) */ | ||
557 | &udpck, | ||
558 | &uhpck, | ||
559 | |||
560 | /* MCK */ | ||
561 | &mck | ||
562 | }; | ||
563 | |||
564 | int __init at91_clock_init(unsigned long main_clock) | ||
565 | { | ||
566 | unsigned tmp, freq, mckr; | ||
567 | int i; | ||
568 | |||
569 | /* | ||
570 | * When the bootloader initialized the main oscillator correctly, | ||
571 | * there's no problem using the cycle counter. But if it didn't, | ||
572 | * or when using oscillator bypass mode, we must be told the speed | ||
573 | * of the main clock. | ||
574 | */ | ||
575 | if (!main_clock) { | ||
576 | do { | ||
577 | tmp = at91_sys_read(AT91_CKGR_MCFR); | ||
578 | } while (!(tmp & AT91_PMC_MAINRDY)); | ||
579 | main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); | ||
580 | } | ||
581 | main_clk.rate_hz = main_clock; | ||
582 | |||
583 | /* report if PLLA is more than mildly overclocked */ | ||
584 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); | ||
585 | if (plla.rate_hz > 209000000) | ||
586 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); | ||
587 | |||
588 | /* | ||
589 | * USB clock init: choose 48 MHz PLLB value, turn all clocks off, | ||
590 | * disable 48MHz clock during usb peripheral suspend. | ||
591 | * | ||
592 | * REVISIT: assumes MCK doesn't derive from PLLB! | ||
593 | */ | ||
594 | at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; | ||
595 | pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); | ||
596 | if (cpu_is_at91rm9200()) { | ||
597 | uhpck.pmc_mask = AT91RM9200_PMC_UHP; | ||
598 | udpck.pmc_mask = AT91RM9200_PMC_UDP; | ||
599 | at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP); | ||
600 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); | ||
601 | } else if (cpu_is_at91sam9260()) { | ||
602 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | ||
603 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | ||
604 | at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP); | ||
605 | } else if (cpu_is_at91sam9261()) { | ||
606 | uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0); | ||
607 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | ||
608 | at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP); | ||
609 | } | ||
610 | at91_sys_write(AT91_CKGR_PLLBR, 0); | ||
611 | |||
612 | udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
613 | uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
614 | |||
615 | /* | ||
616 | * MCK and CPU derive from one of those primary clocks. | ||
617 | * For now, assume this parentage won't change. | ||
618 | */ | ||
619 | mckr = at91_sys_read(AT91_PMC_MCKR); | ||
620 | mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); | ||
621 | freq = mck.parent->rate_hz; | ||
622 | freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ | ||
623 | mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ | ||
624 | |||
625 | /* Register the PMC's standard clocks */ | ||
626 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | ||
627 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); | ||
628 | |||
629 | /* MCK and CPU clock are "always on" */ | ||
630 | clk_enable(&mck); | ||
631 | |||
632 | printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", | ||
633 | freq / 1000000, (unsigned) mck.rate_hz / 1000000, | ||
634 | (unsigned) main_clock / 1000000, | ||
635 | ((unsigned) main_clock % 1000000) / 1000); | ||
636 | |||
637 | /* disable all programmable clocks */ | ||
638 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); | ||
639 | |||
640 | /* disable all other unused peripheral clocks */ | ||
641 | at91_periphclk_reset(); | ||
642 | |||
643 | return 0; | ||
644 | } | ||