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.c83
1 files changed, 64 insertions, 19 deletions
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index aa04e22a9da6..a5291e0e7004 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -48,24 +48,37 @@
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_at91sam9rl() \ 50#define cpu_has_utmi() ( cpu_is_at91sam9rl() \
51 || cpu_is_at91sam9g45()) 51 || cpu_is_at91sam9g45() \
52 || cpu_is_at91sam9x5())
52 53
53#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ 54#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
54 || cpu_is_at91sam9g45()) 55 || cpu_is_at91sam9g45() \
56 || cpu_is_at91sam9x5())
55 57
56#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) 58#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
57 59
58#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ 60#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
59 || cpu_is_at91sam9g45())) 61 || cpu_is_at91sam9g45() \
62 || cpu_is_at91sam9x5()))
60 63
61#define cpu_has_upll() (cpu_is_at91sam9g45()) 64#define cpu_has_upll() (cpu_is_at91sam9g45() \
65 || cpu_is_at91sam9x5())
62 66
63/* USB host HS & FS */ 67/* USB host HS & FS */
64#define cpu_has_uhp() (!cpu_is_at91sam9rl()) 68#define cpu_has_uhp() (!cpu_is_at91sam9rl())
65 69
66/* USB device FS only */ 70/* USB device FS only */
67#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ 71#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
68 || 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())
69 82
70static LIST_HEAD(clocks); 83static LIST_HEAD(clocks);
71static DEFINE_SPINLOCK(clk_lock); 84static DEFINE_SPINLOCK(clk_lock);
@@ -138,13 +151,6 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
138{ 151{
139 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); 152 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
140 153
141 if (cpu_is_at91sam9g45()) {
142 if (is_on)
143 uckr |= AT91_PMC_BIASEN;
144 else
145 uckr &= ~AT91_PMC_BIASEN;
146 }
147
148 if (is_on) { 154 if (is_on) {
149 is_on = AT91_PMC_LOCKU; 155 is_on = AT91_PMC_LOCKU;
150 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); 156 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -209,11 +215,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
209 return &utmi_clk; 215 return &utmi_clk;
210 else if (cpu_has_pllb()) 216 else if (cpu_has_pllb())
211 return &pllb; 217 return &pllb;
218 break;
219 /* alternate PMC: can use master clock */
220 case AT91_PMC_CSS_MASTER:
221 return &mck;
212 } 222 }
213 223
214 return NULL; 224 return NULL;
215} 225}
216 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
217static void __clk_enable(struct clk *clk) 236static void __clk_enable(struct clk *clk)
218{ 237{
219 if (clk->parent) 238 if (clk->parent)
@@ -315,12 +334,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
315{ 334{
316 unsigned long flags; 335 unsigned long flags;
317 unsigned prescale; 336 unsigned prescale;
337 unsigned long prescale_offset, css_mask;
318 unsigned long actual; 338 unsigned long actual;
319 339
320 if (!clk_is_programmable(clk)) 340 if (!clk_is_programmable(clk))
321 return -EINVAL; 341 return -EINVAL;
322 if (clk->users) 342 if (clk->users)
323 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
324 spin_lock_irqsave(&clk_lock, flags); 353 spin_lock_irqsave(&clk_lock, flags);
325 354
326 actual = clk->parent->rate_hz; 355 actual = clk->parent->rate_hz;
@@ -329,8 +358,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
329 u32 pckr; 358 u32 pckr;
330 359
331 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); 360 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
332 pckr &= AT91_PMC_CSS; /* clock selection */ 361 pckr &= css_mask; /* keep clock selection */
333 pckr |= prescale << 2; 362 pckr |= prescale << prescale_offset;
334 at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); 363 at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
335 clk->rate_hz = actual; 364 clk->rate_hz = actual;
336 break; 365 break;
@@ -377,11 +406,17 @@ static void __init init_programmable_clock(struct clk *clk)
377{ 406{
378 struct clk *parent; 407 struct clk *parent;
379 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;
380 415
381 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); 416 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
382 parent = at91_css_to_clk(pckr & AT91_PMC_CSS); 417 parent = at91_css_to_clk(pckr & css_mask);
383 clk->parent = parent; 418 clk->parent = parent;
384 clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); 419 clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
385} 420}
386 421
387#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ 422#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -663,7 +698,7 @@ int __init at91_clock_init(unsigned long main_clock)
663 if (pll_overclock) 698 if (pll_overclock)
664 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);
665 700
666 if (cpu_is_at91sam9g45()) { 701 if (cpu_has_plladiv2()) {
667 mckr = at91_sys_read(AT91_PMC_MCKR); 702 mckr = at91_sys_read(AT91_PMC_MCKR);
668 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 */
669 } 704 }
@@ -685,6 +720,10 @@ int __init at91_clock_init(unsigned long main_clock)
685 * (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)
686 */ 721 */
687 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;
688 } 727 }
689 728
690 /* 729 /*
@@ -703,7 +742,7 @@ int __init at91_clock_init(unsigned long main_clock)
703 mckr = at91_sys_read(AT91_PMC_MCKR); 742 mckr = at91_sys_read(AT91_PMC_MCKR);
704 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); 743 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
705 freq = mck.parent->rate_hz; 744 freq = mck.parent->rate_hz;
706 freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ 745 freq /= pmc_prescaler_divider(mckr); /* prescale */
707 if (cpu_is_at91rm9200()) { 746 if (cpu_is_at91rm9200()) {
708 mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 747 mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
709 } else if (cpu_is_at91sam9g20()) { 748 } else if (cpu_is_at91sam9g20()) {
@@ -711,13 +750,19 @@ int __init at91_clock_init(unsigned long main_clock)
711 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) */
712 if (mckr & AT91_PMC_PDIV) 751 if (mckr & AT91_PMC_PDIV)
713 freq /= 2; /* processor clock division */ 752 freq /= 2; /* processor clock division */
714 } else if (cpu_is_at91sam9g45()) { 753 } else if (cpu_has_mdiv3()) {
715 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? 754 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
716 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 755 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
717 } else { 756 } else {
718 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 757 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
719 } 758 }
720 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
721 /* Register the PMC's standard clocks */ 766 /* Register the PMC's standard clocks */
722 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) 767 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
723 at91_clk_add(standard_pmc_clocks[i]); 768 at91_clk_add(standard_pmc_clocks[i]);