clock-sh7785.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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 <linux/cpufreq.h>
  17. #include <asm/clock.h>
  18. #include <asm/freq.h>
  19. static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
  20. 24, 32, 36, 48 };
  21. struct clk_priv {
  22. unsigned int shift;
  23. /* allowable divisor bitmap */
  24. unsigned long div_bitmap;
  25. /* Supportable frequencies + termination entry */
  26. struct cpufreq_frequency_table freq_table[ARRAY_SIZE(div2)+1];
  27. };
  28. #define FRQMR_CLK_DATA(_name, _shift, _div_bitmap) \
  29. static struct clk_priv _name##_data = { \
  30. .shift = _shift, \
  31. .div_bitmap = _div_bitmap, \
  32. \
  33. .freq_table[0] = { \
  34. .index = 0, \
  35. .frequency = CPUFREQ_TABLE_END, \
  36. }, \
  37. }
  38. FRQMR_CLK_DATA(pfc, 0, 0x0f80);
  39. FRQMR_CLK_DATA(s3fc, 4, 0x0ff0);
  40. FRQMR_CLK_DATA(s2fc, 8, 0x0030);
  41. FRQMR_CLK_DATA(mfc, 12, 0x000c);
  42. FRQMR_CLK_DATA(bfc, 16, 0x0fe0);
  43. FRQMR_CLK_DATA(sfc, 20, 0x000c);
  44. FRQMR_CLK_DATA(ufc, 24, 0x000c);
  45. FRQMR_CLK_DATA(ifc, 28, 0x000e);
  46. static unsigned long frqmr_recalc(struct clk *clk)
  47. {
  48. struct clk_priv *data = clk->priv;
  49. unsigned int idx;
  50. idx = (__raw_readl(FRQMR1) >> data->shift) & 0x000f;
  51. return clk->parent->rate / div2[idx];
  52. }
  53. static void frqmr_build_rate_table(struct clk *clk)
  54. {
  55. struct clk_priv *data = clk->priv;
  56. int i, entry;
  57. for (i = entry = 0; i < ARRAY_SIZE(div2); i++) {
  58. if ((data->div_bitmap & (1 << i)) == 0)
  59. continue;
  60. data->freq_table[entry].index = entry;
  61. data->freq_table[entry].frequency =
  62. clk->parent->rate / div2[i];
  63. entry++;
  64. }
  65. if (entry == 0) {
  66. pr_warning("clkfwk: failed to build frequency table "
  67. "for \"%s\" clk!\n", clk->name);
  68. return;
  69. }
  70. /* Termination entry */
  71. data->freq_table[entry].index = entry;
  72. data->freq_table[entry].frequency = CPUFREQ_TABLE_END;
  73. }
  74. static long frqmr_round_rate(struct clk *clk, unsigned long rate)
  75. {
  76. struct clk_priv *data = clk->priv;
  77. unsigned long rate_error, rate_error_prev = ~0UL;
  78. unsigned long rate_best_fit = rate;
  79. unsigned long highest, lowest;
  80. int i;
  81. highest = lowest = 0;
  82. for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
  83. unsigned long freq = data->freq_table[i].frequency;
  84. if (freq == CPUFREQ_ENTRY_INVALID)
  85. continue;
  86. if (freq > highest)
  87. highest = freq;
  88. if (freq < lowest)
  89. lowest = freq;
  90. rate_error = abs(freq - rate);
  91. if (rate_error < rate_error_prev) {
  92. rate_best_fit = freq;
  93. rate_error_prev = rate_error;
  94. }
  95. if (rate_error == 0)
  96. break;
  97. }
  98. if (rate >= highest)
  99. rate_best_fit = highest;
  100. if (rate <= lowest)
  101. rate_best_fit = lowest;
  102. return rate_best_fit;
  103. }
  104. static struct clk_ops frqmr_clk_ops = {
  105. .recalc = frqmr_recalc,
  106. .build_rate_table = frqmr_build_rate_table,
  107. .round_rate = frqmr_round_rate,
  108. };
  109. static unsigned long pll_recalc(struct clk *clk)
  110. {
  111. /*
  112. * XXX: PLL1 multiplier is locked for the default clock mode,
  113. * when mode pin detection and configuration support is added,
  114. * select the multiplier dynamically.
  115. */
  116. return clk->parent->rate * 36;
  117. }
  118. static struct clk_ops pll_clk_ops = {
  119. .recalc = pll_recalc,
  120. };
  121. /*
  122. * Default rate for the root input clock, reset this with clk_set_rate()
  123. * from the platform code.
  124. */
  125. static struct clk extal_clk = {
  126. .name = "extal",
  127. .id = -1,
  128. .rate = 33333333,
  129. };
  130. static struct clk pll_clk = {
  131. .name = "pll_clk",
  132. .id = -1,
  133. .ops = &pll_clk_ops,
  134. .parent = &extal_clk,
  135. .flags = CLK_ENABLE_ON_INIT,
  136. };
  137. static struct clk cpu_clk = {
  138. .name = "cpu_clk", /* Ick */
  139. .id = -1,
  140. .ops = &frqmr_clk_ops,
  141. .parent = &pll_clk,
  142. .flags = CLK_ENABLE_ON_INIT,
  143. .priv = &ifc_data,
  144. };
  145. static struct clk shyway_clk = {
  146. .name = "shyway_clk", /* SHck */
  147. .id = -1,
  148. .ops = &frqmr_clk_ops,
  149. .parent = &pll_clk,
  150. .flags = CLK_ENABLE_ON_INIT,
  151. .priv = &sfc_data,
  152. };
  153. static struct clk peripheral_clk = {
  154. .name = "peripheral_clk", /* Pck */
  155. .id = -1,
  156. .ops = &frqmr_clk_ops,
  157. .parent = &pll_clk,
  158. .flags = CLK_ENABLE_ON_INIT,
  159. .priv = &pfc_data,
  160. };
  161. static struct clk ddr_clk = {
  162. .name = "ddr_clk", /* DDRck */
  163. .id = -1,
  164. .ops = &frqmr_clk_ops,
  165. .parent = &pll_clk,
  166. .flags = CLK_ENABLE_ON_INIT,
  167. .priv = &mfc_data,
  168. };
  169. static struct clk bus_clk = {
  170. .name = "bus_clk", /* Bck */
  171. .id = -1,
  172. .ops = &frqmr_clk_ops,
  173. .parent = &pll_clk,
  174. .flags = CLK_ENABLE_ON_INIT,
  175. .priv = &bfc_data,
  176. };
  177. static struct clk ga_clk = {
  178. .name = "ga_clk", /* GAck */
  179. .id = -1,
  180. .ops = &frqmr_clk_ops,
  181. .parent = &pll_clk,
  182. .priv = &s2fc_data,
  183. };
  184. static struct clk du_clk = {
  185. .name = "du_clk", /* DUck */
  186. .id = -1,
  187. .ops = &frqmr_clk_ops,
  188. .parent = &pll_clk,
  189. .priv = &s3fc_data,
  190. };
  191. static struct clk umem_clk = {
  192. .name = "umem_clk", /* uck */
  193. .id = -1,
  194. .ops = &frqmr_clk_ops,
  195. .parent = &pll_clk,
  196. .flags = CLK_ENABLE_ON_INIT,
  197. .priv = &ufc_data,
  198. };
  199. static struct clk *clks[] = {
  200. &extal_clk,
  201. &pll_clk,
  202. &cpu_clk,
  203. &shyway_clk,
  204. &peripheral_clk,
  205. &ddr_clk,
  206. &bus_clk,
  207. &ga_clk,
  208. &du_clk,
  209. &umem_clk,
  210. };
  211. static int mstpcr_clk_enable(struct clk *clk)
  212. {
  213. __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
  214. clk->enable_reg);
  215. return 0;
  216. }
  217. static void mstpcr_clk_disable(struct clk *clk)
  218. {
  219. __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
  220. clk->enable_reg);
  221. }
  222. static struct clk_ops mstpcr_clk_ops = {
  223. .enable = mstpcr_clk_enable,
  224. .disable = mstpcr_clk_disable,
  225. .recalc = followparent_recalc,
  226. };
  227. #define MSTPCR0 0xffc80030
  228. #define MSTPCR1 0xffc80034
  229. #define CLK(_name, _id, _parent, _enable_reg, \
  230. _enable_bit, _flags) \
  231. { \
  232. .name = _name, \
  233. .id = _id, \
  234. .parent = _parent, \
  235. .enable_reg = (void __iomem *)_enable_reg, \
  236. .enable_bit = _enable_bit, \
  237. .flags = _flags, \
  238. .ops = &mstpcr_clk_ops, \
  239. }
  240. static struct clk mstpcr_clks[] = {
  241. /* MSTPCR0 */
  242. CLK("scif_fck", 5, &peripheral_clk, MSTPCR0, 29, 0),
  243. CLK("scif_fck", 4, &peripheral_clk, MSTPCR0, 28, 0),
  244. CLK("scif_fck", 3, &peripheral_clk, MSTPCR0, 27, 0),
  245. CLK("scif_fck", 2, &peripheral_clk, MSTPCR0, 26, 0),
  246. CLK("scif_fck", 1, &peripheral_clk, MSTPCR0, 25, 0),
  247. CLK("scif_fck", 0, &peripheral_clk, MSTPCR0, 24, 0),
  248. CLK("ssi_fck", 1, &peripheral_clk, MSTPCR0, 21, 0),
  249. CLK("ssi_fck", 0, &peripheral_clk, MSTPCR0, 20, 0),
  250. CLK("hac_fck", 1, &peripheral_clk, MSTPCR0, 17, 0),
  251. CLK("hac_fck", 0, &peripheral_clk, MSTPCR0, 16, 0),
  252. CLK("mmcif_fck", -1, &peripheral_clk, MSTPCR0, 13, 0),
  253. CLK("flctl_fck", -1, &peripheral_clk, MSTPCR0, 12, 0),
  254. CLK("tmu345_fck", -1, &peripheral_clk, MSTPCR0, 9, 0),
  255. CLK("tmu012_fck", -1, &peripheral_clk, MSTPCR0, 8, 0),
  256. CLK("siof_fck", -1, &peripheral_clk, MSTPCR0, 3, 0),
  257. CLK("hspi_fck", -1, &peripheral_clk, MSTPCR0, 2, 0),
  258. /* MSTPCR1 */
  259. CLK("hudi_fck", -1, NULL, MSTPCR1, 19, 0),
  260. CLK("ubc_fck", -1, NULL, MSTPCR1, 17, 0),
  261. CLK("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0),
  262. CLK("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0),
  263. CLK("gdta_fck", -1, NULL, MSTPCR1, 0, 0),
  264. };
  265. int __init arch_clk_init(void)
  266. {
  267. int i, ret = 0;
  268. for (i = 0; i < ARRAY_SIZE(clks); i++)
  269. ret |= clk_register(clks[i]);
  270. for (i = 0; i < ARRAY_SIZE(mstpcr_clks); i++)
  271. ret |= clk_register(&mstpcr_clks[i]);
  272. return ret;
  273. }