clock.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (C) 2012 Analog Devices Inc.
  3. * Licensed under the GPL-2 or later.
  4. */
  5. #ifndef __CLOCK_H__
  6. #define __CLOCK_H__
  7. #include <asm/blackfin.h>
  8. #ifdef PLL_CTL
  9. #include <asm/mach-common/bits/pll.h>
  10. # define pll_is_bypassed() (bfin_read_PLL_CTL() & BYPASS)
  11. #else
  12. #include <asm/mach-common/bits/cgu.h>
  13. # define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP)
  14. # define bfin_read_PLL_CTL() bfin_read_CGU_CTL()
  15. # define bfin_read_PLL_DIV() bfin_read_CGU_DIV()
  16. # define SSEL SYSSEL
  17. # define SSEL_P SYSSEL_P
  18. #endif
  19. __attribute__((always_inline))
  20. static inline uint32_t early_division(uint32_t dividend, uint32_t divisor)
  21. {
  22. uint32_t quotient;
  23. uint32_t i, j;
  24. for (quotient = 1, i = 1; dividend > divisor; ++i) {
  25. j = divisor << i;
  26. if (j > dividend || (j & 0x80000000)) {
  27. --i;
  28. quotient += (1 << i);
  29. dividend -= (divisor << i);
  30. i = 0;
  31. }
  32. }
  33. return quotient;
  34. }
  35. __attribute__((always_inline))
  36. static inline uint32_t early_get_uart_clk(void)
  37. {
  38. uint32_t msel, pll_ctl, vco;
  39. uint32_t div, ssel, sclk, uclk;
  40. pll_ctl = bfin_read_PLL_CTL();
  41. msel = (pll_ctl & MSEL) >> MSEL_P;
  42. if (msel == 0)
  43. msel = (MSEL >> MSEL_P) + 1;
  44. vco = (CONFIG_CLKIN_HZ >> (pll_ctl & DF)) * msel;
  45. sclk = vco;
  46. if (!pll_is_bypassed()) {
  47. div = bfin_read_PLL_DIV();
  48. ssel = (div & SSEL) >> SSEL_P;
  49. #if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
  50. sclk = vco/ssel;
  51. #else
  52. sclk = early_division(vco, ssel);
  53. #endif
  54. }
  55. uclk = sclk;
  56. #ifdef CGU_DIV
  57. ssel = (div & S0SEL) >> S0SEL_P;
  58. uclk = early_division(sclk, ssel);
  59. #endif
  60. return uclk;
  61. }
  62. extern u_long get_vco(void);
  63. extern u_long get_cclk(void);
  64. extern u_long get_sclk(void);
  65. #ifdef CGU_DIV
  66. extern u_long get_sclk0(void);
  67. extern u_long get_sclk1(void);
  68. extern u_long get_dclk(void);
  69. # define get_uart_clk get_sclk0
  70. # define get_i2c_clk get_sclk0
  71. # define get_spi_clk get_sclk1
  72. #else
  73. # define get_uart_clk get_sclk
  74. # define get_i2c_clk get_sclk
  75. # define get_spi_clk get_sclk
  76. #endif
  77. #endif