clock-r8a7740.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * R8A7740 processor support
  3. *
  4. * Copyright (C) 2011 Renesas Solutions Corp.
  5. * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include <linux/init.h>
  21. #include <linux/kernel.h>
  22. #include <linux/io.h>
  23. #include <linux/sh_clk.h>
  24. #include <linux/clkdev.h>
  25. #include <mach/common.h>
  26. #include <mach/r8a7740.h>
  27. /*
  28. * | MDx | XTAL1/EXTAL1 | System | EXTALR |
  29. * Clock |-------+-----------------+ clock | 32.768 | RCLK
  30. * Mode | 2/1/0 | src MHz | source | KHz | source
  31. * -------+-------+-----------------+-----------+--------+----------
  32. * 0 | 0 0 0 | External 20~50 | XTAL1 | O | EXTALR
  33. * 1 | 0 0 1 | Crystal 20~30 | XTAL1 | O | EXTALR
  34. * 2 | 0 1 0 | External 40~50 | XTAL1 / 2 | O | EXTALR
  35. * 3 | 0 1 1 | Crystal 40~50 | XTAL1 / 2 | O | EXTALR
  36. * 4 | 1 0 0 | External 20~50 | XTAL1 | x | XTAL1 / 1024
  37. * 5 | 1 0 1 | Crystal 20~30 | XTAL1 | x | XTAL1 / 1024
  38. * 6 | 1 1 0 | External 40~50 | XTAL1 / 2 | x | XTAL1 / 2048
  39. * 7 | 1 1 1 | Crystal 40~50 | XTAL1 / 2 | x | XTAL1 / 2048
  40. */
  41. /* CPG registers */
  42. #define FRQCRA 0xe6150000
  43. #define FRQCRB 0xe6150004
  44. #define FRQCRC 0xe61500e0
  45. #define PLLC01CR 0xe6150028
  46. #define SUBCKCR 0xe6150080
  47. #define MSTPSR0 0xe6150030
  48. #define MSTPSR1 0xe6150038
  49. #define MSTPSR2 0xe6150040
  50. #define MSTPSR3 0xe6150048
  51. #define MSTPSR4 0xe615004c
  52. #define SMSTPCR0 0xe6150130
  53. #define SMSTPCR1 0xe6150134
  54. #define SMSTPCR2 0xe6150138
  55. #define SMSTPCR3 0xe615013c
  56. #define SMSTPCR4 0xe6150140
  57. /* Fixed 32 KHz root clock from EXTALR pin */
  58. static struct clk extalr_clk = {
  59. .rate = 32768,
  60. };
  61. /*
  62. * 25MHz default rate for the EXTAL1 root input clock.
  63. * If needed, reset this with clk_set_rate() from the platform code.
  64. */
  65. static struct clk extal1_clk = {
  66. .rate = 25000000,
  67. };
  68. /*
  69. * 48MHz default rate for the EXTAL2 root input clock.
  70. * If needed, reset this with clk_set_rate() from the platform code.
  71. */
  72. static struct clk extal2_clk = {
  73. .rate = 48000000,
  74. };
  75. /*
  76. * 27MHz default rate for the DV_CLKI root input clock.
  77. * If needed, reset this with clk_set_rate() from the platform code.
  78. */
  79. static struct clk dv_clk = {
  80. .rate = 27000000,
  81. };
  82. static unsigned long div_recalc(struct clk *clk)
  83. {
  84. return clk->parent->rate / (int)(clk->priv);
  85. }
  86. static struct sh_clk_ops div_clk_ops = {
  87. .recalc = div_recalc,
  88. };
  89. /* extal1 / 2 */
  90. static struct clk extal1_div2_clk = {
  91. .ops = &div_clk_ops,
  92. .priv = (void *)2,
  93. .parent = &extal1_clk,
  94. };
  95. /* extal1 / 1024 */
  96. static struct clk extal1_div1024_clk = {
  97. .ops = &div_clk_ops,
  98. .priv = (void *)1024,
  99. .parent = &extal1_clk,
  100. };
  101. /* extal1 / 2 / 1024 */
  102. static struct clk extal1_div2048_clk = {
  103. .ops = &div_clk_ops,
  104. .priv = (void *)1024,
  105. .parent = &extal1_div2_clk,
  106. };
  107. /* extal2 / 2 */
  108. static struct clk extal2_div2_clk = {
  109. .ops = &div_clk_ops,
  110. .priv = (void *)2,
  111. .parent = &extal2_clk,
  112. };
  113. static struct sh_clk_ops followparent_clk_ops = {
  114. .recalc = followparent_recalc,
  115. };
  116. /* Main clock */
  117. static struct clk system_clk = {
  118. .ops = &followparent_clk_ops,
  119. };
  120. static struct clk system_div2_clk = {
  121. .ops = &div_clk_ops,
  122. .priv = (void *)2,
  123. .parent = &system_clk,
  124. };
  125. /* r_clk */
  126. static struct clk r_clk = {
  127. .ops = &followparent_clk_ops,
  128. };
  129. /* PLLC0/PLLC1 */
  130. static unsigned long pllc01_recalc(struct clk *clk)
  131. {
  132. unsigned long mult = 1;
  133. if (__raw_readl(PLLC01CR) & (1 << 14))
  134. mult = ((__raw_readl(clk->enable_reg) >> 24) & 0x7f) + 1;
  135. return clk->parent->rate * mult;
  136. }
  137. static struct sh_clk_ops pllc01_clk_ops = {
  138. .recalc = pllc01_recalc,
  139. };
  140. static struct clk pllc0_clk = {
  141. .ops = &pllc01_clk_ops,
  142. .flags = CLK_ENABLE_ON_INIT,
  143. .parent = &system_clk,
  144. .enable_reg = (void __iomem *)FRQCRC,
  145. };
  146. static struct clk pllc1_clk = {
  147. .ops = &pllc01_clk_ops,
  148. .flags = CLK_ENABLE_ON_INIT,
  149. .parent = &system_div2_clk,
  150. .enable_reg = (void __iomem *)FRQCRA,
  151. };
  152. /* PLLC1 / 2 */
  153. static struct clk pllc1_div2_clk = {
  154. .ops = &div_clk_ops,
  155. .priv = (void *)2,
  156. .parent = &pllc1_clk,
  157. };
  158. struct clk *main_clks[] = {
  159. &extalr_clk,
  160. &extal1_clk,
  161. &extal2_clk,
  162. &extal1_div2_clk,
  163. &extal1_div1024_clk,
  164. &extal1_div2048_clk,
  165. &extal2_div2_clk,
  166. &dv_clk,
  167. &system_clk,
  168. &system_div2_clk,
  169. &r_clk,
  170. &pllc0_clk,
  171. &pllc1_clk,
  172. &pllc1_div2_clk,
  173. };
  174. static void div4_kick(struct clk *clk)
  175. {
  176. unsigned long value;
  177. /* set KICK bit in FRQCRB to update hardware setting */
  178. value = __raw_readl(FRQCRB);
  179. value |= (1 << 31);
  180. __raw_writel(value, FRQCRB);
  181. }
  182. static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
  183. 24, 32, 36, 48, 0, 72, 96, 0 };
  184. static struct clk_div_mult_table div4_div_mult_table = {
  185. .divisors = divisors,
  186. .nr_divisors = ARRAY_SIZE(divisors),
  187. };
  188. static struct clk_div4_table div4_table = {
  189. .div_mult_table = &div4_div_mult_table,
  190. .kick = div4_kick,
  191. };
  192. enum {
  193. DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
  194. DIV4_HPP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
  195. DIV4_NR
  196. };
  197. struct clk div4_clks[DIV4_NR] = {
  198. [DIV4_I] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
  199. [DIV4_ZG] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
  200. [DIV4_B] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
  201. [DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
  202. [DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0),
  203. [DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
  204. [DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
  205. [DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0),
  206. [DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0),
  207. [DIV4_CP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 0, 0x6fff, 0),
  208. };
  209. enum {
  210. DIV6_SUB,
  211. DIV6_NR
  212. };
  213. static struct clk div6_clks[DIV6_NR] = {
  214. [DIV6_SUB] = SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
  215. };
  216. enum {
  217. MSTP125,
  218. MSTP116, MSTP111, MSTP100, MSTP117,
  219. MSTP230,
  220. MSTP222,
  221. MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
  222. MSTP329, MSTP323,
  223. MSTP_NR
  224. };
  225. static struct clk mstp_clks[MSTP_NR] = {
  226. [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
  227. [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
  228. [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
  229. [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
  230. [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
  231. [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
  232. [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
  233. [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
  234. [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
  235. [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
  236. [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
  237. [MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
  238. [MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
  239. [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
  240. [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
  241. [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
  242. };
  243. static struct clk_lookup lookups[] = {
  244. /* main clocks */
  245. CLKDEV_CON_ID("extalr", &extalr_clk),
  246. CLKDEV_CON_ID("extal1", &extal1_clk),
  247. CLKDEV_CON_ID("extal2", &extal2_clk),
  248. CLKDEV_CON_ID("extal1_div2", &extal1_div2_clk),
  249. CLKDEV_CON_ID("extal1_div1024", &extal1_div1024_clk),
  250. CLKDEV_CON_ID("extal1_div2048", &extal1_div2048_clk),
  251. CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk),
  252. CLKDEV_CON_ID("dv_clk", &dv_clk),
  253. CLKDEV_CON_ID("system_clk", &system_clk),
  254. CLKDEV_CON_ID("system_div2_clk", &system_div2_clk),
  255. CLKDEV_CON_ID("r_clk", &r_clk),
  256. CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
  257. CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
  258. CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
  259. /* DIV4 clocks */
  260. CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
  261. CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
  262. CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
  263. CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
  264. CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
  265. CLKDEV_CON_ID("hpp_clk", &div4_clks[DIV4_HPP]),
  266. CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
  267. CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
  268. CLKDEV_CON_ID("m3_clk", &div4_clks[DIV4_M3]),
  269. CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
  270. /* DIV6 clocks */
  271. CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
  272. /* MSTP32 clocks */
  273. CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
  274. CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP111]),
  275. CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
  276. CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
  277. CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
  278. CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
  279. CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
  280. CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]),
  281. CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
  282. CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
  283. CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
  284. CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
  285. CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
  286. CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
  287. CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
  288. CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
  289. };
  290. void __init r8a7740_clock_init(u8 md_ck)
  291. {
  292. int k, ret = 0;
  293. /* detect system clock parent */
  294. if (md_ck & MD_CK1)
  295. system_clk.parent = &extal1_div2_clk;
  296. else
  297. system_clk.parent = &extal1_clk;
  298. /* detect RCLK parent */
  299. switch (md_ck & (MD_CK2 | MD_CK1)) {
  300. case MD_CK2 | MD_CK1:
  301. r_clk.parent = &extal1_div2048_clk;
  302. break;
  303. case MD_CK2:
  304. r_clk.parent = &extal1_div1024_clk;
  305. break;
  306. case MD_CK1:
  307. default:
  308. r_clk.parent = &extalr_clk;
  309. break;
  310. }
  311. for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
  312. ret = clk_register(main_clks[k]);
  313. if (!ret)
  314. ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
  315. if (!ret)
  316. ret = sh_clk_div6_register(div6_clks, DIV6_NR);
  317. if (!ret)
  318. ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
  319. clkdev_add_table(lookups, ARRAY_SIZE(lookups));
  320. if (!ret)
  321. shmobile_clk_init();
  322. else
  323. panic("failed to setup r8a7740 clocks\n");
  324. }