gxbb.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
  4. * (C) Copyright 2018 - BayLibre, SAS
  5. * Author: Neil Armstrong <narmstrong@baylibre.com>
  6. */
  7. #include <common.h>
  8. #include <log.h>
  9. #include <asm/arch/clock-gx.h>
  10. #include <asm/io.h>
  11. #include <clk-uclass.h>
  12. #include <div64.h>
  13. #include <dm.h>
  14. #include <regmap.h>
  15. #include <syscon.h>
  16. #include <dt-bindings/clock/gxbb-clkc.h>
  17. #include <linux/bitops.h>
  18. #include "clk_meson.h"
  19. #include <linux/err.h>
  20. /* This driver support only basic clock tree operations :
  21. * - Can calculate clock frequency on a limited tree
  22. * - Can Read muxes and basic dividers (0-based only)
  23. * - Can enable/disable gates with limited propagation
  24. * - Can reparent without propagation, only on muxes
  25. * - Can set rates without reparenting
  26. * This driver is adapted to what is actually supported by U-Boot
  27. */
  28. /* Only the clocks ids we don't want to expose, such as the internal muxes
  29. * and dividers of composite clocks, will remain defined here.
  30. */
  31. #define CLKID_MPEG_SEL 10
  32. #define CLKID_MPEG_DIV 11
  33. #define CLKID_SAR_ADC_DIV 99
  34. #define CLKID_MALI_0_DIV 101
  35. #define CLKID_MALI_1_DIV 104
  36. #define CLKID_CTS_AMCLK_SEL 108
  37. #define CLKID_CTS_AMCLK_DIV 109
  38. #define CLKID_CTS_MCLK_I958_SEL 111
  39. #define CLKID_CTS_MCLK_I958_DIV 112
  40. #define CLKID_32K_CLK_SEL 115
  41. #define CLKID_32K_CLK_DIV 116
  42. #define CLKID_SD_EMMC_A_CLK0_SEL 117
  43. #define CLKID_SD_EMMC_A_CLK0_DIV 118
  44. #define CLKID_SD_EMMC_B_CLK0_SEL 120
  45. #define CLKID_SD_EMMC_B_CLK0_DIV 121
  46. #define CLKID_SD_EMMC_C_CLK0_SEL 123
  47. #define CLKID_SD_EMMC_C_CLK0_DIV 124
  48. #define CLKID_VPU_0_DIV 127
  49. #define CLKID_VPU_1_DIV 130
  50. #define CLKID_VAPB_0_DIV 134
  51. #define CLKID_VAPB_1_DIV 137
  52. #define CLKID_HDMI_PLL_PRE_MULT 141
  53. #define CLKID_MPLL0_DIV 142
  54. #define CLKID_MPLL1_DIV 143
  55. #define CLKID_MPLL2_DIV 144
  56. #define CLKID_MPLL_PREDIV 145
  57. #define CLKID_FCLK_DIV2_DIV 146
  58. #define CLKID_FCLK_DIV3_DIV 147
  59. #define CLKID_FCLK_DIV4_DIV 148
  60. #define CLKID_FCLK_DIV5_DIV 149
  61. #define CLKID_FCLK_DIV7_DIV 150
  62. #define CLKID_VDEC_1_SEL 151
  63. #define CLKID_VDEC_1_DIV 152
  64. #define CLKID_VDEC_HEVC_SEL 154
  65. #define CLKID_VDEC_HEVC_DIV 155
  66. #define XTAL_RATE 24000000
  67. struct meson_clk {
  68. struct regmap *map;
  69. };
  70. static ulong meson_div_get_rate(struct clk *clk, unsigned long id);
  71. static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate,
  72. ulong current_rate);
  73. static ulong meson_mux_set_parent(struct clk *clk, unsigned long id,
  74. unsigned long parent_id);
  75. static ulong meson_mux_get_rate(struct clk *clk, unsigned long id);
  76. static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id,
  77. ulong rate, ulong current_rate);
  78. static ulong meson_mux_get_parent(struct clk *clk, unsigned long id);
  79. static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id);
  80. static struct meson_gate gates[] = {
  81. /* Everything Else (EE) domain gates */
  82. MESON_GATE(CLKID_DDR, HHI_GCLK_MPEG0, 0),
  83. MESON_GATE(CLKID_DOS, HHI_GCLK_MPEG0, 1),
  84. MESON_GATE(CLKID_ISA, HHI_GCLK_MPEG0, 5),
  85. MESON_GATE(CLKID_PL301, HHI_GCLK_MPEG0, 6),
  86. MESON_GATE(CLKID_PERIPHS, HHI_GCLK_MPEG0, 7),
  87. MESON_GATE(CLKID_SPICC, HHI_GCLK_MPEG0, 8),
  88. MESON_GATE(CLKID_I2C, HHI_GCLK_MPEG0, 9),
  89. MESON_GATE(CLKID_SAR_ADC, HHI_GCLK_MPEG0, 10),
  90. MESON_GATE(CLKID_SMART_CARD, HHI_GCLK_MPEG0, 11),
  91. MESON_GATE(CLKID_RNG0, HHI_GCLK_MPEG0, 12),
  92. MESON_GATE(CLKID_UART0, HHI_GCLK_MPEG0, 13),
  93. MESON_GATE(CLKID_SDHC, HHI_GCLK_MPEG0, 14),
  94. MESON_GATE(CLKID_STREAM, HHI_GCLK_MPEG0, 15),
  95. MESON_GATE(CLKID_ASYNC_FIFO, HHI_GCLK_MPEG0, 16),
  96. MESON_GATE(CLKID_SDIO, HHI_GCLK_MPEG0, 17),
  97. MESON_GATE(CLKID_ABUF, HHI_GCLK_MPEG0, 18),
  98. MESON_GATE(CLKID_HIU_IFACE, HHI_GCLK_MPEG0, 19),
  99. MESON_GATE(CLKID_ASSIST_MISC, HHI_GCLK_MPEG0, 23),
  100. MESON_GATE(CLKID_SD_EMMC_A, HHI_GCLK_MPEG0, 24),
  101. MESON_GATE(CLKID_SD_EMMC_B, HHI_GCLK_MPEG0, 25),
  102. MESON_GATE(CLKID_SD_EMMC_C, HHI_GCLK_MPEG0, 26),
  103. MESON_GATE(CLKID_SPI, HHI_GCLK_MPEG0, 30),
  104. MESON_GATE(CLKID_I2S_SPDIF, HHI_GCLK_MPEG1, 2),
  105. MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3),
  106. MESON_GATE(CLKID_DEMUX, HHI_GCLK_MPEG1, 4),
  107. MESON_GATE(CLKID_AIU_GLUE, HHI_GCLK_MPEG1, 6),
  108. MESON_GATE(CLKID_IEC958, HHI_GCLK_MPEG1, 7),
  109. MESON_GATE(CLKID_I2S_OUT, HHI_GCLK_MPEG1, 8),
  110. MESON_GATE(CLKID_AMCLK, HHI_GCLK_MPEG1, 9),
  111. MESON_GATE(CLKID_AIFIFO2, HHI_GCLK_MPEG1, 10),
  112. MESON_GATE(CLKID_MIXER, HHI_GCLK_MPEG1, 11),
  113. MESON_GATE(CLKID_MIXER_IFACE, HHI_GCLK_MPEG1, 12),
  114. MESON_GATE(CLKID_ADC, HHI_GCLK_MPEG1, 13),
  115. MESON_GATE(CLKID_BLKMV, HHI_GCLK_MPEG1, 14),
  116. MESON_GATE(CLKID_AIU, HHI_GCLK_MPEG1, 15),
  117. MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16),
  118. MESON_GATE(CLKID_G2D, HHI_GCLK_MPEG1, 20),
  119. MESON_GATE(CLKID_USB0, HHI_GCLK_MPEG1, 21),
  120. MESON_GATE(CLKID_USB1, HHI_GCLK_MPEG1, 22),
  121. MESON_GATE(CLKID_RESET, HHI_GCLK_MPEG1, 23),
  122. MESON_GATE(CLKID_NAND, HHI_GCLK_MPEG1, 24),
  123. MESON_GATE(CLKID_DOS_PARSER, HHI_GCLK_MPEG1, 25),
  124. MESON_GATE(CLKID_USB, HHI_GCLK_MPEG1, 26),
  125. MESON_GATE(CLKID_VDIN1, HHI_GCLK_MPEG1, 28),
  126. MESON_GATE(CLKID_AHB_ARB0, HHI_GCLK_MPEG1, 29),
  127. MESON_GATE(CLKID_EFUSE, HHI_GCLK_MPEG1, 30),
  128. MESON_GATE(CLKID_BOOT_ROM, HHI_GCLK_MPEG1, 31),
  129. MESON_GATE(CLKID_AHB_DATA_BUS, HHI_GCLK_MPEG2, 1),
  130. MESON_GATE(CLKID_AHB_CTRL_BUS, HHI_GCLK_MPEG2, 2),
  131. MESON_GATE(CLKID_HDMI_INTR_SYNC, HHI_GCLK_MPEG2, 3),
  132. MESON_GATE(CLKID_HDMI_PCLK, HHI_GCLK_MPEG2, 4),
  133. MESON_GATE(CLKID_USB1_DDR_BRIDGE, HHI_GCLK_MPEG2, 8),
  134. MESON_GATE(CLKID_USB0_DDR_BRIDGE, HHI_GCLK_MPEG2, 9),
  135. MESON_GATE(CLKID_MMC_PCLK, HHI_GCLK_MPEG2, 11),
  136. MESON_GATE(CLKID_DVIN, HHI_GCLK_MPEG2, 12),
  137. MESON_GATE(CLKID_UART2, HHI_GCLK_MPEG2, 15),
  138. MESON_GATE(CLKID_SANA, HHI_GCLK_MPEG2, 22),
  139. MESON_GATE(CLKID_VPU_INTR, HHI_GCLK_MPEG2, 25),
  140. MESON_GATE(CLKID_SEC_AHB_AHB3_BRIDGE, HHI_GCLK_MPEG2, 26),
  141. MESON_GATE(CLKID_CLK81_A53, HHI_GCLK_MPEG2, 29),
  142. MESON_GATE(CLKID_VCLK2_VENCI0, HHI_GCLK_OTHER, 1),
  143. MESON_GATE(CLKID_VCLK2_VENCI1, HHI_GCLK_OTHER, 2),
  144. MESON_GATE(CLKID_VCLK2_VENCP0, HHI_GCLK_OTHER, 3),
  145. MESON_GATE(CLKID_VCLK2_VENCP1, HHI_GCLK_OTHER, 4),
  146. MESON_GATE(CLKID_GCLK_VENCI_INT0, HHI_GCLK_OTHER, 8),
  147. MESON_GATE(CLKID_DAC_CLK, HHI_GCLK_OTHER, 10),
  148. MESON_GATE(CLKID_AOCLK_GATE, HHI_GCLK_OTHER, 14),
  149. MESON_GATE(CLKID_IEC958_GATE, HHI_GCLK_OTHER, 16),
  150. MESON_GATE(CLKID_ENC480P, HHI_GCLK_OTHER, 20),
  151. MESON_GATE(CLKID_RNG1, HHI_GCLK_OTHER, 21),
  152. MESON_GATE(CLKID_GCLK_VENCI_INT1, HHI_GCLK_OTHER, 22),
  153. MESON_GATE(CLKID_VCLK2_VENCLMCC, HHI_GCLK_OTHER, 24),
  154. MESON_GATE(CLKID_VCLK2_VENCL, HHI_GCLK_OTHER, 25),
  155. MESON_GATE(CLKID_VCLK_OTHER, HHI_GCLK_OTHER, 26),
  156. MESON_GATE(CLKID_EDP, HHI_GCLK_OTHER, 31),
  157. /* Always On (AO) domain gates */
  158. MESON_GATE(CLKID_AO_MEDIA_CPU, HHI_GCLK_AO, 0),
  159. MESON_GATE(CLKID_AO_AHB_SRAM, HHI_GCLK_AO, 1),
  160. MESON_GATE(CLKID_AO_AHB_BUS, HHI_GCLK_AO, 2),
  161. MESON_GATE(CLKID_AO_IFACE, HHI_GCLK_AO, 3),
  162. MESON_GATE(CLKID_AO_I2C, HHI_GCLK_AO, 4),
  163. /* PLL Gates */
  164. /* CLKID_FCLK_DIV2 is critical for the SCPI Processor */
  165. MESON_GATE(CLKID_FCLK_DIV3, HHI_MPLL_CNTL6, 28),
  166. MESON_GATE(CLKID_FCLK_DIV4, HHI_MPLL_CNTL6, 29),
  167. MESON_GATE(CLKID_FCLK_DIV5, HHI_MPLL_CNTL6, 30),
  168. MESON_GATE(CLKID_FCLK_DIV7, HHI_MPLL_CNTL6, 31),
  169. MESON_GATE(CLKID_MPLL0, HHI_MPLL_CNTL7, 14),
  170. MESON_GATE(CLKID_MPLL1, HHI_MPLL_CNTL8, 14),
  171. MESON_GATE(CLKID_MPLL2, HHI_MPLL_CNTL9, 14),
  172. /* CLKID_CLK81 is critical for the system */
  173. /* Peripheral Gates */
  174. MESON_GATE(CLKID_SAR_ADC_CLK, HHI_SAR_CLK_CNTL, 8),
  175. MESON_GATE(CLKID_SD_EMMC_A_CLK0, HHI_SD_EMMC_CLK_CNTL, 7),
  176. MESON_GATE(CLKID_SD_EMMC_B_CLK0, HHI_SD_EMMC_CLK_CNTL, 23),
  177. MESON_GATE(CLKID_SD_EMMC_C_CLK0, HHI_NAND_CLK_CNTL, 7),
  178. MESON_GATE(CLKID_VPU_0, HHI_VPU_CLK_CNTL, 8),
  179. MESON_GATE(CLKID_VPU_1, HHI_VPU_CLK_CNTL, 24),
  180. MESON_GATE(CLKID_VAPB_0, HHI_VAPBCLK_CNTL, 8),
  181. MESON_GATE(CLKID_VAPB_1, HHI_VAPBCLK_CNTL, 24),
  182. MESON_GATE(CLKID_VAPB, HHI_VAPBCLK_CNTL, 30),
  183. };
  184. static int meson_set_gate_by_id(struct clk *clk, unsigned long id, bool on)
  185. {
  186. struct meson_clk *priv = dev_get_priv(clk->dev);
  187. struct meson_gate *gate;
  188. debug("%s: %sabling %ld\n", __func__, on ? "en" : "dis", id);
  189. /* Propagate through muxes */
  190. switch (id) {
  191. case CLKID_VPU:
  192. return meson_set_gate_by_id(clk,
  193. meson_mux_get_parent(clk, CLKID_VPU), on);
  194. case CLKID_VAPB_SEL:
  195. return meson_set_gate_by_id(clk,
  196. meson_mux_get_parent(clk, CLKID_VAPB_SEL), on);
  197. }
  198. if (id >= ARRAY_SIZE(gates))
  199. return -ENOENT;
  200. gate = &gates[id];
  201. if (gate->reg == 0)
  202. return 0;
  203. debug("%s: really %sabling %ld\n", __func__, on ? "en" : "dis", id);
  204. regmap_update_bits(priv->map, gate->reg,
  205. BIT(gate->bit), on ? BIT(gate->bit) : 0);
  206. /* Propagate to next gate(s) */
  207. switch (id) {
  208. case CLKID_VAPB:
  209. return meson_set_gate_by_id(clk, CLKID_VAPB_SEL, on);
  210. }
  211. return 0;
  212. }
  213. static int meson_clk_enable(struct clk *clk)
  214. {
  215. return meson_set_gate_by_id(clk, clk->id, true);
  216. }
  217. static int meson_clk_disable(struct clk *clk)
  218. {
  219. return meson_set_gate_by_id(clk, clk->id, false);
  220. }
  221. static struct parm meson_vpu_0_div_parm = {
  222. HHI_VPU_CLK_CNTL, 0, 7,
  223. };
  224. int meson_vpu_0_div_parent = CLKID_VPU_0_SEL;
  225. static struct parm meson_vpu_1_div_parm = {
  226. HHI_VPU_CLK_CNTL, 16, 7,
  227. };
  228. int meson_vpu_1_div_parent = CLKID_VPU_1_SEL;
  229. static struct parm meson_vapb_0_div_parm = {
  230. HHI_VAPBCLK_CNTL, 0, 7,
  231. };
  232. int meson_vapb_0_div_parent = CLKID_VAPB_0_SEL;
  233. static struct parm meson_vapb_1_div_parm = {
  234. HHI_VAPBCLK_CNTL, 16, 7,
  235. };
  236. int meson_vapb_1_div_parent = CLKID_VAPB_1_SEL;
  237. static ulong meson_div_get_rate(struct clk *clk, unsigned long id)
  238. {
  239. struct meson_clk *priv = dev_get_priv(clk->dev);
  240. unsigned int rate, parent_rate;
  241. struct parm *parm;
  242. int parent;
  243. uint reg;
  244. switch (id) {
  245. case CLKID_VPU_0_DIV:
  246. parm = &meson_vpu_0_div_parm;
  247. parent = meson_vpu_0_div_parent;
  248. break;
  249. case CLKID_VPU_1_DIV:
  250. parm = &meson_vpu_1_div_parm;
  251. parent = meson_vpu_1_div_parent;
  252. break;
  253. case CLKID_VAPB_0_DIV:
  254. parm = &meson_vapb_0_div_parm;
  255. parent = meson_vapb_0_div_parent;
  256. break;
  257. case CLKID_VAPB_1_DIV:
  258. parm = &meson_vapb_1_div_parm;
  259. parent = meson_vapb_1_div_parent;
  260. break;
  261. default:
  262. return -ENOENT;
  263. }
  264. regmap_read(priv->map, parm->reg_off, &reg);
  265. reg = PARM_GET(parm->width, parm->shift, reg);
  266. debug("%s: div of %ld is %d\n", __func__, id, reg + 1);
  267. parent_rate = meson_clk_get_rate_by_id(clk, parent);
  268. if (IS_ERR_VALUE(parent_rate))
  269. return parent_rate;
  270. debug("%s: parent rate of %ld is %d\n", __func__, id, parent_rate);
  271. rate = parent_rate / (reg + 1);
  272. debug("%s: rate of %ld is %d\n", __func__, id, rate);
  273. return rate;
  274. }
  275. static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate,
  276. ulong current_rate)
  277. {
  278. struct meson_clk *priv = dev_get_priv(clk->dev);
  279. unsigned int new_div = -EINVAL;
  280. unsigned long parent_rate;
  281. struct parm *parm;
  282. int parent;
  283. int ret;
  284. if (current_rate == rate)
  285. return 0;
  286. debug("%s: setting rate of %ld from %ld to %ld\n",
  287. __func__, id, current_rate, rate);
  288. switch (id) {
  289. case CLKID_VPU_0_DIV:
  290. parm = &meson_vpu_0_div_parm;
  291. parent = meson_vpu_0_div_parent;
  292. break;
  293. case CLKID_VPU_1_DIV:
  294. parm = &meson_vpu_1_div_parm;
  295. parent = meson_vpu_1_div_parent;
  296. break;
  297. case CLKID_VAPB_0_DIV:
  298. parm = &meson_vapb_0_div_parm;
  299. parent = meson_vapb_0_div_parent;
  300. break;
  301. case CLKID_VAPB_1_DIV:
  302. parm = &meson_vapb_1_div_parm;
  303. parent = meson_vapb_1_div_parent;
  304. break;
  305. default:
  306. return -ENOENT;
  307. }
  308. parent_rate = meson_clk_get_rate_by_id(clk, parent);
  309. if (IS_ERR_VALUE(parent_rate))
  310. return parent_rate;
  311. debug("%s: parent rate of %ld is %ld\n", __func__, id, parent_rate);
  312. /* If can't divide, set parent instead */
  313. if (!parent_rate || rate > parent_rate)
  314. return meson_clk_set_rate_by_id(clk, parent, rate,
  315. current_rate);
  316. new_div = DIV_ROUND_CLOSEST(parent_rate, rate);
  317. debug("%s: new div of %ld is %d\n", __func__, id, new_div);
  318. /* If overflow, try to set parent rate and retry */
  319. if (!new_div || new_div > (1 << parm->width)) {
  320. ret = meson_clk_set_rate_by_id(clk, parent, rate, current_rate);
  321. if (IS_ERR_VALUE(ret))
  322. return ret;
  323. parent_rate = meson_clk_get_rate_by_id(clk, parent);
  324. if (IS_ERR_VALUE(parent_rate))
  325. return parent_rate;
  326. new_div = DIV_ROUND_CLOSEST(parent_rate, rate);
  327. debug("%s: new new div of %ld is %d\n", __func__, id, new_div);
  328. if (!new_div || new_div > (1 << parm->width))
  329. return -EINVAL;
  330. }
  331. debug("%s: setting div of %ld to %d\n", __func__, id, new_div);
  332. regmap_update_bits(priv->map, parm->reg_off, SETPMASK(parm->width, parm->shift),
  333. (new_div - 1) << parm->shift);
  334. debug("%s: new rate of %ld is %ld\n",
  335. __func__, id, meson_div_get_rate(clk, id));
  336. return 0;
  337. }
  338. static struct parm meson_vpu_mux_parm = {
  339. HHI_VPU_CLK_CNTL, 31, 1,
  340. };
  341. int meson_vpu_mux_parents[] = {
  342. CLKID_VPU_0,
  343. CLKID_VPU_1,
  344. };
  345. static struct parm meson_vpu_0_mux_parm = {
  346. HHI_VPU_CLK_CNTL, 9, 2,
  347. };
  348. static struct parm meson_vpu_1_mux_parm = {
  349. HHI_VPU_CLK_CNTL, 25, 2,
  350. };
  351. static int meson_vpu_0_1_mux_parents[] = {
  352. CLKID_FCLK_DIV4,
  353. CLKID_FCLK_DIV3,
  354. CLKID_FCLK_DIV5,
  355. CLKID_FCLK_DIV7,
  356. };
  357. static struct parm meson_vapb_sel_mux_parm = {
  358. HHI_VAPBCLK_CNTL, 31, 1,
  359. };
  360. int meson_vapb_sel_mux_parents[] = {
  361. CLKID_VAPB_0,
  362. CLKID_VAPB_1,
  363. };
  364. static struct parm meson_vapb_0_mux_parm = {
  365. HHI_VAPBCLK_CNTL, 9, 2,
  366. };
  367. static struct parm meson_vapb_1_mux_parm = {
  368. HHI_VAPBCLK_CNTL, 25, 2,
  369. };
  370. static int meson_vapb_0_1_mux_parents[] = {
  371. CLKID_FCLK_DIV4,
  372. CLKID_FCLK_DIV3,
  373. CLKID_FCLK_DIV5,
  374. CLKID_FCLK_DIV7,
  375. };
  376. static ulong meson_mux_get_parent(struct clk *clk, unsigned long id)
  377. {
  378. struct meson_clk *priv = dev_get_priv(clk->dev);
  379. struct parm *parm;
  380. int *parents;
  381. uint reg;
  382. switch (id) {
  383. case CLKID_VPU:
  384. parm = &meson_vpu_mux_parm;
  385. parents = meson_vpu_mux_parents;
  386. break;
  387. case CLKID_VPU_0_SEL:
  388. parm = &meson_vpu_0_mux_parm;
  389. parents = meson_vpu_0_1_mux_parents;
  390. break;
  391. case CLKID_VPU_1_SEL:
  392. parm = &meson_vpu_1_mux_parm;
  393. parents = meson_vpu_0_1_mux_parents;
  394. break;
  395. case CLKID_VAPB_SEL:
  396. parm = &meson_vapb_sel_mux_parm;
  397. parents = meson_vapb_sel_mux_parents;
  398. break;
  399. case CLKID_VAPB_0_SEL:
  400. parm = &meson_vapb_0_mux_parm;
  401. parents = meson_vapb_0_1_mux_parents;
  402. break;
  403. case CLKID_VAPB_1_SEL:
  404. parm = &meson_vapb_1_mux_parm;
  405. parents = meson_vapb_0_1_mux_parents;
  406. break;
  407. default:
  408. return -ENOENT;
  409. }
  410. regmap_read(priv->map, parm->reg_off, &reg);
  411. reg = PARM_GET(parm->width, parm->shift, reg);
  412. debug("%s: parent of %ld is %d (%d)\n",
  413. __func__, id, parents[reg], reg);
  414. return parents[reg];
  415. }
  416. static ulong meson_mux_set_parent(struct clk *clk, unsigned long id,
  417. unsigned long parent_id)
  418. {
  419. unsigned long cur_parent = meson_mux_get_parent(clk, id);
  420. struct meson_clk *priv = dev_get_priv(clk->dev);
  421. unsigned int new_index = -EINVAL;
  422. struct parm *parm;
  423. int *parents;
  424. int i;
  425. if (IS_ERR_VALUE(cur_parent))
  426. return cur_parent;
  427. debug("%s: setting parent of %ld from %ld to %ld\n",
  428. __func__, id, cur_parent, parent_id);
  429. if (cur_parent == parent_id)
  430. return 0;
  431. switch (id) {
  432. case CLKID_VPU:
  433. parm = &meson_vpu_mux_parm;
  434. parents = meson_vpu_mux_parents;
  435. break;
  436. case CLKID_VPU_0_SEL:
  437. parm = &meson_vpu_0_mux_parm;
  438. parents = meson_vpu_0_1_mux_parents;
  439. break;
  440. case CLKID_VPU_1_SEL:
  441. parm = &meson_vpu_1_mux_parm;
  442. parents = meson_vpu_0_1_mux_parents;
  443. break;
  444. case CLKID_VAPB_SEL:
  445. parm = &meson_vapb_sel_mux_parm;
  446. parents = meson_vapb_sel_mux_parents;
  447. break;
  448. case CLKID_VAPB_0_SEL:
  449. parm = &meson_vapb_0_mux_parm;
  450. parents = meson_vapb_0_1_mux_parents;
  451. break;
  452. case CLKID_VAPB_1_SEL:
  453. parm = &meson_vapb_1_mux_parm;
  454. parents = meson_vapb_0_1_mux_parents;
  455. break;
  456. default:
  457. /* Not a mux */
  458. return -ENOENT;
  459. }
  460. for (i = 0 ; i < (1 << parm->width) ; ++i) {
  461. if (parents[i] == parent_id)
  462. new_index = i;
  463. }
  464. if (IS_ERR_VALUE(new_index))
  465. return new_index;
  466. debug("%s: new index of %ld is %d\n", __func__, id, new_index);
  467. regmap_update_bits(priv->map, parm->reg_off, SETPMASK(parm->width, parm->shift),
  468. new_index << parm->shift);
  469. debug("%s: new parent of %ld is %ld\n",
  470. __func__, id, meson_mux_get_parent(clk, id));
  471. return 0;
  472. }
  473. static ulong meson_mux_get_rate(struct clk *clk, unsigned long id)
  474. {
  475. int parent = meson_mux_get_parent(clk, id);
  476. if (IS_ERR_VALUE(parent))
  477. return parent;
  478. return meson_clk_get_rate_by_id(clk, parent);
  479. }
  480. static unsigned long meson_clk81_get_rate(struct clk *clk)
  481. {
  482. struct meson_clk *priv = dev_get_priv(clk->dev);
  483. unsigned long parent_rate;
  484. uint reg;
  485. int parents[] = {
  486. -1,
  487. -1,
  488. CLKID_FCLK_DIV7,
  489. CLKID_MPLL1,
  490. CLKID_MPLL2,
  491. CLKID_FCLK_DIV4,
  492. CLKID_FCLK_DIV3,
  493. CLKID_FCLK_DIV5
  494. };
  495. /* mux */
  496. regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
  497. reg = (reg >> 12) & 7;
  498. switch (reg) {
  499. case 0:
  500. parent_rate = XTAL_RATE;
  501. break;
  502. case 1:
  503. return -ENOENT;
  504. default:
  505. parent_rate = meson_clk_get_rate_by_id(clk, parents[reg]);
  506. }
  507. /* divider */
  508. regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
  509. reg = reg & ((1 << 7) - 1);
  510. /* clk81 divider is zero based */
  511. return parent_rate / (reg + 1);
  512. }
  513. static long mpll_rate_from_params(unsigned long parent_rate,
  514. unsigned long sdm,
  515. unsigned long n2)
  516. {
  517. unsigned long divisor = (SDM_DEN * n2) + sdm;
  518. if (n2 < N2_MIN)
  519. return -EINVAL;
  520. return DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, divisor);
  521. }
  522. static struct parm meson_mpll0_parm[3] = {
  523. {HHI_MPLL_CNTL7, 0, 14}, /* psdm */
  524. {HHI_MPLL_CNTL7, 16, 9}, /* pn2 */
  525. };
  526. static struct parm meson_mpll1_parm[3] = {
  527. {HHI_MPLL_CNTL8, 0, 14}, /* psdm */
  528. {HHI_MPLL_CNTL8, 16, 9}, /* pn2 */
  529. };
  530. static struct parm meson_mpll2_parm[3] = {
  531. {HHI_MPLL_CNTL9, 0, 14}, /* psdm */
  532. {HHI_MPLL_CNTL9, 16, 9}, /* pn2 */
  533. };
  534. /*
  535. * MultiPhase Locked Loops are outputs from a PLL with additional frequency
  536. * scaling capabilities. MPLL rates are calculated as:
  537. *
  538. * f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384)
  539. */
  540. static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id)
  541. {
  542. struct meson_clk *priv = dev_get_priv(clk->dev);
  543. struct parm *psdm, *pn2;
  544. unsigned long sdm, n2;
  545. unsigned long parent_rate;
  546. uint reg;
  547. switch (id) {
  548. case CLKID_MPLL0:
  549. psdm = &meson_mpll0_parm[0];
  550. pn2 = &meson_mpll0_parm[1];
  551. break;
  552. case CLKID_MPLL1:
  553. psdm = &meson_mpll1_parm[0];
  554. pn2 = &meson_mpll1_parm[1];
  555. break;
  556. case CLKID_MPLL2:
  557. psdm = &meson_mpll2_parm[0];
  558. pn2 = &meson_mpll2_parm[1];
  559. break;
  560. default:
  561. return -ENOENT;
  562. }
  563. parent_rate = meson_clk_get_rate_by_id(clk, CLKID_FIXED_PLL);
  564. if (IS_ERR_VALUE(parent_rate))
  565. return parent_rate;
  566. regmap_read(priv->map, psdm->reg_off, &reg);
  567. sdm = PARM_GET(psdm->width, psdm->shift, reg);
  568. regmap_read(priv->map, pn2->reg_off, &reg);
  569. n2 = PARM_GET(pn2->width, pn2->shift, reg);
  570. return mpll_rate_from_params(parent_rate, sdm, n2);
  571. }
  572. static struct parm meson_fixed_pll_parm[3] = {
  573. {HHI_MPLL_CNTL, 0, 9}, /* pm */
  574. {HHI_MPLL_CNTL, 9, 5}, /* pn */
  575. {HHI_MPLL_CNTL, 16, 2}, /* pod */
  576. };
  577. static struct parm meson_sys_pll_parm[3] = {
  578. {HHI_SYS_PLL_CNTL, 0, 9}, /* pm */
  579. {HHI_SYS_PLL_CNTL, 9, 5}, /* pn */
  580. {HHI_SYS_PLL_CNTL, 10, 2}, /* pod */
  581. };
  582. static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
  583. {
  584. struct meson_clk *priv = dev_get_priv(clk->dev);
  585. struct parm *pm, *pn, *pod;
  586. unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
  587. u16 n, m, od;
  588. uint reg;
  589. switch (id) {
  590. case CLKID_FIXED_PLL:
  591. pm = &meson_fixed_pll_parm[0];
  592. pn = &meson_fixed_pll_parm[1];
  593. pod = &meson_fixed_pll_parm[2];
  594. break;
  595. case CLKID_SYS_PLL:
  596. pm = &meson_sys_pll_parm[0];
  597. pn = &meson_sys_pll_parm[1];
  598. pod = &meson_sys_pll_parm[2];
  599. break;
  600. default:
  601. return -ENOENT;
  602. }
  603. regmap_read(priv->map, pn->reg_off, &reg);
  604. n = PARM_GET(pn->width, pn->shift, reg);
  605. regmap_read(priv->map, pm->reg_off, &reg);
  606. m = PARM_GET(pm->width, pm->shift, reg);
  607. regmap_read(priv->map, pod->reg_off, &reg);
  608. od = PARM_GET(pod->width, pod->shift, reg);
  609. return ((parent_rate_mhz * m / n) >> od) * 1000000;
  610. }
  611. static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id)
  612. {
  613. ulong rate;
  614. switch (id) {
  615. case CLKID_FIXED_PLL:
  616. case CLKID_SYS_PLL:
  617. rate = meson_pll_get_rate(clk, id);
  618. break;
  619. case CLKID_FCLK_DIV2:
  620. rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 2;
  621. break;
  622. case CLKID_FCLK_DIV3:
  623. rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 3;
  624. break;
  625. case CLKID_FCLK_DIV4:
  626. rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 4;
  627. break;
  628. case CLKID_FCLK_DIV5:
  629. rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 5;
  630. break;
  631. case CLKID_FCLK_DIV7:
  632. rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 7;
  633. break;
  634. case CLKID_MPLL0:
  635. case CLKID_MPLL1:
  636. case CLKID_MPLL2:
  637. rate = meson_mpll_get_rate(clk, id);
  638. break;
  639. case CLKID_CLK81:
  640. rate = meson_clk81_get_rate(clk);
  641. break;
  642. case CLKID_VPU_0:
  643. rate = meson_div_get_rate(clk, CLKID_VPU_0_DIV);
  644. break;
  645. case CLKID_VPU_1:
  646. rate = meson_div_get_rate(clk, CLKID_VPU_1_DIV);
  647. break;
  648. case CLKID_VAPB:
  649. rate = meson_mux_get_rate(clk, CLKID_VAPB_SEL);
  650. break;
  651. case CLKID_VAPB_0:
  652. rate = meson_div_get_rate(clk, CLKID_VAPB_0_DIV);
  653. break;
  654. case CLKID_VAPB_1:
  655. rate = meson_div_get_rate(clk, CLKID_VAPB_1_DIV);
  656. break;
  657. case CLKID_VPU_0_DIV:
  658. case CLKID_VPU_1_DIV:
  659. case CLKID_VAPB_0_DIV:
  660. case CLKID_VAPB_1_DIV:
  661. rate = meson_div_get_rate(clk, id);
  662. break;
  663. case CLKID_VPU:
  664. case CLKID_VPU_0_SEL:
  665. case CLKID_VPU_1_SEL:
  666. case CLKID_VAPB_SEL:
  667. case CLKID_VAPB_0_SEL:
  668. case CLKID_VAPB_1_SEL:
  669. rate = meson_mux_get_rate(clk, id);
  670. break;
  671. default:
  672. if (gates[id].reg != 0) {
  673. /* a clock gate */
  674. rate = meson_clk81_get_rate(clk);
  675. break;
  676. }
  677. return -ENOENT;
  678. }
  679. debug("clock %lu has rate %lu\n", id, rate);
  680. return rate;
  681. }
  682. static ulong meson_clk_get_rate(struct clk *clk)
  683. {
  684. return meson_clk_get_rate_by_id(clk, clk->id);
  685. }
  686. static int meson_clk_set_parent(struct clk *clk, struct clk *parent)
  687. {
  688. return meson_mux_set_parent(clk, clk->id, parent->id);
  689. }
  690. static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id,
  691. ulong rate, ulong current_rate)
  692. {
  693. if (current_rate == rate)
  694. return 0;
  695. switch (id) {
  696. /* Fixed clocks */
  697. case CLKID_FIXED_PLL:
  698. case CLKID_SYS_PLL:
  699. case CLKID_FCLK_DIV2:
  700. case CLKID_FCLK_DIV3:
  701. case CLKID_FCLK_DIV4:
  702. case CLKID_FCLK_DIV5:
  703. case CLKID_FCLK_DIV7:
  704. case CLKID_MPLL0:
  705. case CLKID_MPLL1:
  706. case CLKID_MPLL2:
  707. case CLKID_CLK81:
  708. return -EINVAL;
  709. case CLKID_VPU:
  710. return meson_clk_set_rate_by_id(clk,
  711. meson_mux_get_parent(clk, CLKID_VPU), rate,
  712. current_rate);
  713. case CLKID_VAPB:
  714. case CLKID_VAPB_SEL:
  715. return meson_clk_set_rate_by_id(clk,
  716. meson_mux_get_parent(clk, CLKID_VAPB_SEL),
  717. rate, current_rate);
  718. case CLKID_VPU_0:
  719. return meson_div_set_rate(clk, CLKID_VPU_0_DIV, rate,
  720. current_rate);
  721. case CLKID_VPU_1:
  722. return meson_div_set_rate(clk, CLKID_VPU_1_DIV, rate,
  723. current_rate);
  724. case CLKID_VAPB_0:
  725. return meson_div_set_rate(clk, CLKID_VAPB_0_DIV, rate,
  726. current_rate);
  727. case CLKID_VAPB_1:
  728. return meson_div_set_rate(clk, CLKID_VAPB_1_DIV, rate,
  729. current_rate);
  730. case CLKID_VPU_0_DIV:
  731. case CLKID_VPU_1_DIV:
  732. case CLKID_VAPB_0_DIV:
  733. case CLKID_VAPB_1_DIV:
  734. return meson_div_set_rate(clk, id, rate, current_rate);
  735. default:
  736. return -ENOENT;
  737. }
  738. return -EINVAL;
  739. }
  740. static ulong meson_clk_set_rate(struct clk *clk, ulong rate)
  741. {
  742. ulong current_rate = meson_clk_get_rate_by_id(clk, clk->id);
  743. int ret;
  744. if (IS_ERR_VALUE(current_rate))
  745. return current_rate;
  746. debug("%s: setting rate of %ld from %ld to %ld\n",
  747. __func__, clk->id, current_rate, rate);
  748. ret = meson_clk_set_rate_by_id(clk, clk->id, rate, current_rate);
  749. if (IS_ERR_VALUE(ret))
  750. return ret;
  751. debug("clock %lu has new rate %lu\n", clk->id,
  752. meson_clk_get_rate_by_id(clk, clk->id));
  753. return 0;
  754. }
  755. static int meson_clk_probe(struct udevice *dev)
  756. {
  757. struct meson_clk *priv = dev_get_priv(dev);
  758. priv->map = syscon_node_to_regmap(dev_ofnode(dev_get_parent(dev)));
  759. if (IS_ERR(priv->map))
  760. return PTR_ERR(priv->map);
  761. /*
  762. * Depending on the boot src, the state of the MMC clock might
  763. * be different. Reset it to make sure we won't get stuck
  764. */
  765. regmap_write(priv->map, HHI_NAND_CLK_CNTL, 0);
  766. regmap_write(priv->map, HHI_SD_EMMC_CLK_CNTL, 0);
  767. debug("meson-clk: probed\n");
  768. return 0;
  769. }
  770. static struct clk_ops meson_clk_ops = {
  771. .disable = meson_clk_disable,
  772. .enable = meson_clk_enable,
  773. .get_rate = meson_clk_get_rate,
  774. .set_parent = meson_clk_set_parent,
  775. .set_rate = meson_clk_set_rate,
  776. };
  777. static const struct udevice_id meson_clk_ids[] = {
  778. { .compatible = "amlogic,gxbb-clkc" },
  779. { .compatible = "amlogic,gxl-clkc" },
  780. { }
  781. };
  782. U_BOOT_DRIVER(meson_clk) = {
  783. .name = "meson_clk",
  784. .id = UCLASS_CLK,
  785. .of_match = meson_clk_ids,
  786. .priv_auto = sizeof(struct meson_clk),
  787. .ops = &meson_clk_ops,
  788. .probe = meson_clk_probe,
  789. };