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