clock_manager_arria10.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  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 <malloc.h>
  8. #include <asm/io.h>
  9. #include <dm.h>
  10. #include <clk.h>
  11. #include <dm/device-internal.h>
  12. #include <asm/arch/clock_manager.h>
  13. #include <linux/delay.h>
  14. #ifdef CONFIG_SPL_BUILD
  15. static u32 eosc1_hz;
  16. static u32 cb_intosc_hz;
  17. static u32 f2s_free_hz;
  18. struct mainpll_cfg {
  19. u32 vco0_psrc;
  20. u32 vco1_denom;
  21. u32 vco1_numer;
  22. u32 mpuclk;
  23. u32 mpuclk_cnt;
  24. u32 mpuclk_src;
  25. u32 nocclk;
  26. u32 nocclk_cnt;
  27. u32 nocclk_src;
  28. u32 cntr2clk_cnt;
  29. u32 cntr3clk_cnt;
  30. u32 cntr4clk_cnt;
  31. u32 cntr5clk_cnt;
  32. u32 cntr6clk_cnt;
  33. u32 cntr7clk_cnt;
  34. u32 cntr7clk_src;
  35. u32 cntr8clk_cnt;
  36. u32 cntr9clk_cnt;
  37. u32 cntr9clk_src;
  38. u32 cntr15clk_cnt;
  39. u32 nocdiv_l4mainclk;
  40. u32 nocdiv_l4mpclk;
  41. u32 nocdiv_l4spclk;
  42. u32 nocdiv_csatclk;
  43. u32 nocdiv_cstraceclk;
  44. u32 nocdiv_cspdbclk;
  45. };
  46. struct perpll_cfg {
  47. u32 vco0_psrc;
  48. u32 vco1_denom;
  49. u32 vco1_numer;
  50. u32 cntr2clk_cnt;
  51. u32 cntr2clk_src;
  52. u32 cntr3clk_cnt;
  53. u32 cntr3clk_src;
  54. u32 cntr4clk_cnt;
  55. u32 cntr4clk_src;
  56. u32 cntr5clk_cnt;
  57. u32 cntr5clk_src;
  58. u32 cntr6clk_cnt;
  59. u32 cntr6clk_src;
  60. u32 cntr7clk_cnt;
  61. u32 cntr8clk_cnt;
  62. u32 cntr8clk_src;
  63. u32 cntr9clk_cnt;
  64. u32 cntr9clk_src;
  65. u32 emacctl_emac0sel;
  66. u32 emacctl_emac1sel;
  67. u32 emacctl_emac2sel;
  68. u32 gpiodiv_gpiodbclk;
  69. };
  70. struct strtou32 {
  71. const char *str;
  72. const u32 val;
  73. };
  74. static const struct strtou32 mainpll_cfg_tab[] = {
  75. { "vco0-psrc", offsetof(struct mainpll_cfg, vco0_psrc) },
  76. { "vco1-denom", offsetof(struct mainpll_cfg, vco1_denom) },
  77. { "vco1-numer", offsetof(struct mainpll_cfg, vco1_numer) },
  78. { "mpuclk-cnt", offsetof(struct mainpll_cfg, mpuclk_cnt) },
  79. { "mpuclk-src", offsetof(struct mainpll_cfg, mpuclk_src) },
  80. { "nocclk-cnt", offsetof(struct mainpll_cfg, nocclk_cnt) },
  81. { "nocclk-src", offsetof(struct mainpll_cfg, nocclk_src) },
  82. { "cntr2clk-cnt", offsetof(struct mainpll_cfg, cntr2clk_cnt) },
  83. { "cntr3clk-cnt", offsetof(struct mainpll_cfg, cntr3clk_cnt) },
  84. { "cntr4clk-cnt", offsetof(struct mainpll_cfg, cntr4clk_cnt) },
  85. { "cntr5clk-cnt", offsetof(struct mainpll_cfg, cntr5clk_cnt) },
  86. { "cntr6clk-cnt", offsetof(struct mainpll_cfg, cntr6clk_cnt) },
  87. { "cntr7clk-cnt", offsetof(struct mainpll_cfg, cntr7clk_cnt) },
  88. { "cntr7clk-src", offsetof(struct mainpll_cfg, cntr7clk_src) },
  89. { "cntr8clk-cnt", offsetof(struct mainpll_cfg, cntr8clk_cnt) },
  90. { "cntr9clk-cnt", offsetof(struct mainpll_cfg, cntr9clk_cnt) },
  91. { "cntr9clk-src", offsetof(struct mainpll_cfg, cntr9clk_src) },
  92. { "cntr15clk-cnt", offsetof(struct mainpll_cfg, cntr15clk_cnt) },
  93. { "nocdiv-l4mainclk", offsetof(struct mainpll_cfg, nocdiv_l4mainclk) },
  94. { "nocdiv-l4mpclk", offsetof(struct mainpll_cfg, nocdiv_l4mpclk) },
  95. { "nocdiv-l4spclk", offsetof(struct mainpll_cfg, nocdiv_l4spclk) },
  96. { "nocdiv-csatclk", offsetof(struct mainpll_cfg, nocdiv_csatclk) },
  97. { "nocdiv-cstraceclk", offsetof(struct mainpll_cfg, nocdiv_cstraceclk) },
  98. { "nocdiv-cspdbgclk", offsetof(struct mainpll_cfg, nocdiv_cspdbclk) },
  99. };
  100. static const struct strtou32 perpll_cfg_tab[] = {
  101. { "vco0-psrc", offsetof(struct perpll_cfg, vco0_psrc) },
  102. { "vco1-denom", offsetof(struct perpll_cfg, vco1_denom) },
  103. { "vco1-numer", offsetof(struct perpll_cfg, vco1_numer) },
  104. { "cntr2clk-cnt", offsetof(struct perpll_cfg, cntr2clk_cnt) },
  105. { "cntr2clk-src", offsetof(struct perpll_cfg, cntr2clk_src) },
  106. { "cntr3clk-cnt", offsetof(struct perpll_cfg, cntr3clk_cnt) },
  107. { "cntr3clk-src", offsetof(struct perpll_cfg, cntr3clk_src) },
  108. { "cntr4clk-cnt", offsetof(struct perpll_cfg, cntr4clk_cnt) },
  109. { "cntr4clk-src", offsetof(struct perpll_cfg, cntr4clk_src) },
  110. { "cntr5clk-cnt", offsetof(struct perpll_cfg, cntr5clk_cnt) },
  111. { "cntr5clk-src", offsetof(struct perpll_cfg, cntr5clk_src) },
  112. { "cntr6clk-cnt", offsetof(struct perpll_cfg, cntr6clk_cnt) },
  113. { "cntr6clk-src", offsetof(struct perpll_cfg, cntr6clk_src) },
  114. { "cntr7clk-cnt", offsetof(struct perpll_cfg, cntr7clk_cnt) },
  115. { "cntr8clk-cnt", offsetof(struct perpll_cfg, cntr8clk_cnt) },
  116. { "cntr8clk-src", offsetof(struct perpll_cfg, cntr8clk_src) },
  117. { "cntr9clk-cnt", offsetof(struct perpll_cfg, cntr9clk_cnt) },
  118. { "emacctl-emac0sel", offsetof(struct perpll_cfg, emacctl_emac0sel) },
  119. { "emacctl-emac1sel", offsetof(struct perpll_cfg, emacctl_emac1sel) },
  120. { "emacctl-emac2sel", offsetof(struct perpll_cfg, emacctl_emac2sel) },
  121. { "gpiodiv-gpiodbclk", offsetof(struct perpll_cfg, gpiodiv_gpiodbclk) },
  122. };
  123. static const struct strtou32 alteragrp_cfg_tab[] = {
  124. { "nocclk", offsetof(struct mainpll_cfg, nocclk) },
  125. { "mpuclk", offsetof(struct mainpll_cfg, mpuclk) },
  126. };
  127. struct strtopu32 {
  128. const char *str;
  129. u32 *p;
  130. };
  131. const struct strtopu32 dt_to_val[] = {
  132. { "altera_arria10_hps_eosc1", &eosc1_hz },
  133. { "altera_arria10_hps_cb_intosc_ls", &cb_intosc_hz },
  134. { "altera_arria10_hps_f2h_free", &f2s_free_hz },
  135. };
  136. static int of_to_struct(const void *blob, int node, const struct strtou32 *cfg_tab,
  137. int cfg_tab_len, void *cfg)
  138. {
  139. int i;
  140. u32 val;
  141. for (i = 0; i < cfg_tab_len; i++) {
  142. if (fdtdec_get_int_array(blob, node, cfg_tab[i].str, &val, 1)) {
  143. /* could not find required property */
  144. return -EINVAL;
  145. }
  146. *(u32 *)(cfg + cfg_tab[i].val) = val;
  147. }
  148. return 0;
  149. }
  150. static int of_get_input_clks(const void *blob)
  151. {
  152. struct udevice *dev;
  153. struct clk clk;
  154. int i, ret;
  155. for (i = 0; i < ARRAY_SIZE(dt_to_val); i++) {
  156. memset(&clk, 0, sizeof(clk));
  157. ret = uclass_get_device_by_name(UCLASS_CLK, dt_to_val[i].str,
  158. &dev);
  159. if (ret)
  160. return ret;
  161. ret = clk_request(dev, &clk);
  162. if (ret)
  163. return ret;
  164. *dt_to_val[i].p = clk_get_rate(&clk);
  165. }
  166. return 0;
  167. }
  168. static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg,
  169. struct perpll_cfg *per_cfg)
  170. {
  171. int ret, node, child, len;
  172. const char *node_name;
  173. ret = of_get_input_clks(blob);
  174. if (ret)
  175. return ret;
  176. node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK_INIT);
  177. if (node < 0)
  178. return -EINVAL;
  179. child = fdt_first_subnode(blob, node);
  180. if (child < 0)
  181. return -EINVAL;
  182. node_name = fdt_get_name(blob, child, &len);
  183. while (node_name) {
  184. if (!strcmp(node_name, "mainpll")) {
  185. if (of_to_struct(blob, child, mainpll_cfg_tab,
  186. ARRAY_SIZE(mainpll_cfg_tab), main_cfg))
  187. return -EINVAL;
  188. } else if (!strcmp(node_name, "perpll")) {
  189. if (of_to_struct(blob, child, perpll_cfg_tab,
  190. ARRAY_SIZE(perpll_cfg_tab), per_cfg))
  191. return -EINVAL;
  192. } else if (!strcmp(node_name, "alteragrp")) {
  193. if (of_to_struct(blob, child, alteragrp_cfg_tab,
  194. ARRAY_SIZE(alteragrp_cfg_tab), main_cfg))
  195. return -EINVAL;
  196. }
  197. child = fdt_next_subnode(blob, child);
  198. if (child < 0)
  199. break;
  200. node_name = fdt_get_name(blob, child, &len);
  201. }
  202. return 0;
  203. }
  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. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_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,
  498. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
  499. mdelay(1);
  500. cm_wait_for_lock(LOCKED_MASK);
  501. }
  502. /* ramping the periph PLL to final value */
  503. static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg,
  504. struct perpll_cfg *per_cfg,
  505. unsigned int pll_ramp_periph_hz)
  506. {
  507. unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0;
  508. /* find out the increment value */
  509. if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) {
  510. clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ;
  511. clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg);
  512. } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) {
  513. clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ;
  514. clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg);
  515. }
  516. /* execute the ramping here */
  517. for (clk_hz = pll_ramp_periph_hz + clk_incr_hz;
  518. clk_hz < clk_final_hz; clk_hz += clk_incr_hz) {
  519. writel((per_cfg->vco1_denom <<
  520. CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  521. cm_calc_safe_pll_numer(1, main_cfg, per_cfg,
  522. clk_hz),
  523. socfpga_get_clkmgr_addr() +
  524. CLKMGR_A10_PERPLL_VCO1);
  525. mdelay(1);
  526. cm_wait_for_lock(LOCKED_MASK);
  527. }
  528. writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  529. per_cfg->vco1_numer,
  530. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
  531. mdelay(1);
  532. cm_wait_for_lock(LOCKED_MASK);
  533. }
  534. /*
  535. * Setup clocks while making no assumptions of the
  536. * previous state of the clocks.
  537. *
  538. * Start by being paranoid and gate all sw managed clocks
  539. *
  540. * Put all plls in bypass
  541. *
  542. * Put all plls VCO registers back to reset value (bgpwr dwn).
  543. *
  544. * Put peripheral and main pll src to reset value to avoid glitch.
  545. *
  546. * Delay 5 us.
  547. *
  548. * Deassert bg pwr dn and set numerator and denominator
  549. *
  550. * Start 7 us timer.
  551. *
  552. * set internal dividers
  553. *
  554. * Wait for 7 us timer.
  555. *
  556. * Enable plls
  557. *
  558. * Set external dividers while plls are locking
  559. *
  560. * Wait for pll lock
  561. *
  562. * Assert/deassert outreset all.
  563. *
  564. * Take all pll's out of bypass
  565. *
  566. * Clear safe mode
  567. *
  568. * set source main and peripheral clocks
  569. *
  570. * Ungate clocks
  571. */
  572. static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
  573. {
  574. unsigned int pll_ramp_main_hz = 0, pll_ramp_periph_hz = 0,
  575. ramp_required;
  576. /* gate off all mainpll clock excpet HW managed clock */
  577. writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
  578. CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
  579. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_ENR);
  580. /* now we can gate off the rest of the peripheral clocks */
  581. writel(0, socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_EN);
  582. /* Put all plls in external bypass */
  583. writel(CLKMGR_MAINPLL_BYPASS_RESET,
  584. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_BYPASSS);
  585. writel(CLKMGR_PERPLL_BYPASS_RESET,
  586. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_BYPASSS);
  587. /*
  588. * Put all plls VCO registers back to reset value.
  589. * Some code might have messed with them. At same time set the
  590. * desired clock source
  591. */
  592. writel(CLKMGR_MAINPLL_VCO0_RESET |
  593. CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK |
  594. (main_cfg->vco0_psrc << CLKMGR_MAINPLL_VCO0_PSRC_LSB),
  595. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0);
  596. writel(CLKMGR_PERPLL_VCO0_RESET |
  597. CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK |
  598. (per_cfg->vco0_psrc << CLKMGR_PERPLL_VCO0_PSRC_LSB),
  599. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO0);
  600. writel(CLKMGR_MAINPLL_VCO1_RESET,
  601. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
  602. writel(CLKMGR_PERPLL_VCO1_RESET,
  603. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
  604. /* clear the interrupt register status register */
  605. writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
  606. CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
  607. CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
  608. CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
  609. CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
  610. CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK |
  611. CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK |
  612. CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK,
  613. socfpga_get_clkmgr_addr() + CLKMGR_A10_INTR);
  614. /* Program VCO Numerator and Denominator for main PLL */
  615. ramp_required = cm_is_pll_ramp_required(0, main_cfg, per_cfg);
  616. if (ramp_required) {
  617. /* set main PLL to safe starting threshold frequency */
  618. if (ramp_required == 1)
  619. pll_ramp_main_hz = CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
  620. else if (ramp_required == 2)
  621. pll_ramp_main_hz = CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
  622. writel((main_cfg->vco1_denom <<
  623. CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
  624. cm_calc_safe_pll_numer(0, main_cfg, per_cfg,
  625. pll_ramp_main_hz),
  626. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
  627. } else
  628. writel((main_cfg->vco1_denom <<
  629. CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
  630. main_cfg->vco1_numer,
  631. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
  632. /* Program VCO Numerator and Denominator for periph PLL */
  633. ramp_required = cm_is_pll_ramp_required(1, main_cfg, per_cfg);
  634. if (ramp_required) {
  635. /* set periph PLL to safe starting threshold frequency */
  636. if (ramp_required == 1)
  637. pll_ramp_periph_hz =
  638. CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ;
  639. else if (ramp_required == 2)
  640. pll_ramp_periph_hz =
  641. CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ;
  642. writel((per_cfg->vco1_denom <<
  643. CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  644. cm_calc_safe_pll_numer(1, main_cfg, per_cfg,
  645. pll_ramp_periph_hz),
  646. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
  647. } else
  648. writel((per_cfg->vco1_denom <<
  649. CLKMGR_PERPLL_VCO1_DENOM_LSB) |
  650. per_cfg->vco1_numer,
  651. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
  652. /* Wait for at least 5 us */
  653. udelay(5);
  654. /* Now deassert BGPWRDN and PWRDN */
  655. clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0,
  656. CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK |
  657. CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK);
  658. clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO0,
  659. CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK |
  660. CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK);
  661. /* Wait for at least 7 us */
  662. udelay(7);
  663. /* enable the VCO and disable the external regulator to PLL */
  664. writel((readl(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0) &
  665. ~CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK) |
  666. CLKMGR_MAINPLL_VCO0_EN_SET_MSK,
  667. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0);
  668. writel((readl(socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO0) &
  669. ~CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK) |
  670. CLKMGR_PERPLL_VCO0_EN_SET_MSK,
  671. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO0);
  672. /* setup all the main PLL counter and clock source */
  673. writel(main_cfg->nocclk,
  674. socfpga_get_clkmgr_addr() + CLKMGR_A10_ALTR_NOCCLK);
  675. writel(main_cfg->mpuclk,
  676. socfpga_get_clkmgr_addr() + CLKMGR_A10_ALTR_MPUCLK);
  677. /* main_emaca_clk divider */
  678. writel(main_cfg->cntr2clk_cnt,
  679. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR2CLK);
  680. /* main_emacb_clk divider */
  681. writel(main_cfg->cntr3clk_cnt,
  682. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR3CLK);
  683. /* main_emac_ptp_clk divider */
  684. writel(main_cfg->cntr4clk_cnt,
  685. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR4CLK);
  686. /* main_gpio_db_clk divider */
  687. writel(main_cfg->cntr5clk_cnt,
  688. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR5CLK);
  689. /* main_sdmmc_clk divider */
  690. writel(main_cfg->cntr6clk_cnt,
  691. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR6CLK);
  692. /* main_s2f_user0_clk divider */
  693. writel(main_cfg->cntr7clk_cnt |
  694. (main_cfg->cntr7clk_src << CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB),
  695. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR7CLK);
  696. /* main_s2f_user1_clk divider */
  697. writel(main_cfg->cntr8clk_cnt,
  698. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR8CLK);
  699. /* main_hmc_pll_clk divider */
  700. writel(main_cfg->cntr9clk_cnt |
  701. (main_cfg->cntr9clk_src << CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB),
  702. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR9CLK);
  703. /* main_periph_ref_clk divider */
  704. writel(main_cfg->cntr15clk_cnt,
  705. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_CNTR15CLK);
  706. /* setup all the peripheral PLL counter and clock source */
  707. /* peri_emaca_clk divider */
  708. writel(per_cfg->cntr2clk_cnt |
  709. (per_cfg->cntr2clk_src << CLKMGR_PERPLL_CNTR2CLK_SRC_LSB),
  710. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR2CLK);
  711. /* peri_emacb_clk divider */
  712. writel(per_cfg->cntr3clk_cnt |
  713. (per_cfg->cntr3clk_src << CLKMGR_PERPLL_CNTR3CLK_SRC_LSB),
  714. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR3CLK);
  715. /* peri_emac_ptp_clk divider */
  716. writel(per_cfg->cntr4clk_cnt |
  717. (per_cfg->cntr4clk_src << CLKMGR_PERPLL_CNTR4CLK_SRC_LSB),
  718. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR4CLK);
  719. /* peri_gpio_db_clk divider */
  720. writel(per_cfg->cntr5clk_cnt |
  721. (per_cfg->cntr5clk_src << CLKMGR_PERPLL_CNTR5CLK_SRC_LSB),
  722. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR5CLK);
  723. /* peri_sdmmc_clk divider */
  724. writel(per_cfg->cntr6clk_cnt |
  725. (per_cfg->cntr6clk_src << CLKMGR_PERPLL_CNTR6CLK_SRC_LSB),
  726. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR6CLK);
  727. /* peri_s2f_user0_clk divider */
  728. writel(per_cfg->cntr7clk_cnt,
  729. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR7CLK);
  730. /* peri_s2f_user1_clk divider */
  731. writel(per_cfg->cntr8clk_cnt |
  732. (per_cfg->cntr8clk_src << CLKMGR_PERPLL_CNTR8CLK_SRC_LSB),
  733. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR8CLK);
  734. /* peri_hmc_pll_clk divider */
  735. writel(per_cfg->cntr9clk_cnt,
  736. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_CNTR9CLK);
  737. /* setup all the external PLL counter */
  738. /* mpu wrapper / external divider */
  739. writel(main_cfg->mpuclk_cnt |
  740. (main_cfg->mpuclk_src << CLKMGR_MAINPLL_MPUCLK_SRC_LSB),
  741. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_MPUCLK);
  742. /* NOC wrapper / external divider */
  743. writel(main_cfg->nocclk_cnt |
  744. (main_cfg->nocclk_src << CLKMGR_MAINPLL_NOCCLK_SRC_LSB),
  745. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_NOCCLK);
  746. /* NOC subclock divider such as l4 */
  747. writel(main_cfg->nocdiv_l4mainclk |
  748. (main_cfg->nocdiv_l4mpclk <<
  749. CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) |
  750. (main_cfg->nocdiv_l4spclk <<
  751. CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB) |
  752. (main_cfg->nocdiv_csatclk <<
  753. CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB) |
  754. (main_cfg->nocdiv_cstraceclk <<
  755. CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB) |
  756. (main_cfg->nocdiv_cspdbclk <<
  757. CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB),
  758. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_NOCDIV);
  759. /* gpio_db external divider */
  760. writel(per_cfg->gpiodiv_gpiodbclk,
  761. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_GPIOFIV);
  762. /* setup the EMAC clock mux select */
  763. writel((per_cfg->emacctl_emac0sel <<
  764. CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB) |
  765. (per_cfg->emacctl_emac1sel <<
  766. CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB) |
  767. (per_cfg->emacctl_emac2sel <<
  768. CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB),
  769. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_EMACCTL);
  770. /* at this stage, check for PLL lock status */
  771. cm_wait_for_lock(LOCKED_MASK);
  772. /*
  773. * after locking, but before taking out of bypass,
  774. * assert/deassert outresetall
  775. */
  776. /* assert mainpll outresetall */
  777. setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0,
  778. CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
  779. /* assert perpll outresetall */
  780. setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO0,
  781. CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
  782. /* de-assert mainpll outresetall */
  783. clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0,
  784. CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK);
  785. /* de-assert perpll outresetall */
  786. clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO0,
  787. CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK);
  788. /* Take all PLLs out of bypass when boot mode is cleared. */
  789. /* release mainpll from bypass */
  790. writel(CLKMGR_MAINPLL_BYPASS_RESET,
  791. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_BYPASSR);
  792. /* wait till Clock Manager is not busy */
  793. cm_wait_for_fsm();
  794. /* release perpll from bypass */
  795. writel(CLKMGR_PERPLL_BYPASS_RESET,
  796. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_BYPASSR);
  797. /* wait till Clock Manager is not busy */
  798. cm_wait_for_fsm();
  799. /* clear boot mode */
  800. clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_CTRL,
  801. CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK);
  802. /* wait till Clock Manager is not busy */
  803. cm_wait_for_fsm();
  804. /* At here, we need to ramp to final value if needed */
  805. if (pll_ramp_main_hz != 0)
  806. cm_pll_ramp_main(main_cfg, per_cfg, pll_ramp_main_hz);
  807. if (pll_ramp_periph_hz != 0)
  808. cm_pll_ramp_periph(main_cfg, per_cfg, pll_ramp_periph_hz);
  809. /* Now ungate non-hw-managed clocks */
  810. writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK |
  811. CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK,
  812. socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_ENS);
  813. writel(CLKMGR_PERPLL_EN_RESET,
  814. socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_ENS);
  815. /* Clear the loss lock and slip bits as they might set during
  816. clock reconfiguration */
  817. writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK |
  818. CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK |
  819. CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK |
  820. CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK |
  821. CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK |
  822. CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK,
  823. socfpga_get_clkmgr_addr() + CLKMGR_A10_INTR);
  824. return 0;
  825. }
  826. static void cm_use_intosc(void)
  827. {
  828. setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_CTRL,
  829. CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK);
  830. }
  831. int cm_basic_init(const void *blob)
  832. {
  833. struct mainpll_cfg main_cfg;
  834. struct perpll_cfg per_cfg;
  835. int rval;
  836. /* initialize to zero for use case of optional node */
  837. memset(&main_cfg, 0, sizeof(main_cfg));
  838. memset(&per_cfg, 0, sizeof(per_cfg));
  839. rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg);
  840. if (rval)
  841. return rval;
  842. cm_use_intosc();
  843. return cm_full_cfg(&main_cfg, &per_cfg);
  844. }
  845. #endif
  846. static u32 cm_get_rate_dm(char *name)
  847. {
  848. struct uclass *uc;
  849. struct udevice *dev = NULL;
  850. struct clk clk = { 0 };
  851. ulong rate;
  852. int ret;
  853. /* Device addresses start at 1 */
  854. ret = uclass_get(UCLASS_CLK, &uc);
  855. if (ret)
  856. return 0;
  857. ret = uclass_get_device_by_name(UCLASS_CLK, name, &dev);
  858. if (ret)
  859. return 0;
  860. ret = device_probe(dev);
  861. if (ret)
  862. return 0;
  863. ret = clk_request(dev, &clk);
  864. if (ret)
  865. return 0;
  866. rate = clk_get_rate(&clk);
  867. clk_free(&clk);
  868. return rate;
  869. }
  870. static u32 cm_get_rate_dm_khz(char *name)
  871. {
  872. return cm_get_rate_dm(name) / 1000;
  873. }
  874. unsigned long cm_get_mpu_clk_hz(void)
  875. {
  876. return cm_get_rate_dm("main_mpu_base_clk");
  877. }
  878. unsigned int cm_get_qspi_controller_clk_hz(void)
  879. {
  880. return cm_get_rate_dm("qspi_clk");
  881. }
  882. unsigned int cm_get_l4_sp_clk_hz(void)
  883. {
  884. return cm_get_rate_dm("l4_sp_clk");
  885. }
  886. void cm_print_clock_quick_summary(void)
  887. {
  888. printf("MPU %10d kHz\n", cm_get_rate_dm_khz("main_mpu_base_clk"));
  889. printf("MMC %8d kHz\n", cm_get_rate_dm_khz("sdmmc_clk"));
  890. printf("QSPI %8d kHz\n", cm_get_rate_dm_khz("qspi_clk"));
  891. printf("SPI %8d kHz\n", cm_get_rate_dm_khz("spi_m_clk"));
  892. printf("EOSC1 %8d kHz\n", cm_get_rate_dm_khz("osc1"));
  893. printf("cb_intosc %8d kHz\n", cm_get_rate_dm_khz("cb_intosc_ls_clk"));
  894. printf("f2s_free %8d kHz\n", cm_get_rate_dm_khz("f2s_free_clk"));
  895. printf("Main VCO %8d kHz\n", cm_get_rate_dm_khz("main_pll@40"));
  896. printf("NOC %8d kHz\n", cm_get_rate_dm_khz("main_noc_base_clk"));
  897. printf("L4 Main %8d kHz\n", cm_get_rate_dm_khz("l4_main_clk"));
  898. printf("L4 MP %8d kHz\n", cm_get_rate_dm_khz("l4_mp_clk"));
  899. printf("L4 SP %8d kHz\n", cm_get_rate_dm_khz("l4_sp_clk"));
  900. printf("L4 sys free %8d kHz\n", cm_get_rate_dm_khz("l4_sys_free_clk"));
  901. }