clocks.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. * clocks.c - figure out sclk/cclk/vco and such
  3. *
  4. * Copyright (c) 2005-2008 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <asm/blackfin.h>
  10. /* Get the voltage input multiplier */
  11. static u_long cached_vco_pll_ctl, cached_vco;
  12. u_long get_vco(void)
  13. {
  14. u_long msel;
  15. u_long pll_ctl = bfin_read_PLL_CTL();
  16. if (pll_ctl == cached_vco_pll_ctl)
  17. return cached_vco;
  18. else
  19. cached_vco_pll_ctl = pll_ctl;
  20. msel = (pll_ctl >> 9) & 0x3F;
  21. if (0 == msel)
  22. msel = 64;
  23. cached_vco = CONFIG_CLKIN_HZ;
  24. cached_vco >>= (1 & pll_ctl); /* DF bit */
  25. cached_vco *= msel;
  26. return cached_vco;
  27. }
  28. /* Get the Core clock */
  29. static u_long cached_cclk_pll_div, cached_cclk;
  30. u_long get_cclk(void)
  31. {
  32. u_long csel, ssel;
  33. if (bfin_read_PLL_STAT() & 0x1)
  34. return CONFIG_CLKIN_HZ;
  35. ssel = bfin_read_PLL_DIV();
  36. if (ssel == cached_cclk_pll_div)
  37. return cached_cclk;
  38. else
  39. cached_cclk_pll_div = ssel;
  40. csel = ((ssel >> 4) & 0x03);
  41. ssel &= 0xf;
  42. if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
  43. cached_cclk = get_vco() / ssel;
  44. else
  45. cached_cclk = get_vco() >> csel;
  46. return cached_cclk;
  47. }
  48. /* Get the System clock */
  49. static u_long cached_sclk_pll_div, cached_sclk;
  50. u_long get_sclk(void)
  51. {
  52. u_long ssel;
  53. if (bfin_read_PLL_STAT() & 0x1)
  54. return CONFIG_CLKIN_HZ;
  55. ssel = bfin_read_PLL_DIV();
  56. if (ssel == cached_sclk_pll_div)
  57. return cached_sclk;
  58. else
  59. cached_sclk_pll_div = ssel;
  60. ssel &= 0xf;
  61. cached_sclk = get_vco() / ssel;
  62. return cached_sclk;
  63. }