clk-jh7110.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2022 Starfive, Inc.
  4. * Author: yanhong <yanhong.wang@starfivetech.com>
  5. *
  6. */
  7. #include <common.h>
  8. #include <malloc.h>
  9. #include <clk-uclass.h>
  10. #include <clk.h>
  11. #include <dm/device.h>
  12. #include <dm/devres.h>
  13. #include <dm.h>
  14. #include <linux/clk-provider.h>
  15. #include <dt-bindings/clock/starfive-jh7110-clkgen.h>
  16. #include <log.h>
  17. #include <linux/clk-provider.h>
  18. #define STARFIVE_CLK_ENABLE_SHIFT 31 /*[31]*/
  19. #define STARFIVE_CLK_INVERT_SHIFT 30 /*[30]*/
  20. #define STARFIVE_CLK_MUX_SHIFT 24 /*[29:24]*/
  21. #define STARFIVE_CLK_DIV_SHIFT 0 /*[23:0]*/
  22. #define SYS_OFFSET(id) (id * 4)
  23. #define STG_OFFSET(id) ((id - JH7110_CLK_SYS_REG_END) * 4)
  24. #define AON_OFFSET(id) ((id - JH7110_CLK_STG_REG_END) * 4)
  25. #define JH7110_PLL0 (JH7110_CLK_RTC+1)
  26. #define JH7110_PLL1 (JH7110_CLK_RTC+2)
  27. #define JH7110_PLL2 (JH7110_CLK_RTC+3)
  28. struct jh7110_clk_priv {
  29. void __iomem *sys;
  30. void __iomem *stg;
  31. void __iomem *aon;
  32. };
  33. static const char *cpu_root_sels[2] = {
  34. [0] = "osc",
  35. [1] = "pll0_out",
  36. };
  37. static const char *perh_root_sels[2] = {
  38. [0] = "pll0_out",
  39. [1] = "pll2_out",
  40. };
  41. static const char *bus_root_sels[2] = {
  42. [0] = "osc",
  43. [1] = "pll2_out",
  44. };
  45. static const char *qspi_ref_sels[2] = {
  46. [0] = "osc",
  47. [1] = "clk_qspi_ref_src",
  48. };
  49. static const char *gmac5_tx_sels[2] = {
  50. [0] = "gmac1_gtxclk",
  51. [1] = "gmac1_rmii_rtx",
  52. };
  53. static const char *aon_apb_func_sels[2] = {
  54. [0] = "osc_div4",
  55. [1] = "osc",
  56. };
  57. static const char *u0_dw_gmac5_axi64_clk_tx_sels[2] = {
  58. [0] = "gmac0_gtxclk",
  59. [1] = "gmac0_rmii_rtx",
  60. };
  61. static ulong starfive_clk_get_rate(struct clk *clk)
  62. {
  63. struct clk *c;
  64. int ret;
  65. debug("%s(#%lu)\n", __func__, clk->id);
  66. ret = clk_get_by_id(clk->id, &c);
  67. if (ret)
  68. return ret;
  69. return clk_get_rate(c);
  70. }
  71. static ulong starfive_clk_set_rate(struct clk *clk, unsigned long rate)
  72. {
  73. struct clk *c;
  74. int ret;
  75. debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
  76. ret = clk_get_by_id(clk->id, &c);
  77. if (ret)
  78. return ret;
  79. return clk_set_rate(c, rate);
  80. }
  81. static int __starfive_clk_enable(struct clk *clk, bool enable)
  82. {
  83. struct clk *c;
  84. int ret;
  85. debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
  86. ret = clk_get_by_id(clk->id, &c);
  87. if (ret)
  88. return ret;
  89. if (enable)
  90. ret = clk_enable(c);
  91. else
  92. ret = clk_disable(c);
  93. return ret;
  94. }
  95. static int starfive_clk_disable(struct clk *clk)
  96. {
  97. return __starfive_clk_enable(clk, 0);
  98. }
  99. static int starfive_clk_enable(struct clk *clk)
  100. {
  101. return __starfive_clk_enable(clk, 1);
  102. }
  103. static int starfive_clk_set_parent(struct clk *clk, struct clk *parent)
  104. {
  105. struct clk *c, *cp;
  106. int ret;
  107. debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
  108. ret = clk_get_by_id(clk->id, &c);
  109. if (ret)
  110. return ret;
  111. ret = clk_get_by_id(parent->id, &cp);
  112. if (ret)
  113. return ret;
  114. ret = clk_set_parent(c, cp);
  115. c->dev->parent = cp->dev;
  116. return ret;
  117. }
  118. static const struct clk_ops starfive_clk_ops = {
  119. .set_rate = starfive_clk_set_rate,
  120. .get_rate = starfive_clk_get_rate,
  121. .enable = starfive_clk_enable,
  122. .disable = starfive_clk_disable,
  123. .set_parent = starfive_clk_set_parent,
  124. };
  125. static struct clk *starfive_clk_mux(void __iomem *reg,
  126. const char *name,
  127. unsigned int offset,
  128. u8 width,
  129. const char * const *parent_names,
  130. u8 num_parents)
  131. {
  132. return clk_register_mux(NULL, name, parent_names, num_parents, 0,
  133. reg + offset, STARFIVE_CLK_MUX_SHIFT, width, 0);
  134. }
  135. static struct clk *starfive_clk_gate(void __iomem *reg,
  136. const char *name,
  137. const char *parent_name,
  138. unsigned int offset)
  139. {
  140. return clk_register_gate(NULL, name, parent_name, 0, reg+offset,
  141. STARFIVE_CLK_ENABLE_SHIFT, 0, NULL);
  142. }
  143. static struct clk *starfive_clk_fix_factor(void __iomem *reg,
  144. const char *name,
  145. const char *parent_name,
  146. unsigned int mult,
  147. unsigned int div)
  148. {
  149. return clk_register_fixed_factor(NULL, name, parent_name,
  150. 0, mult, div);
  151. }
  152. static struct clk *starfive_clk_divider(void __iomem *reg,
  153. const char *name,
  154. const char *parent_name,
  155. unsigned int offset,
  156. u8 width)
  157. {
  158. return clk_register_divider(NULL, name, parent_name, 0, reg+offset, 0,
  159. width, CLK_DIVIDER_ONE_BASED);
  160. }
  161. static struct clk *starfive_clk_composite(void __iomem *reg,
  162. const char *name,
  163. const char * const *parent_names,
  164. unsigned int num_parents,
  165. unsigned int offset,
  166. unsigned int mux_width,
  167. unsigned int gate_width,
  168. unsigned int div_width)
  169. {
  170. struct clk *clk = ERR_PTR(-ENOMEM);
  171. struct clk_divider *div = NULL;
  172. struct clk_gate *gate = NULL;
  173. struct clk_mux *mux = NULL;
  174. int mask_arry[4] = {0x1, 0x3, 0x7, 0xF};
  175. int mask;
  176. if (mux_width) {
  177. if (mux_width > 4)
  178. goto fail;
  179. else
  180. mask = mask_arry[mux_width-1];
  181. mux = kzalloc(sizeof(*mux), GFP_KERNEL);
  182. if (!mux)
  183. goto fail;
  184. mux->reg = reg + offset;
  185. mux->mask = mask;
  186. mux->shift = STARFIVE_CLK_MUX_SHIFT;
  187. mux->num_parents = num_parents;
  188. mux->flags = 0;
  189. mux->parent_names = parent_names;
  190. }
  191. if (gate_width) {
  192. gate = kzalloc(sizeof(*gate), GFP_KERNEL);
  193. if (!gate)
  194. goto fail;
  195. gate->reg = reg + offset;
  196. gate->bit_idx = STARFIVE_CLK_ENABLE_SHIFT;
  197. gate->flags = 0;
  198. }
  199. if (div_width) {
  200. div = kzalloc(sizeof(*div), GFP_KERNEL);
  201. if (!div)
  202. goto fail;
  203. div->reg = reg + offset;
  204. div->shift = STARFIVE_CLK_DIV_SHIFT;
  205. div->width = div_width;
  206. div->flags = CLK_DIVIDER_ONE_BASED;
  207. div->table = NULL;
  208. }
  209. clk = clk_register_composite(NULL, name,
  210. parent_names, num_parents,
  211. &mux->clk, &clk_mux_ops,
  212. &div->clk, &clk_divider_ops,
  213. &gate->clk, &clk_gate_ops, 0);
  214. if (IS_ERR(clk))
  215. goto fail;
  216. return clk;
  217. fail:
  218. kfree(gate);
  219. kfree(div);
  220. kfree(mux);
  221. return ERR_CAST(clk);
  222. }
  223. static struct clk *starfive_clk_fix_parent_composite(void __iomem *reg,
  224. const char *name,
  225. const char *parent_names,
  226. unsigned int offset,
  227. unsigned int mux_width,
  228. unsigned int gate_width,
  229. unsigned int div_width)
  230. {
  231. const char * const *parents;
  232. parents = &parent_names;
  233. return starfive_clk_composite(reg, name, parents, 1, offset,
  234. mux_width, gate_width, div_width);
  235. }
  236. static struct clk *starfive_clk_gate_divider(void __iomem *reg,
  237. const char *name,
  238. const char *parent,
  239. unsigned int offset,
  240. unsigned int width)
  241. {
  242. const char * const *parent_names;
  243. parent_names = &parent;
  244. return starfive_clk_composite(reg, name, parent_names, 1,
  245. offset, 0, 1, width);
  246. }
  247. static struct clk *starfive_clk_gate_dis(void __iomem *reg,
  248. const char *name,
  249. const char *parent_name,
  250. unsigned int offset)
  251. {
  252. return clk_register_gate(NULL, name, parent_name, 0, reg+offset,
  253. STARFIVE_CLK_ENABLE_SHIFT,
  254. CLK_GATE_SET_TO_DISABLE, NULL);
  255. }
  256. static int jh7110_clk_init(struct udevice *dev)
  257. {
  258. struct jh7110_clk_priv *priv = dev_get_priv(dev);
  259. clk_dm(JH7110_PLL0,
  260. starfive_clk_fix_factor(priv->sys,
  261. "pll0_out", "osc", 52, 1));
  262. clk_dm(JH7110_PLL1,
  263. starfive_clk_fix_factor(priv->sys,
  264. "pll1_out", "osc", 44, 1));
  265. clk_dm(JH7110_PLL2,
  266. starfive_clk_fix_factor(priv->sys,
  267. "pll2_out", "osc", 51, 1));
  268. /*root*/
  269. clk_dm(JH7110_CPU_ROOT,
  270. starfive_clk_mux(priv->sys, "cpu_root",
  271. SYS_OFFSET(JH7110_CPU_ROOT), 1,
  272. cpu_root_sels, ARRAY_SIZE(cpu_root_sels)));
  273. clk_dm(JH7110_CPU_CORE,
  274. starfive_clk_divider(priv->sys,
  275. "cpu_core", "cpu_root",
  276. SYS_OFFSET(JH7110_CPU_CORE), 3));
  277. clk_dm(JH7110_CPU_BUS,
  278. starfive_clk_divider(priv->sys,
  279. "cpu_bus", "cpu_core",
  280. SYS_OFFSET(JH7110_CPU_BUS), 2));
  281. clk_dm(JH7110_DDR_ROOT,
  282. starfive_clk_fix_factor(priv->sys,
  283. "ddr_root", "pll1_out", 1, 1));
  284. clk_dm(JH7110_GMACUSB_ROOT,
  285. starfive_clk_fix_factor(priv->sys,
  286. "gmacusb_root", "pll0_out", 1, 1));
  287. clk_dm(JH7110_PERH_ROOT,
  288. starfive_clk_mux(priv->sys, "perh_root",
  289. SYS_OFFSET(JH7110_PERH_ROOT), 1,
  290. perh_root_sels, ARRAY_SIZE(perh_root_sels)));
  291. clk_dm(JH7110_BUS_ROOT,
  292. starfive_clk_mux(priv->sys, "bus_root",
  293. SYS_OFFSET(JH7110_BUS_ROOT), 1,
  294. bus_root_sels, ARRAY_SIZE(bus_root_sels)));
  295. clk_dm(JH7110_AXI_CFG0,
  296. starfive_clk_divider(priv->sys,
  297. "axi_cfg0", "bus_root",
  298. SYS_OFFSET(JH7110_AXI_CFG0), 2));
  299. clk_dm(JH7110_STG_AXIAHB,
  300. starfive_clk_divider(priv->sys,
  301. "stg_axiahb", "axi_cfg0",
  302. SYS_OFFSET(JH7110_STG_AXIAHB), 2));
  303. clk_dm(JH7110_AHB0,
  304. starfive_clk_gate(priv->sys,
  305. "ahb0", "stg_axiahb",
  306. SYS_OFFSET(JH7110_AHB0)));
  307. clk_dm(JH7110_AHB1,
  308. starfive_clk_gate(priv->sys,
  309. "ahb1", "stg_axiahb",
  310. SYS_OFFSET(JH7110_AHB1)));
  311. clk_dm(JH7110_APB_BUS_FUNC,
  312. starfive_clk_divider(priv->sys,
  313. "apb_bus_func", "stg_axiahb",
  314. SYS_OFFSET(JH7110_APB_BUS_FUNC), 4));
  315. clk_dm(JH7110_OSC_DIV4,
  316. starfive_clk_divider(priv->aon,
  317. "osc_div4", "osc",
  318. AON_OFFSET(JH7110_OSC_DIV4), 3));
  319. clk_dm(JH7110_AON_APB_FUNC,
  320. starfive_clk_mux(priv->aon, "aon_apb_func",
  321. AON_OFFSET(JH7110_AON_APB_FUNC), 1,
  322. aon_apb_func_sels, ARRAY_SIZE(aon_apb_func_sels)));
  323. clk_dm(JH7110_APB_BUS,
  324. starfive_clk_fix_factor(priv->sys,
  325. "apb_bus", "aon_apb_func", 1, 1));
  326. clk_dm(JH7110_APB0,
  327. starfive_clk_gate(priv->sys,
  328. "apb0", "apb_bus",
  329. SYS_OFFSET(JH7110_APB0)));
  330. clk_dm(JH7110_APB12,
  331. starfive_clk_fix_factor(priv->sys,
  332. "apb12", "apb_bus", 1, 1));
  333. clk_dm(JH7110_AON_APB,
  334. starfive_clk_fix_factor(priv->sys,
  335. "aon_apb", "apb_bus_func", 1, 1));
  336. /*hifi4*/
  337. clk_dm(JH7110_HIFI4_CORE,
  338. starfive_clk_divider(priv->sys,
  339. "hifi4_core", "bus_root",
  340. SYS_OFFSET(JH7110_HIFI4_CORE), 4));
  341. /*QSPI*/
  342. clk_dm(JH7110_QSPI_CLK_AHB,
  343. starfive_clk_gate(priv->sys,
  344. "u0_cdns_qspi_clk_ahb", "ahb1",
  345. SYS_OFFSET(JH7110_QSPI_CLK_AHB)));
  346. clk_dm(JH7110_QSPI_CLK_APB,
  347. starfive_clk_gate(priv->sys,
  348. "u0_cdns_qspi_clk_apb", "apb12",
  349. SYS_OFFSET(JH7110_QSPI_CLK_APB)));
  350. clk_dm(JH7110_QSPI_REF_SRC,
  351. starfive_clk_divider(priv->sys,
  352. "u0_cdns_qspi_ref_src", "gmacusb_root",
  353. SYS_OFFSET(JH7110_QSPI_REF_SRC), 5));
  354. clk_dm(JH7110_QSPI_CLK_REF,
  355. starfive_clk_composite(priv->sys,
  356. "u0_cdns_qspi_clk_ref",
  357. qspi_ref_sels, ARRAY_SIZE(qspi_ref_sels),
  358. SYS_OFFSET(JH7110_QSPI_CLK_REF), 1, 1, 0));
  359. /*SDIO*/
  360. clk_dm(JH7110_SDIO0_CLK_AHB,
  361. starfive_clk_gate(priv->sys,
  362. "u0_dw_sdio_clk_ahb", "ahb0",
  363. SYS_OFFSET(JH7110_SDIO0_CLK_AHB)));
  364. clk_dm(JH7110_SDIO1_CLK_AHB,
  365. starfive_clk_gate(priv->sys,
  366. "u1_dw_sdio_clk_ahb", "ahb0",
  367. SYS_OFFSET(JH7110_SDIO1_CLK_AHB)));
  368. clk_dm(JH7110_SDIO0_CLK_SDCARD,
  369. starfive_clk_fix_parent_composite(priv->sys,
  370. "u0_dw_sdio_clk_sdcard", "axi_cfg0",
  371. SYS_OFFSET(JH7110_SDIO0_CLK_SDCARD), 0, 1, 4));
  372. clk_dm(JH7110_SDIO1_CLK_SDCARD,
  373. starfive_clk_fix_parent_composite(priv->sys,
  374. "u1_dw_sdio_clk_sdcard", "axi_cfg0",
  375. SYS_OFFSET(JH7110_SDIO1_CLK_SDCARD), 0, 1, 4));
  376. /*STG*/
  377. clk_dm(JH7110_USB_125M,
  378. starfive_clk_divider(priv->sys,
  379. "usb_125m", "gmacusb_root",
  380. SYS_OFFSET(JH7110_USB_125M), 4));
  381. /*GMAC1*/
  382. clk_dm(JH7110_GMAC5_CLK_AHB,
  383. starfive_clk_gate(priv->sys,
  384. "u1_dw_gmac5_axi64_clk_ahb", "ahb0",
  385. SYS_OFFSET(JH7110_GMAC5_CLK_AHB)));
  386. clk_dm(JH7110_GMAC5_CLK_AXI,
  387. starfive_clk_gate(priv->sys,
  388. "u1_dw_gmac5_axi64_clk_axi", "stg_axiahb",
  389. SYS_OFFSET(JH7110_GMAC5_CLK_AXI)));
  390. clk_dm(JH7110_GMAC_SRC,
  391. starfive_clk_divider(priv->sys,
  392. "gmac_src", "gmacusb_root",
  393. SYS_OFFSET(JH7110_GMAC_SRC), 3));
  394. clk_dm(JH7110_GMAC1_GTXCLK,
  395. starfive_clk_divider(priv->sys,
  396. "gmac1_gtxclk", "gmacusb_root",
  397. SYS_OFFSET(JH7110_GMAC1_GTXCLK), 4));
  398. clk_dm(JH7110_GMAC1_RMII_RTX,
  399. starfive_clk_divider(priv->sys,
  400. "gmac1_rmii_rtx", "gmac1_rmii_refin",
  401. SYS_OFFSET(JH7110_GMAC1_RMII_RTX), 5));
  402. clk_dm(JH7110_GMAC5_CLK_PTP,
  403. starfive_clk_gate_divider(priv->sys,
  404. "u1_dw_gmac5_axi64_clk_ptp", "gmac_src",
  405. SYS_OFFSET(JH7110_GMAC5_CLK_PTP), 5));
  406. clk_dm(JH7110_GMAC5_CLK_RMII,
  407. starfive_clk_fix_factor(priv->sys,
  408. "u1_dw_gmac5_axi64_clk_rmii",
  409. "gmac1_rmii_refin", 1, 1));
  410. clk_dm(JH7110_GMAC5_CLK_TX,
  411. starfive_clk_composite(priv->sys,
  412. "u1_dw_gmac5_axi64_clk_tx",
  413. gmac5_tx_sels, ARRAY_SIZE(gmac5_tx_sels),
  414. SYS_OFFSET(JH7110_GMAC5_CLK_TX), 1, 1, 0));
  415. clk_dm(JH7110_GMAC5_CLK_TX_INV,
  416. starfive_clk_gate_dis(priv->sys,
  417. "u1_dw_gmac5_axi64_clk_tx_inv",
  418. "u1_dw_gmac5_axi64_clk_tx",
  419. SYS_OFFSET(JH7110_GMAC5_CLK_TX_INV)));
  420. clk_dm(JH7110_GMAC1_GTXC,
  421. starfive_clk_gate_divider(priv->sys,
  422. "gmac1_gtxc", "gmac1_gtxclk",
  423. SYS_OFFSET(JH7110_GMAC1_GTXC), 6));
  424. /*GMAC0*/
  425. clk_dm(JH7110_AON_AHB,
  426. starfive_clk_fix_factor(priv->sys, "aon_ahb",
  427. "stg_axiahb", 1, 1));
  428. clk_dm(JH7110_GMAC0_GTXCLK,
  429. starfive_clk_gate_divider(priv->sys, "gmac0_gtxclk",
  430. "gmacusb_root", SYS_OFFSET(JH7110_GMAC0_GTXCLK), 4));
  431. clk_dm(JH7110_GMAC0_PTP,
  432. starfive_clk_gate_divider(priv->sys, "gmac0_ptp",
  433. "gmac_src", SYS_OFFSET(JH7110_GMAC0_PTP), 5));
  434. clk_dm(JH7110_GMAC_PHY,
  435. starfive_clk_gate_divider(priv->sys, "gmac_phy",
  436. "gmac_src", SYS_OFFSET(JH7110_GMAC_PHY), 5));
  437. clk_dm(JH7110_GMAC0_GTXC,
  438. starfive_clk_gate_divider(priv->sys, "gmac0_gtxc",
  439. "gmac0_gtxclk", SYS_OFFSET(JH7110_GMAC0_GTXC), 5));
  440. /*UART0*/
  441. clk_dm(JH7110_UART0_CLK_APB,
  442. starfive_clk_gate(priv->sys,
  443. "u0_dw_uart_clk_apb", "apb0",
  444. SYS_OFFSET(JH7110_UART0_CLK_APB)));
  445. clk_dm(JH7110_UART0_CLK_CORE,
  446. starfive_clk_gate(priv->sys,
  447. "u0_dw_uart_clk_core", "osc",
  448. SYS_OFFSET(JH7110_UART0_CLK_CORE)));
  449. /*UART1*/
  450. clk_dm(JH7110_UART1_CLK_APB,
  451. starfive_clk_gate(priv->sys,
  452. "u1_dw_uart_clk_apb", "apb0",
  453. SYS_OFFSET(JH7110_UART1_CLK_APB)));
  454. clk_dm(JH7110_UART1_CLK_CORE,
  455. starfive_clk_gate(priv->sys,
  456. "u1_dw_uart_clk_core", "osc",
  457. SYS_OFFSET(JH7110_UART1_CLK_CORE)));
  458. /*UART2*/
  459. clk_dm(JH7110_UART2_CLK_APB,
  460. starfive_clk_gate(priv->sys,
  461. "u2_dw_uart_clk_apb", "apb0",
  462. SYS_OFFSET(JH7110_UART2_CLK_APB)));
  463. clk_dm(JH7110_UART2_CLK_CORE,
  464. starfive_clk_gate(priv->sys,
  465. "u2_dw_uart_clk_core", "osc",
  466. SYS_OFFSET(JH7110_UART2_CLK_CORE)));
  467. /*UART3*/
  468. clk_dm(JH7110_UART3_CLK_APB,
  469. starfive_clk_gate(priv->sys,
  470. "u3_dw_uart_clk_apb", "apb0",
  471. SYS_OFFSET(JH7110_UART3_CLK_APB)));
  472. clk_dm(JH7110_UART3_CLK_CORE,
  473. starfive_clk_gate(priv->sys,
  474. "u3_dw_uart_clk_core", "perh_root",
  475. SYS_OFFSET(JH7110_UART3_CLK_CORE)));
  476. /*UART4*/
  477. clk_dm(JH7110_UART4_CLK_APB,
  478. starfive_clk_gate(priv->sys,
  479. "u4_dw_uart_clk_apb", "apb0",
  480. SYS_OFFSET(JH7110_UART4_CLK_APB)));
  481. clk_dm(JH7110_UART4_CLK_CORE,
  482. starfive_clk_gate(priv->sys,
  483. "u4_dw_uart_clk_core", "perh_root",
  484. SYS_OFFSET(JH7110_UART4_CLK_CORE)));
  485. /*UART5*/
  486. clk_dm(JH7110_UART5_CLK_APB,
  487. starfive_clk_gate(priv->sys,
  488. "u5_dw_uart_clk_apb", "apb0",
  489. SYS_OFFSET(JH7110_UART5_CLK_APB)));
  490. clk_dm(JH7110_UART5_CLK_CORE,
  491. starfive_clk_gate(priv->sys,
  492. "u5_dw_uart_clk_core", "perh_root",
  493. SYS_OFFSET(JH7110_UART5_CLK_CORE)));
  494. clk_dm(JH7110_STG_APB,
  495. starfive_clk_fix_factor(priv->stg,
  496. "stg_apb", "apb_bus", 1, 1));
  497. clk_dm(JH7110_HIFI4_CLK_CORE,
  498. starfive_clk_gate(priv->stg,
  499. "u0_hifi4_clk_core", "hifi4_core",
  500. STG_OFFSET(JH7110_HIFI4_CLK_CORE)));
  501. clk_dm(JH7110_USB0_CLK_USB_APB,
  502. starfive_clk_gate(priv->stg,
  503. "u0_cdn_usb_clk_usb_apb", "stg_apb",
  504. STG_OFFSET(JH7110_USB0_CLK_USB_APB)));
  505. clk_dm(JH7110_USB0_CLK_UTMI_APB,
  506. starfive_clk_gate(priv->stg,
  507. "u0_cdn_usb_clk_utmi_apb", "stg_apb",
  508. STG_OFFSET(JH7110_USB0_CLK_UTMI_APB)));
  509. clk_dm(JH7110_USB0_CLK_AXI,
  510. starfive_clk_gate(priv->stg,
  511. "u0_cdn_usb_clk_axi", "stg_axiahb",
  512. STG_OFFSET(JH7110_USB0_CLK_AXI)));
  513. clk_dm(JH7110_USB0_CLK_LPM,
  514. starfive_clk_gate_divider(priv->stg,
  515. "u0_cdn_usb_clk_lpm", "osc",
  516. STG_OFFSET(JH7110_USB0_CLK_LPM), 2));
  517. clk_dm(JH7110_USB0_CLK_STB,
  518. starfive_clk_gate_divider(priv->stg,
  519. "u0_cdn_usb_clk_stb", "osc",
  520. STG_OFFSET(JH7110_USB0_CLK_STB), 3));
  521. clk_dm(JH7110_USB0_CLK_APP_125,
  522. starfive_clk_gate(priv->stg,
  523. "u0_cdn_usb_clk_app_125", "usb_125m",
  524. STG_OFFSET(JH7110_USB0_CLK_APP_125)));
  525. clk_dm(JH7110_USB0_REFCLK,
  526. starfive_clk_divider(priv->stg,
  527. "u0_cdn_usb_refclk", "osc",
  528. STG_OFFSET(JH7110_USB0_REFCLK), 2));
  529. /*GMAC1*/
  530. clk_dm(JH7110_U0_GMAC5_CLK_AHB,
  531. starfive_clk_gate(priv->aon,
  532. "u0_dw_gmac5_axi64_clk_ahb", "aon_ahb",
  533. AON_OFFSET(JH7110_U0_GMAC5_CLK_AHB)));
  534. clk_dm(JH7110_U0_GMAC5_CLK_AXI,
  535. starfive_clk_gate(priv->aon,
  536. "u0_dw_gmac5_axi64_clk_axi", "aon_ahb",
  537. AON_OFFSET(JH7110_U0_GMAC5_CLK_AXI)));
  538. clk_dm(JH7110_GMAC0_RMII_RTX,
  539. starfive_clk_divider(priv->aon,
  540. "gmac0_rmii_rtx", "gmac0_rmii_refin",
  541. AON_OFFSET(JH7110_GMAC0_RMII_RTX), 5));
  542. clk_dm(JH7110_U0_GMAC5_CLK_PTP,
  543. starfive_clk_fix_factor(priv->aon,
  544. "u0_dw_gmac5_axi64_clk_ptp",
  545. "gmac0_ptp", 1, 1));
  546. clk_dm(JH7110_U0_GMAC5_CLK_TX,
  547. starfive_clk_composite(priv->aon,
  548. "u0_dw_gmac5_axi64_clk_tx",
  549. u0_dw_gmac5_axi64_clk_tx_sels,
  550. ARRAY_SIZE(u0_dw_gmac5_axi64_clk_tx_sels),
  551. AON_OFFSET(JH7110_U0_GMAC5_CLK_TX), 1, 1, 0));
  552. clk_dm(JH7110_U0_GMAC5_CLK_TX_INV,
  553. starfive_clk_gate_dis(priv->aon,
  554. "u0_dw_gmac5_axi64_clk_tx_inv",
  555. "u0_dw_gmac5_axi64_clk_tx",
  556. AON_OFFSET(JH7110_U0_GMAC5_CLK_TX_INV)));
  557. clk_dm(JH7110_U0_GMAC5_CLK_RMII,
  558. starfive_clk_fix_factor(priv->aon,
  559. "u0_dw_gmac5_axi64_clk_rmii",
  560. "gmac0_rmii_refin", 1, 1));
  561. /*otp*/
  562. clk_dm(JH7110_OTPC_CLK_APB,
  563. starfive_clk_gate(priv->aon,
  564. "u0_otpc_clk_apb", "aon_apb",
  565. AON_OFFSET(JH7110_OTPC_CLK_APB)));
  566. return 0;
  567. }
  568. static int jh7110_clk_probe(struct udevice *dev)
  569. {
  570. struct jh7110_clk_priv *priv = dev_get_priv(dev);
  571. priv->aon = dev_remap_addr_name(dev, "aon");
  572. if (!priv->aon)
  573. return -EINVAL;
  574. priv->sys = dev_remap_addr_name(dev, "sys");
  575. if (!priv->sys)
  576. return -EINVAL;
  577. priv->stg = dev_remap_addr_name(dev, "stg");
  578. if (!priv->stg)
  579. return -EINVAL;
  580. return jh7110_clk_init(dev);
  581. }
  582. static const struct udevice_id jh7110_clk_of_match[] = {
  583. { .compatible = "starfive,jh7110-clkgen" },
  584. { }
  585. };
  586. U_BOOT_DRIVER(jh7110_clk) = {
  587. .name = "jh7110_clk",
  588. .id = UCLASS_CLK,
  589. .of_match = jh7110_clk_of_match,
  590. .probe = jh7110_clk_probe,
  591. .ops = &starfive_clk_ops,
  592. .priv_auto = sizeof(struct jh7110_clk_priv),
  593. .flags = DM_FLAG_PRE_RELOC,
  594. };