clock.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
  3. *
  4. * Copyright (C) 2005 David Brownell
  5. * Copyright (C) 2005 Ivan Kokshaysky
  6. * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
  7. * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. */
  14. #include <common.h>
  15. #include <asm/io.h>
  16. #include <asm/arch/hardware.h>
  17. #include <asm/arch/at91_pmc.h>
  18. #include <asm/arch/clk.h>
  19. #if !defined(CONFIG_AT91FAMILY)
  20. # error You need to define CONFIG_AT91FAMILY in your board config!
  21. #endif
  22. DECLARE_GLOBAL_DATA_PTR;
  23. static unsigned long at91_css_to_rate(unsigned long css)
  24. {
  25. switch (css) {
  26. case AT91_PMC_MCKR_CSS_SLOW:
  27. return CONFIG_SYS_AT91_SLOW_CLOCK;
  28. case AT91_PMC_MCKR_CSS_MAIN:
  29. return gd->arch.main_clk_rate_hz;
  30. case AT91_PMC_MCKR_CSS_PLLA:
  31. return gd->arch.plla_rate_hz;
  32. }
  33. return 0;
  34. }
  35. static u32 at91_pll_rate(u32 freq, u32 reg)
  36. {
  37. unsigned mul, div;
  38. div = reg & 0xff;
  39. mul = (reg >> 18) & 0x7f;
  40. if (div && mul) {
  41. freq /= div;
  42. freq *= mul + 1;
  43. } else {
  44. freq = 0;
  45. }
  46. return freq;
  47. }
  48. int at91_clock_init(unsigned long main_clock)
  49. {
  50. unsigned freq, mckr;
  51. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  52. #ifndef CONFIG_SYS_AT91_MAIN_CLOCK
  53. unsigned tmp;
  54. /*
  55. * When the bootloader initialized the main oscillator correctly,
  56. * there's no problem using the cycle counter. But if it didn't,
  57. * or when using oscillator bypass mode, we must be told the speed
  58. * of the main clock.
  59. */
  60. if (!main_clock) {
  61. do {
  62. tmp = readl(&pmc->mcfr);
  63. } while (!(tmp & AT91_PMC_MCFR_MAINRDY));
  64. tmp &= AT91_PMC_MCFR_MAINF_MASK;
  65. main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
  66. }
  67. #endif
  68. gd->arch.main_clk_rate_hz = main_clock;
  69. /* report if PLLA is more than mildly overclocked */
  70. gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
  71. /*
  72. * MCK and CPU derive from one of those primary clocks.
  73. * For now, assume this parentage won't change.
  74. */
  75. mckr = readl(&pmc->mckr);
  76. /* plla divisor by 2 */
  77. if (mckr & (1 << 12))
  78. gd->arch.plla_rate_hz >>= 1;
  79. gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
  80. freq = gd->arch.mck_rate_hz;
  81. /* prescale */
  82. freq >>= mckr & AT91_PMC_MCKR_PRES_MASK;
  83. switch (mckr & AT91_PMC_MCKR_MDIV_MASK) {
  84. case AT91_PMC_MCKR_MDIV_2:
  85. gd->arch.mck_rate_hz = freq / 2;
  86. break;
  87. case AT91_PMC_MCKR_MDIV_3:
  88. gd->arch.mck_rate_hz = freq / 3;
  89. break;
  90. case AT91_PMC_MCKR_MDIV_4:
  91. gd->arch.mck_rate_hz = freq / 4;
  92. break;
  93. default:
  94. break;
  95. }
  96. gd->arch.cpu_clk_rate_hz = freq;
  97. return 0;
  98. }
  99. void at91_periph_clk_enable(int id)
  100. {
  101. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  102. if (id > 31)
  103. writel(1 << (id - 32), &pmc->pcer1);
  104. else
  105. writel(1 << id, &pmc->pcer);
  106. }