clock.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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_STAT() & DF)
  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. sclk = early_division(vco, ssel);
  50. }
  51. uclk = sclk;
  52. #ifdef CGU_DIV
  53. ssel = (div & S0SEL) >> S0SEL_P;
  54. uclk = early_division(sclk, ssel);
  55. #endif
  56. return uclk;
  57. }
  58. #ifdef CGU_DIV
  59. # define get_uart_clk get_sclk0
  60. #else
  61. # define get_uart_clk get_sclk
  62. #endif
  63. #endif