clock-sh7785.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * arch/sh/kernel/cpu/sh4a/clock-sh7785.c
  3. *
  4. * SH7785 support for the clock framework
  5. *
  6. * Copyright (C) 2007 - 2009 Paul Mundt
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file "COPYING" in the main directory of this archive
  10. * for more details.
  11. */
  12. #include <linux/init.h>
  13. #include <linux/kernel.h>
  14. #include <linux/clk.h>
  15. #include <linux/io.h>
  16. #include <asm/clock.h>
  17. #include <asm/freq.h>
  18. static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
  19. 24, 32, 36, 48 };
  20. struct clk_priv {
  21. unsigned int shift;
  22. };
  23. #define FRQMR_CLK_DATA(_name, _shift) \
  24. static struct clk_priv _name##_data = { .shift = _shift, }
  25. FRQMR_CLK_DATA(pfc, 0);
  26. FRQMR_CLK_DATA(s3fc, 4);
  27. FRQMR_CLK_DATA(s2fc, 8);
  28. FRQMR_CLK_DATA(mfc, 12);
  29. FRQMR_CLK_DATA(bfc, 16);
  30. FRQMR_CLK_DATA(sfc, 20);
  31. FRQMR_CLK_DATA(ufc, 24);
  32. FRQMR_CLK_DATA(ifc, 28);
  33. static unsigned long frqmr_clk_recalc(struct clk *clk)
  34. {
  35. struct clk_priv *data = clk->priv;
  36. unsigned int idx;
  37. idx = (__raw_readl(FRQMR1) >> data->shift) & 0x000f;
  38. /*
  39. * XXX: PLL1 multiplier is locked for the default clock mode,
  40. * when mode pin detection and configuration support is added,
  41. * select the multiplier dynamically.
  42. */
  43. return clk->parent->rate * 36 / div2[idx];
  44. }
  45. static struct clk_ops frqmr_clk_ops = {
  46. .recalc = frqmr_clk_recalc,
  47. };
  48. /*
  49. * Default rate for the root input clock, reset this with clk_set_rate()
  50. * from the platform code.
  51. */
  52. static struct clk extal_clk = {
  53. .name = "extal",
  54. .id = -1,
  55. .rate = 33333333,
  56. };
  57. static struct clk cpu_clk = {
  58. .name = "cpu_clk", /* Ick */
  59. .id = -1,
  60. .ops = &frqmr_clk_ops,
  61. .parent = &extal_clk,
  62. .flags = CLK_ENABLE_ON_INIT,
  63. .priv = &ifc_data,
  64. };
  65. static struct clk shyway_clk = {
  66. .name = "shyway_clk", /* SHck */
  67. .id = -1,
  68. .ops = &frqmr_clk_ops,
  69. .parent = &extal_clk,
  70. .flags = CLK_ENABLE_ON_INIT,
  71. .priv = &sfc_data,
  72. };
  73. static struct clk peripheral_clk = {
  74. .name = "peripheral_clk", /* Pck */
  75. .id = -1,
  76. .ops = &frqmr_clk_ops,
  77. .parent = &extal_clk,
  78. .flags = CLK_ENABLE_ON_INIT,
  79. .priv = &pfc_data,
  80. };
  81. static struct clk ddr_clk = {
  82. .name = "ddr_clk", /* DDRck */
  83. .id = -1,
  84. .ops = &frqmr_clk_ops,
  85. .parent = &extal_clk,
  86. .flags = CLK_ENABLE_ON_INIT,
  87. .priv = &mfc_data,
  88. };
  89. static struct clk bus_clk = {
  90. .name = "bus_clk", /* Bck */
  91. .id = -1,
  92. .ops = &frqmr_clk_ops,
  93. .parent = &extal_clk,
  94. .flags = CLK_ENABLE_ON_INIT,
  95. .priv = &bfc_data,
  96. };
  97. static struct clk ga_clk = {
  98. .name = "ga_clk", /* GAck */
  99. .id = -1,
  100. .ops = &frqmr_clk_ops,
  101. .parent = &extal_clk,
  102. .priv = &s2fc_data,
  103. };
  104. static struct clk du_clk = {
  105. .name = "du_clk", /* DUck */
  106. .id = -1,
  107. .ops = &frqmr_clk_ops,
  108. .parent = &extal_clk,
  109. .priv = &s3fc_data,
  110. };
  111. static struct clk umem_clk = {
  112. .name = "umem_clk", /* uck */
  113. .id = -1,
  114. .ops = &frqmr_clk_ops,
  115. .parent = &extal_clk,
  116. .flags = CLK_ENABLE_ON_INIT,
  117. .priv = &ufc_data,
  118. };
  119. static struct clk *clks[] = {
  120. &extal_clk,
  121. &cpu_clk,
  122. &shyway_clk,
  123. &peripheral_clk,
  124. &ddr_clk,
  125. &bus_clk,
  126. &ga_clk,
  127. &du_clk,
  128. &umem_clk,
  129. };
  130. int __init arch_clk_init(void)
  131. {
  132. int i, ret = 0;
  133. for (i = 0; i < ARRAY_SIZE(clks); i++)
  134. ret |= clk_register(clks[i]);
  135. return ret;
  136. }