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