diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:48:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:48:14 -0700 |
commit | 2ca7d674d7ab2220707b2ada0b690c0e7c95e7ac (patch) | |
tree | 9c0927ed1d540e5fd704c1f82689870786514655 /arch/arm/mach-at91/clock.c | |
parent | 2195d2818c37bdf263865f1e9effccdd9fc5f9d4 (diff) | |
parent | 87d721ad7a37b7650dd710c88dd5c6a5bf9fe996 (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (257 commits)
[ARM] Update mach-types
ARM: 5636/1: Move vendor enum to AMBA include
ARM: Fix pfn_valid() for sparse memory
[ARM] orion5x: Add LaCie NAS 2Big Network support
[ARM] pxa/sharpsl_pm: zaurus c3000 aka spitz: fix resume
ARM: 5686/1: at91: Correct AC97 reset line in at91sam9263ek board
ARM: 5640/1: This patch modifies the support of AC97 on the at91sam9263 ek board
ARM: 5689/1: Update default config of HP Jornada 700-series machines
ARM: 5691/1: fix cache aliasing issues between kmap() and kmap_atomic() with highmem
ARM: 5688/1: ks8695_serial: disable_irq() lockup
ARM: 5687/1: fix an oops with highmem
ARM: 5684/1: Add nuc960 platform to w90x900
ARM: 5683/1: Add nuc950 platform to w90x900
ARM: 5682/1: Add cpu.c and dev.c and modify some files of w90p910 platform
ARM: 5626/1: add suspend/resume functions to amba-pl011 serial driver
ARM: 5625/1: fix hard coded 4K resource size in amba bus detection
MMC: MMCI: convert realview MMC to use gpiolib
ARM: 5685/1: Make MMCI driver compile without gpiolib
ARM: implement highpte
ARM: Show FIQ in /proc/interrupts on CONFIG_FIQ
...
Fix up trivial conflict in arch/arm/kernel/signal.c.
It was due to the TIF_NOTIFY_RESUME addition in commit d0420c83f ("KEYS:
Extend TIF_NOTIFY_RESUME to (almost) all architectures") and follow-ups.
Diffstat (limited to 'arch/arm/mach-at91/clock.c')
-rw-r--r-- | arch/arm/mach-at91/clock.c | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index bac578fe0d3..c042dcf4725 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -47,20 +47,25 @@ * Chips have some kind of clocks : group them by functionality */ #define cpu_has_utmi() ( cpu_is_at91cap9() \ - || cpu_is_at91sam9rl()) + || cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45()) -#define cpu_has_800M_plla() (cpu_is_at91sam9g20()) +#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ + || cpu_is_at91sam9g45()) -#define cpu_has_pllb() (!cpu_is_at91sam9rl()) +#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) -#define cpu_has_upll() (0) +#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45())) + +#define cpu_has_upll() (cpu_is_at91sam9g45()) /* USB host HS & FS */ #define cpu_has_uhp() (!cpu_is_at91sam9rl()) /* USB device FS only */ -#define cpu_has_udpfs() (!cpu_is_at91sam9rl()) - +#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45())) static LIST_HEAD(clocks); static DEFINE_SPINLOCK(clk_lock); @@ -133,6 +138,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on) { unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); + if (cpu_is_at91sam9g45()) { + if (is_on) + uckr |= AT91_PMC_BIASEN; + else + uckr &= ~AT91_PMC_BIASEN; + } + if (is_on) { is_on = AT91_PMC_LOCKU; at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); @@ -310,6 +322,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) unsigned long flags; unsigned prescale; unsigned long actual; + unsigned long prev = ULONG_MAX; if (!clk_is_programmable(clk)) return -EINVAL; @@ -317,8 +330,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate) actual = clk->parent->rate_hz; for (prescale = 0; prescale < 7; prescale++) { - if (actual && actual <= rate) + if (actual > rate) + prev = actual; + + if (actual && actual <= rate) { + if ((prev - rate) < (rate - actual)) { + actual = prev; + prescale--; + } break; + } actual >>= 1; } @@ -373,6 +394,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent) return -EBUSY; if (!clk_is_primary(parent) || !clk_is_programmable(clk)) return -EINVAL; + + if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB) + return -EINVAL; + spin_lock_irqsave(&clk_lock, flags); clk->rate_hz = parent->rate_hz; @@ -601,7 +626,9 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) uhpck.pmc_mask = AT91RM9200_PMC_UHP; udpck.pmc_mask = AT91RM9200_PMC_UDP; at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || + cpu_is_at91sam9263() || cpu_is_at91sam9g20() || + cpu_is_at91sam9g10()) { uhpck.pmc_mask = AT91SAM926x_PMC_UHP; udpck.pmc_mask = AT91SAM926x_PMC_UDP; } else if (cpu_is_at91cap9()) { @@ -637,6 +664,7 @@ int __init at91_clock_init(unsigned long main_clock) { unsigned tmp, freq, mckr; int i; + int pll_overclock = false; /* * When the bootloader initialized the main oscillator correctly, @@ -654,12 +682,25 @@ int __init at91_clock_init(unsigned long main_clock) /* report if PLLA is more than mildly overclocked */ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); - if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000) - || (cpu_has_800M_plla() && plla.rate_hz > 800000000)) + if (cpu_has_300M_plla()) { + if (plla.rate_hz > 300000000) + pll_overclock = true; + } else if (cpu_has_800M_plla()) { + if (plla.rate_hz > 800000000) + pll_overclock = true; + } else { + if (plla.rate_hz > 209000000) + pll_overclock = true; + } + if (pll_overclock) pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); + if (cpu_is_at91sam9g45()) { + mckr = at91_sys_read(AT91_PMC_MCKR); + plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ + } - if (cpu_has_upll() && !cpu_has_pllb()) { + if (!cpu_has_pllb() && cpu_has_upll()) { /* setup UTMI clock as the fourth primary clock * (instead of pllb) */ utmi_clk.type |= CLK_TYPE_PRIMARY; @@ -701,6 +742,9 @@ int __init at91_clock_init(unsigned long main_clock) freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ if (mckr & AT91_PMC_PDIV) freq /= 2; /* processor clock division */ + } else if (cpu_is_at91sam9g45()) { + mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? + freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } else { mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } |