aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/clock.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index bac578fe0d3d..6396680271e8 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -47,20 +47,25 @@
47 * Chips have some kind of clocks : group them by functionality 47 * Chips have some kind of clocks : group them by functionality
48 */ 48 */
49#define cpu_has_utmi() ( cpu_is_at91cap9() \ 49#define cpu_has_utmi() ( cpu_is_at91cap9() \
50 || cpu_is_at91sam9rl()) 50 || cpu_is_at91sam9rl() \
51 || cpu_is_at91sam9g45())
51 52
52#define cpu_has_800M_plla() (cpu_is_at91sam9g20()) 53#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
54 || cpu_is_at91sam9g45())
53 55
54#define cpu_has_pllb() (!cpu_is_at91sam9rl()) 56#define cpu_has_300M_plla() (0)
55 57
56#define cpu_has_upll() (0) 58#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
59 || cpu_is_at91sam9g45()))
60
61#define cpu_has_upll() (cpu_is_at91sam9g45())
57 62
58/* USB host HS & FS */ 63/* USB host HS & FS */
59#define cpu_has_uhp() (!cpu_is_at91sam9rl()) 64#define cpu_has_uhp() (!cpu_is_at91sam9rl())
60 65
61/* USB device FS only */ 66/* USB device FS only */
62#define cpu_has_udpfs() (!cpu_is_at91sam9rl()) 67#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
63 68 || cpu_is_at91sam9g45()))
64 69
65static LIST_HEAD(clocks); 70static LIST_HEAD(clocks);
66static DEFINE_SPINLOCK(clk_lock); 71static DEFINE_SPINLOCK(clk_lock);
@@ -133,6 +138,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
133{ 138{
134 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); 139 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
135 140
141 if (cpu_is_at91sam9g45()) {
142 if (is_on)
143 uckr |= AT91_PMC_BIASEN;
144 else
145 uckr &= ~AT91_PMC_BIASEN;
146 }
147
136 if (is_on) { 148 if (is_on) {
137 is_on = AT91_PMC_LOCKU; 149 is_on = AT91_PMC_LOCKU;
138 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); 150 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -310,6 +322,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
310 unsigned long flags; 322 unsigned long flags;
311 unsigned prescale; 323 unsigned prescale;
312 unsigned long actual; 324 unsigned long actual;
325 unsigned long prev = ULONG_MAX;
313 326
314 if (!clk_is_programmable(clk)) 327 if (!clk_is_programmable(clk))
315 return -EINVAL; 328 return -EINVAL;
@@ -317,8 +330,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
317 330
318 actual = clk->parent->rate_hz; 331 actual = clk->parent->rate_hz;
319 for (prescale = 0; prescale < 7; prescale++) { 332 for (prescale = 0; prescale < 7; prescale++) {
320 if (actual && actual <= rate) 333 if (actual > rate)
334 prev = actual;
335
336 if (actual && actual <= rate) {
337 if ((prev - rate) < (rate - actual)) {
338 actual = prev;
339 prescale--;
340 }
321 break; 341 break;
342 }
322 actual >>= 1; 343 actual >>= 1;
323 } 344 }
324 345
@@ -373,6 +394,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
373 return -EBUSY; 394 return -EBUSY;
374 if (!clk_is_primary(parent) || !clk_is_programmable(clk)) 395 if (!clk_is_primary(parent) || !clk_is_programmable(clk))
375 return -EINVAL; 396 return -EINVAL;
397
398 if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB)
399 return -EINVAL;
400
376 spin_lock_irqsave(&clk_lock, flags); 401 spin_lock_irqsave(&clk_lock, flags);
377 402
378 clk->rate_hz = parent->rate_hz; 403 clk->rate_hz = parent->rate_hz;
@@ -637,6 +662,7 @@ int __init at91_clock_init(unsigned long main_clock)
637{ 662{
638 unsigned tmp, freq, mckr; 663 unsigned tmp, freq, mckr;
639 int i; 664 int i;
665 int pll_overclock = false;
640 666
641 /* 667 /*
642 * When the bootloader initialized the main oscillator correctly, 668 * When the bootloader initialized the main oscillator correctly,
@@ -654,12 +680,25 @@ int __init at91_clock_init(unsigned long main_clock)
654 680
655 /* report if PLLA is more than mildly overclocked */ 681 /* report if PLLA is more than mildly overclocked */
656 plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); 682 plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
657 if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000) 683 if (cpu_has_300M_plla()) {
658 || (cpu_has_800M_plla() && plla.rate_hz > 800000000)) 684 if (plla.rate_hz > 300000000)
685 pll_overclock = true;
686 } else if (cpu_has_800M_plla()) {
687 if (plla.rate_hz > 800000000)
688 pll_overclock = true;
689 } else {
690 if (plla.rate_hz > 209000000)
691 pll_overclock = true;
692 }
693 if (pll_overclock)
659 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); 694 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
660 695
696 if (cpu_is_at91sam9g45()) {
697 mckr = at91_sys_read(AT91_PMC_MCKR);
698 plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
699 }
661 700
662 if (cpu_has_upll() && !cpu_has_pllb()) { 701 if (!cpu_has_pllb() && cpu_has_upll()) {
663 /* setup UTMI clock as the fourth primary clock 702 /* setup UTMI clock as the fourth primary clock
664 * (instead of pllb) */ 703 * (instead of pllb) */
665 utmi_clk.type |= CLK_TYPE_PRIMARY; 704 utmi_clk.type |= CLK_TYPE_PRIMARY;
@@ -701,6 +740,9 @@ int __init at91_clock_init(unsigned long main_clock)
701 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ 740 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
702 if (mckr & AT91_PMC_PDIV) 741 if (mckr & AT91_PMC_PDIV)
703 freq /= 2; /* processor clock division */ 742 freq /= 2; /* processor clock division */
743 } else if (cpu_is_at91sam9g45()) {
744 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
745 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
704 } else { 746 } else {
705 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 747 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
706 } 748 }