clock_manager_arria10.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2016-2017 Intel Corporation
  4. */
  5. #include <common.h>
  6. #include <fdtdec.h>
  7. #include <asm/io.h>
  8. #include <dm.h>
  9. #include <clk.h>
  10. #include <dm/device-internal.h>
  11. #include <asm/arch/clock_manager.h>
  12. #ifdef CONFIG_SPL_BUILD
  13. static u32 eosc1_hz;
  14. static u32 cb_intosc_hz;
  15. static u32 f2s_free_hz;
  16. struct mainpll_cfg {
  17. u32 vco0_psrc;
  18. u32 vco1_denom;
  19. u32 vco1_numer;
  20. u32 mpuclk;
  21. u32 mpuclk_cnt;
  22. u32 mpuclk_src;
  23. u32 nocclk;
  24. u32 nocclk_cnt;
  25. u32 nocclk_src;
  26. u32 cntr2clk_cnt;
  27. u32 cntr3clk_cnt;
  28. u32 cntr4clk_cnt;
  29. u32 cntr5clk_cnt;
  30. u32 cntr6clk_cnt;
  31. u32 cntr7clk_cnt;
  32. u32 cntr7clk_src;
  33. u32 cntr8clk_cnt;
  34. u32 cntr9clk_cnt;
  35. u32 cntr9clk_src;
  36. u32 cntr15clk_cnt;
  37. u32 nocdiv_l4mainclk;
  38. u32 nocdiv_l4mpclk;
  39. u32 nocdiv_l4spclk;
  40. u32 nocdiv_csatclk;
  41. u32 nocdiv_cstraceclk;
  42. u32 nocdiv_cspdbclk;
  43. };
  44. struct perpll_cfg {
  45. u32 vco0_psrc;
  46. u32 vco1_denom;
  47. u32 vco1_numer;
  48. u32 cntr2clk_cnt;
  49. u32 cntr2clk_src;
  50. u32 cntr3clk_cnt;
  51. u32 cntr3clk_src;
  52. u32 cntr4clk_cnt;
  53. u32 cntr4clk_src;
  54. u32 cntr5clk_cnt;
  55. u32 cntr5clk_src;
  56. u32 cntr6clk_cnt;
  57. u32 cntr6clk_src;
  58. u32 cntr7clk_cnt;
  59. u32 cntr8clk_cnt;
  60. u32 cntr8clk_src;
  61. u32 cntr9clk_cnt;
  62. u32 cntr9clk_src;
  63. u32 emacctl_emac0sel;
  64. u32 emacctl_emac1sel;
  65. u32 emacctl_emac2sel;
  66. u32 gpiodiv_gpiodbclk;
  67. };
  68. struct strtou32 {
  69. const char *str;
  70. const u32 val;
  71. };
  72. static const struct strtou32 mainpll_cfg_tab[] = {
  73. { "vco0-psrc", offsetof(struct mainpll_cfg, vco0_psrc) },
  74. { "vco1-denom", offsetof(struct mainpll_cfg, vco1_denom) },
  75. { "vco1-numer", offsetof(struct mainpll_cfg, vco1_numer) },
  76. { "mpuclk-cnt", offsetof(struct mainpll_cfg, mpuclk_cnt) },
  77. { "mpuclk-src", offsetof(struct mainpll_cfg, mpuclk_src) },
  78. { "nocclk-cnt", offsetof(struct mainpll_cfg, nocclk_cnt) },
  79. { "nocclk-src", offsetof(struct mainpll_cfg, nocclk_src) },
  80. { "cntr2clk-cnt", offsetof(struct mainpll_cfg, cntr2clk_cnt) },
  81. { "cntr3clk-cnt", offsetof(struct mainpll_cfg, cntr3clk_cnt) },
  82. { "cntr4clk-cnt", offsetof(struct mainpll_cfg, cntr4clk_cnt) },
  83. { "cntr5clk-cnt", offsetof(struct mainpll_cfg, cntr5clk_cnt) },
  84. { "cntr6clk-cnt", offsetof(struct mainpll_cfg, cntr6clk_cnt) },
  85. { "cntr7clk-cnt", offsetof(struct mainpll_cfg, cntr7clk_cnt) },
  86. { "cntr7clk-src", offsetof(struct mainpll_cfg, cntr7clk_src) },
  87. { "cntr8clk-cnt", offsetof(struct mainpll_cfg, cntr8clk_cnt) },
  88. { "cntr9clk-cnt", offsetof(struct mainpll_cfg, cntr9clk_cnt) },
  89. { "cntr9clk-src", offsetof(struct mainpll_cfg, cntr9clk_src) },
  90. { "cntr15clk-cnt", offsetof(struct mainpll_cfg, cntr15clk_cnt) },
  91. { "nocdiv-l4mainclk", offsetof(struct mainpll_cfg, nocdiv_l4mainclk) },
  92. { "nocdiv-l4mpclk", offsetof(struct mainpll_cfg, nocdiv_l4mpclk) },
  93. { "nocdiv-l4spclk", offsetof(struct mainpll_cfg, nocdiv_l4spclk) },
  94. { "nocdiv-csatclk", offsetof(struct mainpll_cfg, nocdiv_csatclk) },
  95. { "nocdiv-cstraceclk", offsetof(struct mainpll_cfg, nocdiv_cstraceclk) },
  96. { "nocdiv-cspdbgclk", offsetof(struct mainpll_cfg, nocdiv_cspdbclk) },
  97. };
  98. static const struct strtou32 perpll_cfg_tab[] = {
  99. { "vco0-psrc", offsetof(struct perpll_cfg, vco0_psrc) },
  100. { "vco1-denom", offsetof(struct perpll_cfg, vco1_denom) },
  101. { "vco1-numer", offsetof(struct perpll_cfg, vco1_numer) },
  102. { "cntr2clk-cnt", offsetof(struct perpll_cfg, cntr2clk_cnt) },
  103. { "cntr2clk-src", offsetof(struct perpll_cfg, cntr2clk_src) },
  104. { "cntr3clk-cnt", offsetof(struct perpll_cfg, cntr3clk_cnt) },
  105. { "cntr3clk-src", offsetof(struct perpll_cfg, cntr3clk_src) },
  106. { "cntr4clk-cnt", offsetof(struct perpll_cfg, cntr4clk_cnt) },
  107. { "cntr4clk-src", offsetof(struct perpll_cfg, cntr4clk_src) },
  108. { "cntr5clk-cnt", offsetof(struct perpll_cfg, cntr5clk_cnt) },
  109. { "cntr5clk-src", offsetof(struct perpll_cfg, cntr5clk_src) },
  110. { "cntr6clk-cnt", offsetof(struct perpll_cfg, cntr6clk_cnt) },
  111. { "cntr6clk-src", offsetof(struct perpll_cfg, cntr6clk_src) },
  112. { "cntr7clk-cnt", offsetof(struct perpll_cfg, cntr7clk_cnt) },
  113. { "cntr8clk-cnt", offsetof(struct perpll_cfg, cntr8clk_cnt) },
  114. { "cntr8clk-src", offsetof(struct perpll_cfg, cntr8clk_src) },
  115. { "cntr9clk-cnt", offsetof(struct perpll_cfg, cntr9clk_cnt) },
  116. { "emacctl-emac0sel", offsetof(struct perpll_cfg, emacctl_emac0sel) },
  117. { "emacctl-emac1sel", offsetof(struct perpll_cfg, emacctl_emac1sel) },
  118. { "emacctl-emac2sel", offsetof(struct perpll_cfg, emacctl_emac2sel) },
  119. { "gpiodiv-gpiodbclk", offsetof(struct perpll_cfg, gpiodiv_gpiodbclk) },
  120. };
  121. static const struct strtou32 alteragrp_cfg_tab[] = {
  122. { "nocclk", offsetof(struct mainpll_cfg, nocclk) },
  123. { "mpuclk", offsetof(struct mainpll_cfg, mpuclk) },
  124. };
  125. struct strtopu32 {
  126. const char *str;
  127. u32 *p;
  128. };
  129. const struct strtopu32 dt_to_val[] = {
  130. { "altera_arria10_hps_eosc1", &eosc1_hz },
  131. { "altera_arria10_hps_cb_intosc_ls", &cb_intosc_hz },
  132. { "altera_arria10_hps_f2h_free", &f2s_free_hz },
  133. };
  134. static int of_to_struct(const void *blob, int node, const struct strtou32 *cfg_tab,
  135. int cfg_tab_len, void *cfg)
  136. {
  137. int i;
  138. u32 val;
  139. for (i = 0; i < cfg_tab_len; i++) {
  140. if (fdtdec_get_int_array(blob, node, cfg_tab[i].str, &val, 1)) {
  141. /* could not find required property */
  142. return -EINVAL;
  143. }
  144. *(u32 *)(cfg + cfg_tab[i].val) = val;
  145. }
  146. return 0;
  147. }
  148. static int of_get_input_clks(const void *blob)
  149. {
  150. struct udevice *dev;
  151. struct clk clk;
  152. int i, ret;
  153. for (i = 0; i < ARRAY_SIZE(dt_to_val); i++) {
  154. memset(&clk, 0, sizeof(clk));
  155. ret = uclass_get_device_by_name(UCLASS_CLK, dt_to_val[i].str,
  156. &dev);
  157. if (ret)
  158. return ret;
  159. ret = clk_request(dev, &clk);
  160. if (ret)
  161. return ret;
  162. *dt_to_val[i].p = clk_get_rate(&clk);
  163. }
  164. return 0;
  165. }
  166. static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg,
  167. struct perpll_cfg *per_cfg)
  168. {
  169. int ret, node, child, len;
  170. const char *node_name;
  171. ret = of_get_input_clks(blob);
  172. if (ret)
  173. return ret;
  174. node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK_INIT);
  175. if (node < 0)
  176. return -EINVAL;
  177. child = fdt_first_subnode(blob, node);
  178. if (child < 0)
  179. return -EINVAL;
  180. node_name = fdt_get_name(blob, child, &len);
  181. while (node_name) {
  182. if (!strcmp(node_name, "mainpll")) {
  183. if (of_to_struct(blob, child, mainpll_cfg_tab,
  184. ARRAY_SIZE(mainpll_cfg_tab), main_cfg))
  185. return -EINVAL;
  186. } else if (!strcmp(node_name, "perpll")) {
  187. if (of_to_struct(blob, child, perpll_cfg_tab,
  188. ARRAY_SIZE(perpll_cfg_tab), per_cfg))
  189. return -EINVAL;
  190. } else if (!strcmp(node_name, "alteragrp")) {
  191. if (of_to_struct(blob, child, alteragrp_cfg_tab,
  192. ARRAY_SIZE(alteragrp_cfg_tab), main_cfg))
  193. return -EINVAL;
  194. }
  195. child = fdt_next_subnode(blob, child);
  196. if (child < 0)
  197. break;
  198. node_name = fdt_get_name(blob, child, &len);
  199. }
  200. return 0;
  201. }
  202. static const struct socfpga_clock_manager *clock_manager_base =
  203. (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
  204. /* calculate the intended main VCO frequency based on handoff */
  205. static unsigned int cm_calc_handoff_main_vco_clk_hz
  206. (struct mainpll_cfg *main_cfg)
  207. {
  208. unsigned int clk_hz;
  209. /* Check main VCO clock source: eosc, intosc or f2s? */
  210. switch (main_cfg->vco0_psrc) {
  211. case CLKMGR_MAINPLL_VCO0_PSRC_EOSC:
  212. clk_hz = eosc1_hz;
  213. break;
  214. case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC:
  215. clk_hz = cb_intosc_hz;
  216. break;
  217. case CLKMGR_MAINPLL_VCO0_PSRC_F2S:
  218. clk_hz = f2s_free_hz;
  219. break;
  220. default:
  221. return 0;
  222. }
  223. /* calculate the VCO frequency */
  224. clk_hz /= 1 + main_cfg->vco1_denom;
  225. clk_hz *= 1 + main_cfg->vco1_numer;
  226. return clk_hz;
  227. }
  228. /* calculate the intended periph VCO frequency based on handoff */
  229. static unsigned int cm_calc_handoff_periph_vco_clk_hz(
  230. struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
  231. {
  232. unsigned int clk_hz;
  233. /* Check periph VCO clock source: eosc, intosc, f2s or mainpll? */
  234. switch (per_cfg->vco0_psrc) {
  235. case CLKMGR_PERPLL_VCO0_PSRC_EOSC:
  236. clk_hz = eosc1_hz;
  237. break;
  238. case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC:
  239. clk_hz = cb_intosc_hz;
  240. break;
  241. case CLKMGR_PERPLL_VCO0_PSRC_F2S:
  242. clk_hz = f2s_free_hz;
  243. break;
  244. case CLKMGR_PERPLL_VCO0_PSRC_MAIN:
  245. clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
  246. clk_hz /= main_cfg->cntr15clk_cnt;
  247. break;
  248. default:
  249. return 0;
  250. }
  251. /* calculate the VCO frequency */
  252. clk_hz /= 1 + per_cfg->vco1_denom;
  253. clk_hz *= 1 + per_cfg->vco1_numer;
  254. return clk_hz;
  255. }
  256. /* calculate the intended MPU clock frequency based on handoff */
  257. static unsigned int cm_calc_handoff_mpu_clk_hz(struct mainpll_cfg *main_cfg,
  258. struct perpll_cfg *per_cfg)
  259. {
  260. unsigned int clk_hz;
  261. /* Check MPU clock source: main, periph, osc1, intosc or f2s? */
  262. switch (main_cfg->mpuclk_src) {
  263. case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN:
  264. clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
  265. clk_hz /= (main_cfg->mpuclk & CLKMGR_MAINPLL_MPUCLK_CNT_MSK)
  266. + 1;
  267. break;
  268. case CLKMGR_MAINPLL_MPUCLK_SRC_PERI:
  269. clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg);
  270. clk_hz /= ((main_cfg->mpuclk >>
  271. CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) &
  272. CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
  273. break;
  274. case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1:
  275. clk_hz = eosc1_hz;
  276. break;
  277. case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC:
  278. clk_hz = cb_intosc_hz;
  279. break;
  280. case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA:
  281. clk_hz = f2s_free_hz;
  282. break;
  283. default:
  284. return 0;
  285. }
  286. clk_hz /= main_cfg->mpuclk_cnt + 1;
  287. return clk_hz;
  288. }
  289. /* calculate the intended NOC clock frequency based on handoff */
  290. static unsigned int cm_calc_handoff_noc_clk_hz(struct mainpll_cfg *main_cfg,
  291. struct perpll_cfg *per_cfg)
  292. {
  293. unsigned int clk_hz;
  294. /* Check MPU clock source: main, periph, osc1, intosc or f2s? */
  295. switch (main_cfg->nocclk_src) {
  296. case CLKMGR_MAINPLL_NOCCLK_SRC_MAIN:
  297. clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
  298. clk_hz /= (main_cfg->nocclk & CLKMGR_MAINPLL_NOCCLK_CNT_MSK)
  299. + 1;
  300. break;
  301. case CLKMGR_MAINPLL_NOCCLK_SRC_PERI:
  302. clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg);
  303. clk_hz /= ((main_cfg->nocclk >>
  304. CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) &
  305. CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1;
  306. break;
  307. case CLKMGR_MAINPLL_NOCCLK_SRC_OSC1:
  308. clk_hz = eosc1_hz;
  309. break;
  310. case CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC:
  311. clk_hz = cb_intosc_hz;
  312. break;
  313. case CLKMGR_MAINPLL_NOCCLK_SRC_FPGA:
  314. clk_hz = f2s_free_hz;
  315. break;
  316. default:
  317. return 0;
  318. }
  319. clk_hz /= main_cfg->nocclk_cnt + 1;
  320. return clk_hz;
  321. }
  322. /* return 1 if PLL ramp is required */
  323. static int cm_is_pll_ramp_required(int main0periph1,
  324. struct mainpll_cfg *main_cfg,
  325. struct perpll_cfg *per_cfg)
  326. {
  327. /* Check for main PLL */
  328. if (main0periph1 == 0) {
  329. /*
  330. * PLL ramp is not required if both MPU clock and NOC clock are
  331. * not sourced from main PLL
  332. */
  333. if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_MAIN &&
  334. main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_MAIN)
  335. return 0;
  336. /*
  337. * PLL ramp is required if MPU clock is sourced from main PLL
  338. * and MPU clock is over 900MHz (as advised by HW team)
  339. */
  340. if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN &&
  341. (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) >
  342. CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ))
  343. return 1;
  344. /*
  345. * PLL ramp is required if NOC clock is sourced from main PLL
  346. * and NOC clock is over 300MHz (as advised by HW team)
  347. */
  348. if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN &&
  349. (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) >
  350. CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ))
  351. return 2;
  352. } else if (main0periph1 == 1) {
  353. /*
  354. * PLL ramp is not required if both MPU clock and NOC clock are
  355. * not sourced from periph PLL
  356. */
  357. if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_PERI &&
  358. main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_PERI)
  359. return 0;
  360. /*
  361. * PLL ramp is required if MPU clock are source from periph PLL
  362. * and MPU clock is over 900MHz (as advised by HW team)
  363. */
  364. if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI &&
  365. (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) >
  366. CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ))
  367. return 1;
  368. /*
  369. * PLL ramp is required if NOC clock are source from periph PLL
  370. * and NOC clock is over 300MHz (as advised by HW team)
  371. */
  372. if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI &&
  373. (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) >
  374. CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ))
  375. return 2;
  376. }
  377. return 0;
  378. }
  379. static u32 cm_calculate_numer(struct mainpll_cfg *main_cfg,
  380. struct perpll_cfg *per_cfg,
  381. u32 safe_hz, u32 clk_hz)
  382. {
  383. u32 cnt;
  384. u32 clk;
  385. u32 shift;
  386. u32 mask;
  387. u32 denom;
  388. if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) {
  389. cnt = main_cfg->mpuclk_cnt;
  390. clk = main_cfg->mpuclk;
  391. shift = 0;
  392. mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK;
  393. denom = main_cfg->vco1_denom;
  394. } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) {
  395. cnt = main_cfg->nocclk_cnt;
  396. clk = main_cfg->nocclk;
  397. shift = 0;
  398. mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK;
  399. denom = main_cfg->vco1_denom;
  400. } else if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
  401. cnt = main_cfg->mpuclk_cnt;
  402. clk = main_cfg->mpuclk;
  403. shift = CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB;
  404. mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK;
  405. denom = per_cfg->vco1_denom;
  406. } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
  407. cnt = main_cfg->nocclk_cnt;
  408. clk = main_cfg->nocclk;
  409. shift = CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB;
  410. mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK;
  411. denom = per_cfg->vco1_denom;
  412. } else {
  413. return 0;
  414. }
  415. return (safe_hz / clk_hz) * (cnt + 1) * (((clk >> shift) & mask) + 1) *
  416. (1 + denom) - 1;
  417. }
  418. /*
  419. * Calculate the new PLL numerator which is based on existing DTS hand off and
  420. * intended safe frequency (safe_hz). Note that PLL ramp is only modifying the
  421. * numerator while maintaining denominator as denominator will influence the
  422. * jitter condition. Please refer A10 HPS TRM for the jitter guide. Note final
  423. * value for numerator is minus with 1 to cater our register value
  424. * representation.
  425. */
  426. static unsigned int cm_calc_safe_pll_numer(int main0periph1,
  427. struct mainpll_cfg *main_cfg,
  428. struct perpll_cfg *per_cfg,
  429. unsigned int safe_hz)
  430. {
  431. unsigned int clk_hz = 0;
  432. /* Check for main PLL */
  433. if (main0periph1 == 0) {
  434. /* Check main VCO clock source: eosc, intosc or f2s? */
  435. switch (main_cfg->vco0_psrc) {
  436. case CLKMGR_MAINPLL_VCO0_PSRC_EOSC:
  437. clk_hz = eosc1_hz;
  438. break;
  439. case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC:
  440. clk_hz = cb_intosc_hz;
  441. break;
  442. case CLKMGR_MAINPLL_VCO0_PSRC_F2S:
  443. clk_hz = f2s_free_hz;
  444. break;
  445. default:
  446. return 0;
  447. }
  448. } else if (main0periph1 == 1) {
  449. /* Check periph VCO clock source: eosc, intosc, f2s, mainpll */
  450. switch (per_cfg->vco0_psrc) {
  451. case CLKMGR_PERPLL_VCO0_PSRC_EOSC:
  452. clk_hz = eosc1_hz;
  453. break;
  454. case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC:
  455. clk_hz = cb_intosc_hz;
  456. break;
  457. case CLKMGR_PERPLL_VCO0_PSRC_F2S:
  458. clk_hz = f2s_free_hz;
  459. break;
  460. case CLKMGR_PERPLL_VCO0_PSRC_MAIN:
  461. clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg);
  462. clk_hz /= main_cfg->cntr15clk_cnt;
  463. break;
  464. default:
  465. return 0;
  466. }
  467. } else {
  468. return 0;
  469. }
  470. return cm_calculate_numer(main_cfg, per_cfg, safe_hz, clk_hz);
  471. }
  472. /* ramping the main PLL to final value */
  473. static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg,
  474. struct perpll_cfg *per_cfg,
  475. unsigned int pll_ramp_main_hz)
  476. {
  477. unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
  478. /* find out the increment value */
  479. if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) {
  480. clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
  481. clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
  482. } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) {
  483. clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
  484. clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
  485. }
  486. /* execute the ramping here */
  487. for (clk_hz = pll_ramp_main_hz + clk_incr_hz;
  488. clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
  489. writel((main_cfg->vco1_denom <<
  490. CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
  491. cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz),
  492. &clock_manager_base->main_pll.vco1);
  493. mdelay(1);
  494. cm_wait_for_lock(LOCKED_MASK);
  495. }
  496. writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
  497. main_cfg->vco1_numer, &clock_manager_base->main_pll.vco1);
  498. mdelay(1);
  499. cm_wait_for_lock(LOCKED_MASK);
  500. }
  501. /* ramping the periph PLL to final value */
  502. static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg,
  503. struct perpll_cfg *per_cfg,
  504. unsigned int pll_ramp_periph_hz)
  505. {
  506. unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
  507. /* find out the increment value */
  508. if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
  509. clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
  510. clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
  511. } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
  512. clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
  513. clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
  514. }
  515. /* execute the ramping here */
  516. for (clk_hz = pll_ramp_periph_hz + clk_incr_hz;
  517. clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
  518. writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  519. cm_calc_safe_pll_numer(1, main_cfg, per_cfg, clk_hz),
  520. &clock_manager_base->per_pll.vco1);
  521. mdelay(1);
  522. cm_wait_for_lock(LOCKED_MASK);
  523. }
  524. writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  525. per_cfg->vco1_numer, &clock_manager_base->per_pll.vco1);
  526. mdelay(1);
  527. cm_wait_for_lock(LOCKED_MASK);
  528. }
  529. /*
  530. * Setup clocks while making no assumptions of the
  531. * previous state of the clocks.
  532. *
  533. * Start by being paranoid and gate all sw managed clocks
  534. *
  535. * Put all plls in bypass
  536. *
  537. * Put all plls VCO registers back to reset value (bgpwr dwn).
  538. *
  539. * Put peripheral and main pll src to reset value to avoid glitch.
  540. *
  541. * Delay 5 us.
  542. *
  543. * Deassert bg pwr dn and set numerator and denominator
  544. *
  545. * Start 7 us timer.
  546. *
  547. * set internal dividers
  548. *
  549. * Wait for 7 us timer.
  550. *
  551. * Enable plls
  552. *
  553. * Set external dividers while plls are locking
  554. *
  555. * Wait for pll lock
  556. *
  557. * Assert/deassert outreset all.
  558. *
  559. * Take all pll's out of bypass
  560. *
  561. * Clear safe mode
  562. *
  563. * set source main and peripheral clocks
  564. *
  565. * Ungate clocks
  566. */
  567. static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
  568. {
  569. unsigned int pll_ramp_main_hz = 0, pll_ramp_periph_hz = 0,
  570. ramp_required;
  571. /* gate off all mainpll clock excpet HW managed clock */
  572. writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
  573. CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
  574. &clock_manager_base->main_pll.enr);
  575. /* now we can gate off the rest of the peripheral clocks */
  576. writel(0, &clock_manager_base->per_pll.en);
  577. /* Put all plls in external bypass */
  578. writel(CLKMGR_MAINPLL_BYPASS_RESET,
  579. &clock_manager_base->main_pll.bypasss);
  580. writel(CLKMGR_PERPLL_BYPASS_RESET,
  581. &clock_manager_base->per_pll.bypasss);
  582. /*
  583. * Put all plls VCO registers back to reset value.
  584. * Some code might have messed with them. At same time set the
  585. * desired clock source
  586. */
  587. writel(CLKMGR_MAINPLL_VCO0_RESET |
  588. CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK |
  589. (main_cfg->vco0_psrc << CLKMGR_MAINPLL_VCO0_PSRC_LSB),
  590. &clock_manager_base->main_pll.vco0);
  591. writel(CLKMGR_PERPLL_VCO0_RESET |
  592. CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK |
  593. (per_cfg->vco0_psrc << CLKMGR_PERPLL_VCO0_PSRC_LSB),
  594. &clock_manager_base->per_pll.vco0);
  595. writel(CLKMGR_MAINPLL_VCO1_RESET, &clock_manager_base->main_pll.vco1);
  596. writel(CLKMGR_PERPLL_VCO1_RESET, &clock_manager_base->per_pll.vco1);
  597. /* clear the interrupt register status register */
  598. writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
  599. CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
  600. CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
  601. CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
  602. CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
  603. CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK |
  604. CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK |
  605. CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK,
  606. &clock_manager_base->intr);
  607. /* Program VCO Numerator and Denominator for main PLL */
  608. ramp_required = cm_is_pll_ramp_required(0, main_cfg, per_cfg);
  609. if (ramp_required) {
  610. /* set main PLL to safe starting threshold frequency */
  611. if (ramp_required == 1)
  612. pll_ramp_main_hz = CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
  613. else if (ramp_required == 2)
  614. pll_ramp_main_hz = CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
  615. writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
  616. cm_calc_safe_pll_numer(0, main_cfg, per_cfg,
  617. pll_ramp_main_hz),
  618. &clock_manager_base->main_pll.vco1);
  619. } else
  620. writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
  621. main_cfg->vco1_numer,
  622. &clock_manager_base->main_pll.vco1);
  623. /* Program VCO Numerator and Denominator for periph PLL */
  624. ramp_required = cm_is_pll_ramp_required(1, main_cfg, per_cfg);
  625. if (ramp_required) {
  626. /* set periph PLL to safe starting threshold frequency */
  627. if (ramp_required == 1)
  628. pll_ramp_periph_hz =
  629. CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
  630. else if (ramp_required == 2)
  631. pll_ramp_periph_hz =
  632. CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
  633. writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  634. cm_calc_safe_pll_numer(1, main_cfg, per_cfg,
  635. pll_ramp_periph_hz),
  636. &clock_manager_base->per_pll.vco1);
  637. } else
  638. writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  639. per_cfg->vco1_numer,
  640. &clock_manager_base->per_pll.vco1);
  641. /* Wait for at least 5 us */
  642. udelay(5);
  643. /* Now deassert BGPWRDN and PWRDN */
  644. clrbits_le32(&clock_manager_base->main_pll.vco0,
  645. CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK |
  646. CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK);
  647. clrbits_le32(&clock_manager_base->per_pll.vco0,
  648. CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK |
  649. CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK);
  650. /* Wait for at least 7 us */
  651. udelay(7);
  652. /* enable the VCO and disable the external regulator to PLL */
  653. writel((readl(&clock_manager_base->main_pll.vco0) &
  654. ~CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK) |
  655. CLKMGR_MAINPLL_VCO0_EN_SET_MSK,
  656. &clock_manager_base->main_pll.vco0);
  657. writel((readl(&clock_manager_base->per_pll.vco0) &
  658. ~CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK) |
  659. CLKMGR_PERPLL_VCO0_EN_SET_MSK,
  660. &clock_manager_base->per_pll.vco0);
  661. /* setup all the main PLL counter and clock source */
  662. writel(main_cfg->nocclk,
  663. SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET);
  664. writel(main_cfg->mpuclk,
  665. SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MPU_CLK_OFFSET);
  666. /* main_emaca_clk divider */
  667. writel(main_cfg->cntr2clk_cnt, &clock_manager_base->main_pll.cntr2clk);
  668. /* main_emacb_clk divider */
  669. writel(main_cfg->cntr3clk_cnt, &clock_manager_base->main_pll.cntr3clk);
  670. /* main_emac_ptp_clk divider */
  671. writel(main_cfg->cntr4clk_cnt, &clock_manager_base->main_pll.cntr4clk);
  672. /* main_gpio_db_clk divider */
  673. writel(main_cfg->cntr5clk_cnt, &clock_manager_base->main_pll.cntr5clk);
  674. /* main_sdmmc_clk divider */
  675. writel(main_cfg->cntr6clk_cnt, &clock_manager_base->main_pll.cntr6clk);
  676. /* main_s2f_user0_clk divider */
  677. writel(main_cfg->cntr7clk_cnt |
  678. (main_cfg->cntr7clk_src << CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB),
  679. &clock_manager_base->main_pll.cntr7clk);
  680. /* main_s2f_user1_clk divider */
  681. writel(main_cfg->cntr8clk_cnt, &clock_manager_base->main_pll.cntr8clk);
  682. /* main_hmc_pll_clk divider */
  683. writel(main_cfg->cntr9clk_cnt |
  684. (main_cfg->cntr9clk_src << CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB),
  685. &clock_manager_base->main_pll.cntr9clk);
  686. /* main_periph_ref_clk divider */
  687. writel(main_cfg->cntr15clk_cnt,
  688. &clock_manager_base->main_pll.cntr15clk);
  689. /* setup all the peripheral PLL counter and clock source */
  690. /* peri_emaca_clk divider */
  691. writel(per_cfg->cntr2clk_cnt |
  692. (per_cfg->cntr2clk_src << CLKMGR_PERPLL_CNTR2CLK_SRC_LSB),
  693. &clock_manager_base->per_pll.cntr2clk);
  694. /* peri_emacb_clk divider */
  695. writel(per_cfg->cntr3clk_cnt |
  696. (per_cfg->cntr3clk_src << CLKMGR_PERPLL_CNTR3CLK_SRC_LSB),
  697. &clock_manager_base->per_pll.cntr3clk);
  698. /* peri_emac_ptp_clk divider */
  699. writel(per_cfg->cntr4clk_cnt |
  700. (per_cfg->cntr4clk_src << CLKMGR_PERPLL_CNTR4CLK_SRC_LSB),
  701. &clock_manager_base->per_pll.cntr4clk);
  702. /* peri_gpio_db_clk divider */
  703. writel(per_cfg->cntr5clk_cnt |
  704. (per_cfg->cntr5clk_src << CLKMGR_PERPLL_CNTR5CLK_SRC_LSB),
  705. &clock_manager_base->per_pll.cntr5clk);
  706. /* peri_sdmmc_clk divider */
  707. writel(per_cfg->cntr6clk_cnt |
  708. (per_cfg->cntr6clk_src << CLKMGR_PERPLL_CNTR6CLK_SRC_LSB),
  709. &clock_manager_base->per_pll.cntr6clk);
  710. /* peri_s2f_user0_clk divider */
  711. writel(per_cfg->cntr7clk_cnt, &clock_manager_base->per_pll.cntr7clk);
  712. /* peri_s2f_user1_clk divider */
  713. writel(per_cfg->cntr8clk_cnt |
  714. (per_cfg->cntr8clk_src << CLKMGR_PERPLL_CNTR8CLK_SRC_LSB),
  715. &clock_manager_base->per_pll.cntr8clk);
  716. /* peri_hmc_pll_clk divider */
  717. writel(per_cfg->cntr9clk_cnt, &clock_manager_base->per_pll.cntr9clk);
  718. /* setup all the external PLL counter */
  719. /* mpu wrapper / external divider */
  720. writel(main_cfg->mpuclk_cnt |
  721. (main_cfg->mpuclk_src << CLKMGR_MAINPLL_MPUCLK_SRC_LSB),
  722. &clock_manager_base->main_pll.mpuclk);
  723. /* NOC wrapper / external divider */
  724. writel(main_cfg->nocclk_cnt |
  725. (main_cfg->nocclk_src << CLKMGR_MAINPLL_NOCCLK_SRC_LSB),
  726. &clock_manager_base->main_pll.nocclk);
  727. /* NOC subclock divider such as l4 */
  728. writel(main_cfg->nocdiv_l4mainclk |
  729. (main_cfg->nocdiv_l4mpclk <<
  730. CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) |
  731. (main_cfg->nocdiv_l4spclk <<
  732. CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB) |
  733. (main_cfg->nocdiv_csatclk <<
  734. CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB) |
  735. (main_cfg->nocdiv_cstraceclk <<
  736. CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB) |
  737. (main_cfg->nocdiv_cspdbclk <<
  738. CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB),
  739. &clock_manager_base->main_pll.nocdiv);
  740. /* gpio_db external divider */
  741. writel(per_cfg->gpiodiv_gpiodbclk,
  742. &clock_manager_base->per_pll.gpiodiv);
  743. /* setup the EMAC clock mux select */
  744. writel((per_cfg->emacctl_emac0sel <<
  745. CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB) |
  746. (per_cfg->emacctl_emac1sel <<
  747. CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB) |
  748. (per_cfg->emacctl_emac2sel <<
  749. CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB),
  750. &clock_manager_base->per_pll.emacctl);
  751. /* at this stage, check for PLL lock status */
  752. cm_wait_for_lock(LOCKED_MASK);
  753. /*
  754. * after locking, but before taking out of bypass,
  755. * assert/deassert outresetall
  756. */
  757. /* assert mainpll outresetall */
  758. setbits_le32(&clock_manager_base->main_pll.vco0,
  759. CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
  760. /* assert perpll outresetall */
  761. setbits_le32(&clock_manager_base->per_pll.vco0,
  762. CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
  763. /* de-assert mainpll outresetall */
  764. clrbits_le32(&clock_manager_base->main_pll.vco0,
  765. CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
  766. /* de-assert perpll outresetall */
  767. clrbits_le32(&clock_manager_base->per_pll.vco0,
  768. CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
  769. /* Take all PLLs out of bypass when boot mode is cleared. */
  770. /* release mainpll from bypass */
  771. writel(CLKMGR_MAINPLL_BYPASS_RESET,
  772. &clock_manager_base->main_pll.bypassr);
  773. /* wait till Clock Manager is not busy */
  774. cm_wait_for_fsm();
  775. /* release perpll from bypass */
  776. writel(CLKMGR_PERPLL_BYPASS_RESET,
  777. &clock_manager_base->per_pll.bypassr);
  778. /* wait till Clock Manager is not busy */
  779. cm_wait_for_fsm();
  780. /* clear boot mode */
  781. clrbits_le32(&clock_manager_base->ctrl,
  782. CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK);
  783. /* wait till Clock Manager is not busy */
  784. cm_wait_for_fsm();
  785. /* At here, we need to ramp to final value if needed */
  786. if (pll_ramp_main_hz != 0)
  787. cm_pll_ramp_main(main_cfg, per_cfg, pll_ramp_main_hz);
  788. if (pll_ramp_periph_hz != 0)
  789. cm_pll_ramp_periph(main_cfg, per_cfg, pll_ramp_periph_hz);
  790. /* Now ungate non-hw-managed clocks */
  791. writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
  792. CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
  793. &clock_manager_base->main_pll.ens);
  794. writel(CLKMGR_PERPLL_EN_RESET, &clock_manager_base->per_pll.ens);
  795. /* Clear the loss lock and slip bits as they might set during
  796. clock reconfiguration */
  797. writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
  798. CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
  799. CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
  800. CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
  801. CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
  802. CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK,
  803. &clock_manager_base->intr);
  804. return 0;
  805. }
  806. static void cm_use_intosc(void)
  807. {
  808. setbits_le32(&clock_manager_base->ctrl,
  809. CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK);
  810. }
  811. int cm_basic_init(const void *blob)
  812. {
  813. struct mainpll_cfg main_cfg;
  814. struct perpll_cfg per_cfg;
  815. int rval;
  816. /* initialize to zero for use case of optional node */
  817. memset(&main_cfg, 0, sizeof(main_cfg));
  818. memset(&per_cfg, 0, sizeof(per_cfg));
  819. rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg);
  820. if (rval)
  821. return rval;
  822. cm_use_intosc();
  823. return cm_full_cfg(&main_cfg, &per_cfg);
  824. }
  825. #endif
  826. static u32 cm_get_rate_dm(char *name)
  827. {
  828. struct uclass *uc;
  829. struct udevice *dev = NULL;
  830. struct clk clk = { 0 };
  831. ulong rate;
  832. int ret;
  833. /* Device addresses start at 1 */
  834. ret = uclass_get(UCLASS_CLK, &uc);
  835. if (ret)
  836. return 0;
  837. ret = uclass_get_device_by_name(UCLASS_CLK, name, &dev);
  838. if (ret)
  839. return 0;
  840. ret = device_probe(dev);
  841. if (ret)
  842. return 0;
  843. ret = clk_request(dev, &clk);
  844. if (ret)
  845. return 0;
  846. rate = clk_get_rate(&clk);
  847. clk_free(&clk);
  848. return rate;
  849. }
  850. static u32 cm_get_rate_dm_khz(char *name)
  851. {
  852. return cm_get_rate_dm(name) / 1000;
  853. }
  854. unsigned long cm_get_mpu_clk_hz(void)
  855. {
  856. return cm_get_rate_dm("main_mpu_base_clk");
  857. }
  858. unsigned int cm_get_qspi_controller_clk_hz(void)
  859. {
  860. return cm_get_rate_dm("qspi_clk");
  861. }
  862. unsigned int cm_get_l4_sp_clk_hz(void)
  863. {
  864. return cm_get_rate_dm("l4_sp_clk");
  865. }
  866. void cm_print_clock_quick_summary(void)
  867. {
  868. printf("MPU %10d kHz\n", cm_get_rate_dm_khz("main_mpu_base_clk"));
  869. printf("MMC %8d kHz\n", cm_get_rate_dm_khz("sdmmc_clk"));
  870. printf("QSPI %8d kHz\n", cm_get_rate_dm_khz("qspi_clk"));
  871. printf("SPI %8d kHz\n", cm_get_rate_dm_khz("spi_m_clk"));
  872. printf("EOSC1 %8d kHz\n", cm_get_rate_dm_khz("osc1"));
  873. printf("cb_intosc %8d kHz\n", cm_get_rate_dm_khz("cb_intosc_ls_clk"));
  874. printf("f2s_free %8d kHz\n", cm_get_rate_dm_khz("f2s_free_clk"));
  875. printf("Main VCO %8d kHz\n", cm_get_rate_dm_khz("main_pll@40"));
  876. printf("NOC %8d kHz\n", cm_get_rate_dm_khz("main_noc_base_clk"));
  877. printf("L4 Main %8d kHz\n", cm_get_rate_dm_khz("l4_main_clk"));
  878. printf("L4 MP %8d kHz\n", cm_get_rate_dm_khz("l4_mp_clk"));
  879. printf("L4 SP %8d kHz\n", cm_get_rate_dm_khz("l4_sp_clk"));
  880. printf("L4 sys free %8d kHz\n", cm_get_rate_dm_khz("l4_sys_free_clk"));
  881. }