diff options
| -rw-r--r-- | arch/arm/mach-at91/clock.c | 62 |
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 | ||
| 65 | static LIST_HEAD(clocks); | 70 | static LIST_HEAD(clocks); |
| 66 | static DEFINE_SPINLOCK(clk_lock); | 71 | static 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 | } |
