clock_manager_arria10.c 30 KB

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