diff options
Diffstat (limited to 'arch/arm/mach-at91rm9200/clock.c')
| -rw-r--r-- | arch/arm/mach-at91rm9200/clock.c | 85 |
1 files changed, 73 insertions, 12 deletions
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index ec8195a2a3cc..8b95467c6d61 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c | |||
| @@ -201,6 +201,54 @@ static struct clk ohci_clk = { | |||
| 201 | .pmc_mask = 1 << AT91_ID_UHP, | 201 | .pmc_mask = 1 << AT91_ID_UHP, |
| 202 | .mode = pmc_periph_mode, | 202 | .mode = pmc_periph_mode, |
| 203 | }; | 203 | }; |
| 204 | static struct clk ether_clk = { | ||
| 205 | .name = "ether_clk", | ||
| 206 | .parent = &mck, | ||
| 207 | .pmc_mask = 1 << AT91_ID_EMAC, | ||
| 208 | .mode = pmc_periph_mode, | ||
| 209 | }; | ||
| 210 | static struct clk mmc_clk = { | ||
| 211 | .name = "mci_clk", | ||
| 212 | .parent = &mck, | ||
| 213 | .pmc_mask = 1 << AT91_ID_MCI, | ||
| 214 | .mode = pmc_periph_mode, | ||
| 215 | }; | ||
| 216 | static struct clk twi_clk = { | ||
| 217 | .name = "twi_clk", | ||
| 218 | .parent = &mck, | ||
| 219 | .pmc_mask = 1 << AT91_ID_TWI, | ||
| 220 | .mode = pmc_periph_mode, | ||
| 221 | }; | ||
| 222 | static struct clk usart0_clk = { | ||
| 223 | .name = "usart0_clk", | ||
| 224 | .parent = &mck, | ||
| 225 | .pmc_mask = 1 << AT91_ID_US0, | ||
| 226 | .mode = pmc_periph_mode, | ||
| 227 | }; | ||
| 228 | static struct clk usart1_clk = { | ||
| 229 | .name = "usart1_clk", | ||
| 230 | .parent = &mck, | ||
| 231 | .pmc_mask = 1 << AT91_ID_US1, | ||
| 232 | .mode = pmc_periph_mode, | ||
| 233 | }; | ||
| 234 | static struct clk usart2_clk = { | ||
| 235 | .name = "usart2_clk", | ||
| 236 | .parent = &mck, | ||
| 237 | .pmc_mask = 1 << AT91_ID_US2, | ||
| 238 | .mode = pmc_periph_mode, | ||
| 239 | }; | ||
| 240 | static struct clk usart3_clk = { | ||
| 241 | .name = "usart3_clk", | ||
| 242 | .parent = &mck, | ||
| 243 | .pmc_mask = 1 << AT91_ID_US3, | ||
| 244 | .mode = pmc_periph_mode, | ||
| 245 | }; | ||
| 246 | static struct clk spi_clk = { | ||
| 247 | .name = "spi0_clk", | ||
| 248 | .parent = &mck, | ||
| 249 | .pmc_mask = 1 << AT91_ID_SPI, | ||
| 250 | .mode = pmc_periph_mode, | ||
| 251 | }; | ||
| 204 | 252 | ||
| 205 | static struct clk *const clock_list[] = { | 253 | static struct clk *const clock_list[] = { |
| 206 | /* four primary clocks -- MUST BE FIRST! */ | 254 | /* four primary clocks -- MUST BE FIRST! */ |
| @@ -223,15 +271,18 @@ static struct clk *const clock_list[] = { | |||
| 223 | 271 | ||
| 224 | /* MCK and peripherals */ | 272 | /* MCK and peripherals */ |
| 225 | &mck, | 273 | &mck, |
| 226 | // usart0..usart3 | 274 | &usart0_clk, |
| 227 | // mmc | 275 | &usart1_clk, |
| 276 | &usart2_clk, | ||
| 277 | &usart3_clk, | ||
| 278 | &mmc_clk, | ||
| 228 | &udc_clk, | 279 | &udc_clk, |
| 229 | // i2c | 280 | &twi_clk, |
| 230 | // spi | 281 | &spi_clk, |
| 231 | // ssc0..ssc2 | 282 | // ssc0..ssc2 |
| 232 | // tc0..tc5 | 283 | // tc0..tc5 |
| 233 | &ohci_clk, | 284 | &ohci_clk, |
| 234 | // ether | 285 | ðer_clk, |
| 235 | }; | 286 | }; |
| 236 | 287 | ||
| 237 | 288 | ||
| @@ -360,7 +411,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
| 360 | u32 pckr; | 411 | u32 pckr; |
| 361 | 412 | ||
| 362 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | 413 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); |
| 363 | pckr &= 0x03; | 414 | pckr &= AT91_PMC_CSS_PLLB; /* clock selection */ |
| 364 | pckr |= prescale << 2; | 415 | pckr |= prescale << 2; |
| 365 | at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); | 416 | at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); |
| 366 | clk->rate_hz = actual; | 417 | clk->rate_hz = actual; |
| @@ -440,7 +491,7 @@ static int at91_clk_show(struct seq_file *s, void *unused) | |||
| 440 | else | 491 | else |
| 441 | state = ""; | 492 | state = ""; |
| 442 | 493 | ||
| 443 | seq_printf(s, "%-10s users=%d %-3s %9ld Hz %s\n", | 494 | seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", |
| 444 | clk->name, clk->users, state, clk_get_rate(clk), | 495 | clk->name, clk->users, state, clk_get_rate(clk), |
| 445 | clk->parent ? clk->parent->name : ""); | 496 | clk->parent ? clk->parent->name : ""); |
| 446 | } | 497 | } |
| @@ -483,11 +534,18 @@ static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) | |||
| 483 | freq *= mul + 1; | 534 | freq *= mul + 1; |
| 484 | } else | 535 | } else |
| 485 | freq = 0; | 536 | freq = 0; |
| 486 | if (pll == &pllb && (reg & (1 << 28))) | 537 | |
| 487 | freq /= 2; | ||
| 488 | return freq; | 538 | return freq; |
| 489 | } | 539 | } |
| 490 | 540 | ||
| 541 | static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) | ||
| 542 | { | ||
| 543 | if (pll == &pllb && (reg & AT91_PMC_USB96M)) | ||
| 544 | return freq / 2; | ||
| 545 | else | ||
| 546 | return freq; | ||
| 547 | } | ||
| 548 | |||
| 491 | static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) | 549 | static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) |
| 492 | { | 550 | { |
| 493 | unsigned i, div = 0, mul = 0, diff = 1 << 30; | 551 | unsigned i, div = 0, mul = 0, diff = 1 << 30; |
| @@ -550,8 +608,8 @@ int __init at91_clock_init(unsigned long main_clock) | |||
| 550 | if (!main_clock) { | 608 | if (!main_clock) { |
| 551 | do { | 609 | do { |
| 552 | tmp = at91_sys_read(AT91_CKGR_MCFR); | 610 | tmp = at91_sys_read(AT91_CKGR_MCFR); |
| 553 | } while (!(tmp & 0x10000)); | 611 | } while (!(tmp & AT91_PMC_MAINRDY)); |
| 554 | main_clock = (tmp & 0xffff) * (AT91_SLOW_CLOCK / 16); | 612 | main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); |
| 555 | } | 613 | } |
| 556 | main_clk.rate_hz = main_clock; | 614 | main_clk.rate_hz = main_clock; |
| 557 | 615 | ||
| @@ -566,13 +624,16 @@ int __init at91_clock_init(unsigned long main_clock) | |||
| 566 | * | 624 | * |
| 567 | * REVISIT: assumes MCK doesn't derive from PLLB! | 625 | * REVISIT: assumes MCK doesn't derive from PLLB! |
| 568 | */ | 626 | */ |
| 569 | at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | 0x10000000; | 627 | at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; |
| 570 | pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); | 628 | pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); |
| 571 | at91_sys_write(AT91_PMC_PCDR, (1 << AT91_ID_UHP) | (1 << AT91_ID_UDP)); | 629 | at91_sys_write(AT91_PMC_PCDR, (1 << AT91_ID_UHP) | (1 << AT91_ID_UDP)); |
| 572 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP); | 630 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP); |
| 573 | at91_sys_write(AT91_CKGR_PLLBR, 0); | 631 | at91_sys_write(AT91_CKGR_PLLBR, 0); |
| 574 | at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP); | 632 | at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP); |
| 575 | 633 | ||
| 634 | udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
| 635 | uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
| 636 | |||
| 576 | /* | 637 | /* |
| 577 | * MCK and CPU derive from one of those primary clocks. | 638 | * MCK and CPU derive from one of those primary clocks. |
| 578 | * For now, assume this parentage won't change. | 639 | * For now, assume this parentage won't change. |
