clock_manager_arria10.c 35 KB

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