aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-at91/clock.c')
-rw-r--r--arch/arm/mach-at91/clock.c88
1 files changed, 65 insertions, 23 deletions
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 61873f3aa92d..a5291e0e7004 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -47,26 +47,38 @@
47/* 47/*
48 * Chips have some kind of clocks : group them by functionality 48 * Chips have some kind of clocks : group them by functionality
49 */ 49 */
50#define cpu_has_utmi() ( cpu_is_at91cap9() \ 50#define cpu_has_utmi() ( cpu_is_at91sam9rl() \
51 || cpu_is_at91sam9rl() \ 51 || cpu_is_at91sam9g45() \
52 || cpu_is_at91sam9g45()) 52 || cpu_is_at91sam9x5())
53 53
54#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ 54#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
55 || cpu_is_at91sam9g45()) 55 || cpu_is_at91sam9g45() \
56 || cpu_is_at91sam9x5())
56 57
57#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) 58#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
58 59
59#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ 60#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
60 || cpu_is_at91sam9g45())) 61 || cpu_is_at91sam9g45() \
62 || cpu_is_at91sam9x5()))
61 63
62#define cpu_has_upll() (cpu_is_at91sam9g45()) 64#define cpu_has_upll() (cpu_is_at91sam9g45() \
65 || cpu_is_at91sam9x5())
63 66
64/* USB host HS & FS */ 67/* USB host HS & FS */
65#define cpu_has_uhp() (!cpu_is_at91sam9rl()) 68#define cpu_has_uhp() (!cpu_is_at91sam9rl())
66 69
67/* USB device FS only */ 70/* USB device FS only */
68#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ 71#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
69 || cpu_is_at91sam9g45())) 72 || cpu_is_at91sam9g45() \
73 || cpu_is_at91sam9x5()))
74
75#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \
76 || cpu_is_at91sam9x5())
77
78#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \
79 || cpu_is_at91sam9x5())
80
81#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5())
70 82
71static LIST_HEAD(clocks); 83static LIST_HEAD(clocks);
72static DEFINE_SPINLOCK(clk_lock); 84static DEFINE_SPINLOCK(clk_lock);
@@ -139,13 +151,6 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
139{ 151{
140 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); 152 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
141 153
142 if (cpu_is_at91sam9g45()) {
143 if (is_on)
144 uckr |= AT91_PMC_BIASEN;
145 else
146 uckr &= ~AT91_PMC_BIASEN;
147 }
148
149 if (is_on) { 154 if (is_on) {
150 is_on = AT91_PMC_LOCKU; 155 is_on = AT91_PMC_LOCKU;
151 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); 156 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -210,11 +215,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
210 return &utmi_clk; 215 return &utmi_clk;
211 else if (cpu_has_pllb()) 216 else if (cpu_has_pllb())
212 return &pllb; 217 return &pllb;
218 break;
219 /* alternate PMC: can use master clock */
220 case AT91_PMC_CSS_MASTER:
221 return &mck;
213 } 222 }
214 223
215 return NULL; 224 return NULL;
216} 225}
217 226
227static int pmc_prescaler_divider(u32 reg)
228{
229 if (cpu_has_alt_prescaler()) {
230 return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET);
231 } else {
232 return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET);
233 }
234}
235
218static void __clk_enable(struct clk *clk) 236static void __clk_enable(struct clk *clk)
219{ 237{
220 if (clk->parent) 238 if (clk->parent)
@@ -316,12 +334,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
316{ 334{
317 unsigned long flags; 335 unsigned long flags;
318 unsigned prescale; 336 unsigned prescale;
337 unsigned long prescale_offset, css_mask;
319 unsigned long actual; 338 unsigned long actual;
320 339
321 if (!clk_is_programmable(clk)) 340 if (!clk_is_programmable(clk))
322 return -EINVAL; 341 return -EINVAL;
323 if (clk->users) 342 if (clk->users)
324 return -EBUSY; 343 return -EBUSY;
344
345 if (cpu_has_alt_prescaler()) {
346 prescale_offset = PMC_ALT_PRES_OFFSET;
347 css_mask = AT91_PMC_ALT_PCKR_CSS;
348 } else {
349 prescale_offset = PMC_PRES_OFFSET;
350 css_mask = AT91_PMC_CSS;
351 }
352
325 spin_lock_irqsave(&clk_lock, flags); 353 spin_lock_irqsave(&clk_lock, flags);
326 354
327 actual = clk->parent->rate_hz; 355 actual = clk->parent->rate_hz;
@@ -330,8 +358,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
330 u32 pckr; 358 u32 pckr;
331 359
332 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); 360 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
333 pckr &= AT91_PMC_CSS; /* clock selection */ 361 pckr &= css_mask; /* keep clock selection */
334 pckr |= prescale << 2; 362 pckr |= prescale << prescale_offset;
335 at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); 363 at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
336 clk->rate_hz = actual; 364 clk->rate_hz = actual;
337 break; 365 break;
@@ -378,11 +406,17 @@ static void __init init_programmable_clock(struct clk *clk)
378{ 406{
379 struct clk *parent; 407 struct clk *parent;
380 u32 pckr; 408 u32 pckr;
409 unsigned int css_mask;
410
411 if (cpu_has_alt_prescaler())
412 css_mask = AT91_PMC_ALT_PCKR_CSS;
413 else
414 css_mask = AT91_PMC_CSS;
381 415
382 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); 416 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
383 parent = at91_css_to_clk(pckr & AT91_PMC_CSS); 417 parent = at91_css_to_clk(pckr & css_mask);
384 clk->parent = parent; 418 clk->parent = parent;
385 clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); 419 clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
386} 420}
387 421
388#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ 422#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -602,8 +636,6 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
602 cpu_is_at91sam9g10()) { 636 cpu_is_at91sam9g10()) {
603 uhpck.pmc_mask = AT91SAM926x_PMC_UHP; 637 uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
604 udpck.pmc_mask = AT91SAM926x_PMC_UDP; 638 udpck.pmc_mask = AT91SAM926x_PMC_UDP;
605 } else if (cpu_is_at91cap9()) {
606 uhpck.pmc_mask = AT91CAP9_PMC_UHP;
607 } 639 }
608 at91_sys_write(AT91_CKGR_PLLBR, 0); 640 at91_sys_write(AT91_CKGR_PLLBR, 0);
609 641
@@ -666,7 +698,7 @@ int __init at91_clock_init(unsigned long main_clock)
666 if (pll_overclock) 698 if (pll_overclock)
667 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); 699 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
668 700
669 if (cpu_is_at91sam9g45()) { 701 if (cpu_has_plladiv2()) {
670 mckr = at91_sys_read(AT91_PMC_MCKR); 702 mckr = at91_sys_read(AT91_PMC_MCKR);
671 plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ 703 plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
672 } 704 }
@@ -688,6 +720,10 @@ int __init at91_clock_init(unsigned long main_clock)
688 * (obtain the USB High Speed 480 MHz when input is 12 MHz) 720 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
689 */ 721 */
690 utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; 722 utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
723
724 /* UTMI bias and PLL are managed at the same time */
725 if (cpu_has_upll())
726 utmi_clk.pmc_mask |= AT91_PMC_BIASEN;
691 } 727 }
692 728
693 /* 729 /*
@@ -706,7 +742,7 @@ int __init at91_clock_init(unsigned long main_clock)
706 mckr = at91_sys_read(AT91_PMC_MCKR); 742 mckr = at91_sys_read(AT91_PMC_MCKR);
707 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); 743 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
708 freq = mck.parent->rate_hz; 744 freq = mck.parent->rate_hz;
709 freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ 745 freq /= pmc_prescaler_divider(mckr); /* prescale */
710 if (cpu_is_at91rm9200()) { 746 if (cpu_is_at91rm9200()) {
711 mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 747 mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
712 } else if (cpu_is_at91sam9g20()) { 748 } else if (cpu_is_at91sam9g20()) {
@@ -714,13 +750,19 @@ int __init at91_clock_init(unsigned long main_clock)
714 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ 750 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
715 if (mckr & AT91_PMC_PDIV) 751 if (mckr & AT91_PMC_PDIV)
716 freq /= 2; /* processor clock division */ 752 freq /= 2; /* processor clock division */
717 } else if (cpu_is_at91sam9g45()) { 753 } else if (cpu_has_mdiv3()) {
718 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? 754 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
719 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 755 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
720 } else { 756 } else {
721 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 757 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
722 } 758 }
723 759
760 if (cpu_has_alt_prescaler()) {
761 /* Programmable clocks can use MCK */
762 mck.type |= CLK_TYPE_PRIMARY;
763 mck.id = 4;
764 }
765
724 /* Register the PMC's standard clocks */ 766 /* Register the PMC's standard clocks */
725 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) 767 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
726 at91_clk_add(standard_pmc_clocks[i]); 768 at91_clk_add(standard_pmc_clocks[i]);