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