uboot/arch/arm/mach-imx/imx8m/clock_imx8mm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2018-2019 NXP
   4 *
   5 * Peng Fan <peng.fan@nxp.com>
   6 */
   7
   8#include <common.h>
   9#include <asm/arch/clock.h>
  10#include <asm/arch/imx-regs.h>
  11#include <asm/arch/sys_proto.h>
  12#include <asm/io.h>
  13#include <div64.h>
  14#include <errno.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
  19
  20void enable_ocotp_clk(unsigned char enable)
  21{
  22        clock_enable(CCGR_OCOTP, !!enable);
  23}
  24
  25int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
  26{
  27        /* 0 - 3 is valid i2c num */
  28        if (i2c_num > 3)
  29                return -EINVAL;
  30
  31        clock_enable(CCGR_I2C1 + i2c_num, !!enable);
  32
  33        return 0;
  34}
  35
  36#ifdef CONFIG_SPL_BUILD
  37static struct imx_int_pll_rate_table imx8mm_fracpll_tbl[] = {
  38        PLL_1443X_RATE(1000000000U, 250, 3, 1, 0),
  39        PLL_1443X_RATE(800000000U, 300, 9, 0, 0),
  40        PLL_1443X_RATE(750000000U, 250, 8, 0, 0),
  41        PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
  42        PLL_1443X_RATE(600000000U, 300, 3, 2, 0),
  43        PLL_1443X_RATE(594000000U, 99, 1, 2, 0),
  44        PLL_1443X_RATE(400000000U, 300, 9, 1, 0),
  45        PLL_1443X_RATE(266666667U, 400, 9, 2, 0),
  46        PLL_1443X_RATE(167000000U, 334, 3, 4, 0),
  47        PLL_1443X_RATE(100000000U, 300, 9, 3, 0),
  48};
  49
  50static int fracpll_configure(enum pll_clocks pll, u32 freq)
  51{
  52        int i;
  53        u32 tmp, div_val;
  54        void *pll_base;
  55        struct imx_int_pll_rate_table *rate;
  56
  57        for (i = 0; i < ARRAY_SIZE(imx8mm_fracpll_tbl); i++) {
  58                if (freq == imx8mm_fracpll_tbl[i].rate)
  59                        break;
  60        }
  61
  62        if (i == ARRAY_SIZE(imx8mm_fracpll_tbl)) {
  63                printf("No matched freq table %u\n", freq);
  64                return -EINVAL;
  65        }
  66
  67        rate = &imx8mm_fracpll_tbl[i];
  68
  69        switch (pll) {
  70        case ANATOP_DRAM_PLL:
  71                setbits_le32(GPC_BASE_ADDR + 0xEC, 1 << 7);
  72                setbits_le32(GPC_BASE_ADDR + 0xF8, 1 << 5);
  73                writel(SRC_DDR1_ENABLE_MASK, SRC_BASE_ADDR + 0x1004);
  74
  75                pll_base = &ana_pll->dram_pll_gnrl_ctl;
  76                break;
  77        case ANATOP_VIDEO_PLL:
  78                pll_base = &ana_pll->video_pll1_gnrl_ctl;
  79                break;
  80        default:
  81                return 0;
  82        }
  83        /* Bypass clock and set lock to pll output lock */
  84        tmp = readl(pll_base);
  85        tmp |= BYPASS_MASK;
  86        writel(tmp, pll_base);
  87
  88        /* Enable RST */
  89        tmp &= ~RST_MASK;
  90        writel(tmp, pll_base);
  91
  92        div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
  93                (rate->sdiv << SDIV_SHIFT);
  94        writel(div_val, pll_base + 4);
  95        writel(rate->kdiv << KDIV_SHIFT, pll_base + 8);
  96
  97        __udelay(100);
  98
  99        /* Disable RST */
 100        tmp |= RST_MASK;
 101        writel(tmp, pll_base);
 102
 103        /* Wait Lock*/
 104        while (!(readl(pll_base) & LOCK_STATUS))
 105                ;
 106
 107        /* Bypass */
 108        tmp &= ~BYPASS_MASK;
 109        writel(tmp, pll_base);
 110
 111        return 0;
 112}
 113
 114void dram_pll_init(ulong pll_val)
 115{
 116        fracpll_configure(ANATOP_DRAM_PLL, pll_val);
 117}
 118
 119static struct dram_bypass_clk_setting imx8mm_dram_bypass_tbl[] = {
 120        DRAM_BYPASS_ROOT_CONFIG(MHZ(100), 2, CLK_ROOT_PRE_DIV1, 2,
 121                                CLK_ROOT_PRE_DIV2),
 122        DRAM_BYPASS_ROOT_CONFIG(MHZ(250), 3, CLK_ROOT_PRE_DIV2, 2,
 123                                CLK_ROOT_PRE_DIV2),
 124        DRAM_BYPASS_ROOT_CONFIG(MHZ(400), 1, CLK_ROOT_PRE_DIV2, 3,
 125                                CLK_ROOT_PRE_DIV2),
 126};
 127
 128void dram_enable_bypass(ulong clk_val)
 129{
 130        int i;
 131        struct dram_bypass_clk_setting *config;
 132
 133        for (i = 0; i < ARRAY_SIZE(imx8mm_dram_bypass_tbl); i++) {
 134                if (clk_val == imx8mm_dram_bypass_tbl[i].clk)
 135                        break;
 136        }
 137
 138        if (i == ARRAY_SIZE(imx8mm_dram_bypass_tbl)) {
 139                printf("No matched freq table %lu\n", clk_val);
 140                return;
 141        }
 142
 143        config = &imx8mm_dram_bypass_tbl[i];
 144
 145        clock_set_target_val(DRAM_ALT_CLK_ROOT, CLK_ROOT_ON |
 146                             CLK_ROOT_SOURCE_SEL(config->alt_root_sel) |
 147                             CLK_ROOT_PRE_DIV(config->alt_pre_div));
 148        clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON |
 149                             CLK_ROOT_SOURCE_SEL(config->apb_root_sel) |
 150                             CLK_ROOT_PRE_DIV(config->apb_pre_div));
 151        clock_set_target_val(DRAM_SEL_CFG, CLK_ROOT_ON |
 152                             CLK_ROOT_SOURCE_SEL(1));
 153}
 154
 155void dram_disable_bypass(void)
 156{
 157        clock_set_target_val(DRAM_SEL_CFG, CLK_ROOT_ON |
 158                             CLK_ROOT_SOURCE_SEL(0));
 159        clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON |
 160                             CLK_ROOT_SOURCE_SEL(4) |
 161                             CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV5));
 162}
 163#endif
 164
 165void init_uart_clk(u32 index)
 166{
 167        /*
 168         * set uart clock root
 169         * 24M OSC
 170         */
 171        switch (index) {
 172        case 0:
 173                clock_enable(CCGR_UART1, 0);
 174                clock_set_target_val(UART1_CLK_ROOT, CLK_ROOT_ON |
 175                                     CLK_ROOT_SOURCE_SEL(0));
 176                clock_enable(CCGR_UART1, 1);
 177                return;
 178        case 1:
 179                clock_enable(CCGR_UART2, 0);
 180                clock_set_target_val(UART2_CLK_ROOT, CLK_ROOT_ON |
 181                                     CLK_ROOT_SOURCE_SEL(0));
 182                clock_enable(CCGR_UART2, 1);
 183                return;
 184        case 2:
 185                clock_enable(CCGR_UART3, 0);
 186                clock_set_target_val(UART3_CLK_ROOT, CLK_ROOT_ON |
 187                                     CLK_ROOT_SOURCE_SEL(0));
 188                clock_enable(CCGR_UART3, 1);
 189                return;
 190        case 3:
 191                clock_enable(CCGR_UART4, 0);
 192                clock_set_target_val(UART4_CLK_ROOT, CLK_ROOT_ON |
 193                                     CLK_ROOT_SOURCE_SEL(0));
 194                clock_enable(CCGR_UART4, 1);
 195                return;
 196        default:
 197                printf("Invalid uart index\n");
 198                return;
 199        }
 200}
 201
 202void init_wdog_clk(void)
 203{
 204        clock_enable(CCGR_WDOG1, 0);
 205        clock_enable(CCGR_WDOG2, 0);
 206        clock_enable(CCGR_WDOG3, 0);
 207        clock_set_target_val(WDOG_CLK_ROOT, CLK_ROOT_ON |
 208                             CLK_ROOT_SOURCE_SEL(0));
 209        clock_enable(CCGR_WDOG1, 1);
 210        clock_enable(CCGR_WDOG2, 1);
 211        clock_enable(CCGR_WDOG3, 1);
 212}
 213
 214int clock_init(void)
 215{
 216        u32 val_cfg0;
 217
 218        /*
 219         * The gate is not exported to clk tree, so configure them here.
 220         * According to ANAMIX SPEC
 221         * sys pll1 fixed at 800MHz
 222         * sys pll2 fixed at 1GHz
 223         * Here we only enable the outputs.
 224         */
 225        val_cfg0 = readl(&ana_pll->sys_pll1_gnrl_ctl);
 226        val_cfg0 |= INTPLL_CLKE_MASK | INTPLL_DIV2_CLKE_MASK |
 227                INTPLL_DIV3_CLKE_MASK | INTPLL_DIV4_CLKE_MASK |
 228                INTPLL_DIV5_CLKE_MASK | INTPLL_DIV6_CLKE_MASK |
 229                INTPLL_DIV8_CLKE_MASK | INTPLL_DIV10_CLKE_MASK |
 230                INTPLL_DIV20_CLKE_MASK;
 231        writel(val_cfg0, &ana_pll->sys_pll1_gnrl_ctl);
 232
 233        val_cfg0 = readl(&ana_pll->sys_pll2_gnrl_ctl);
 234        val_cfg0 |= INTPLL_CLKE_MASK | INTPLL_DIV2_CLKE_MASK |
 235                INTPLL_DIV3_CLKE_MASK | INTPLL_DIV4_CLKE_MASK |
 236                INTPLL_DIV5_CLKE_MASK | INTPLL_DIV6_CLKE_MASK |
 237                INTPLL_DIV8_CLKE_MASK | INTPLL_DIV10_CLKE_MASK |
 238                INTPLL_DIV20_CLKE_MASK;
 239        writel(val_cfg0, &ana_pll->sys_pll2_gnrl_ctl);
 240
 241        /* config GIC to sys_pll2_100m */
 242        clock_enable(CCGR_GIC, 0);
 243        clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON |
 244                             CLK_ROOT_SOURCE_SEL(3));
 245        clock_enable(CCGR_GIC, 1);
 246
 247        clock_set_target_val(NAND_USDHC_BUS_CLK_ROOT, CLK_ROOT_ON |
 248                             CLK_ROOT_SOURCE_SEL(1));
 249
 250        clock_enable(CCGR_DDR1, 0);
 251        clock_set_target_val(DRAM_ALT_CLK_ROOT, CLK_ROOT_ON |
 252                             CLK_ROOT_SOURCE_SEL(1));
 253        clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON |
 254                             CLK_ROOT_SOURCE_SEL(1));
 255        clock_enable(CCGR_DDR1, 1);
 256
 257        init_wdog_clk();
 258
 259        clock_enable(CCGR_TEMP_SENSOR, 1);
 260
 261        clock_enable(CCGR_SEC_DEBUG, 1);
 262
 263        return 0;
 264};
 265
 266u32 imx_get_uartclk(void)
 267{
 268        return 24000000U;
 269}
 270
 271static u32 decode_intpll(enum clk_root_src intpll)
 272{
 273        u32 pll_gnrl_ctl, pll_div_ctl, pll_clke_mask;
 274        u32 main_div, pre_div, post_div, div;
 275        u64 freq;
 276
 277        switch (intpll) {
 278        case ARM_PLL_CLK:
 279                pll_gnrl_ctl = readl(&ana_pll->arm_pll_gnrl_ctl);
 280                pll_div_ctl = readl(&ana_pll->arm_pll_div_ctl);
 281                break;
 282        case GPU_PLL_CLK:
 283                pll_gnrl_ctl = readl(&ana_pll->gpu_pll_gnrl_ctl);
 284                pll_div_ctl = readl(&ana_pll->gpu_pll_div_ctl);
 285                break;
 286        case VPU_PLL_CLK:
 287                pll_gnrl_ctl = readl(&ana_pll->vpu_pll_gnrl_ctl);
 288                pll_div_ctl = readl(&ana_pll->vpu_pll_div_ctl);
 289                break;
 290        case SYSTEM_PLL1_800M_CLK:
 291        case SYSTEM_PLL1_400M_CLK:
 292        case SYSTEM_PLL1_266M_CLK:
 293        case SYSTEM_PLL1_200M_CLK:
 294        case SYSTEM_PLL1_160M_CLK:
 295        case SYSTEM_PLL1_133M_CLK:
 296        case SYSTEM_PLL1_100M_CLK:
 297        case SYSTEM_PLL1_80M_CLK:
 298        case SYSTEM_PLL1_40M_CLK:
 299                pll_gnrl_ctl = readl(&ana_pll->sys_pll1_gnrl_ctl);
 300                pll_div_ctl = readl(&ana_pll->sys_pll1_div_ctl);
 301                break;
 302        case SYSTEM_PLL2_1000M_CLK:
 303        case SYSTEM_PLL2_500M_CLK:
 304        case SYSTEM_PLL2_333M_CLK:
 305        case SYSTEM_PLL2_250M_CLK:
 306        case SYSTEM_PLL2_200M_CLK:
 307        case SYSTEM_PLL2_166M_CLK:
 308        case SYSTEM_PLL2_125M_CLK:
 309        case SYSTEM_PLL2_100M_CLK:
 310        case SYSTEM_PLL2_50M_CLK:
 311                pll_gnrl_ctl = readl(&ana_pll->sys_pll2_gnrl_ctl);
 312                pll_div_ctl = readl(&ana_pll->sys_pll2_div_ctl);
 313                break;
 314        case SYSTEM_PLL3_CLK:
 315                pll_gnrl_ctl = readl(&ana_pll->sys_pll3_gnrl_ctl);
 316                pll_div_ctl = readl(&ana_pll->sys_pll3_div_ctl);
 317                break;
 318        default:
 319                return -EINVAL;
 320        }
 321
 322        /* Only support SYS_XTAL 24M, PAD_CLK not take into consideration */
 323        if ((pll_gnrl_ctl & INTPLL_REF_CLK_SEL_MASK) != 0)
 324                return 0;
 325
 326        if ((pll_gnrl_ctl & INTPLL_RST_MASK) == 0)
 327                return 0;
 328
 329        /*
 330         * When BYPASS is equal to 1, PLL enters the bypass mode
 331         * regardless of the values of RESETB
 332         */
 333        if (pll_gnrl_ctl & INTPLL_BYPASS_MASK)
 334                return 24000000u;
 335
 336        if (!(pll_gnrl_ctl & INTPLL_LOCK_MASK)) {
 337                puts("pll not locked\n");
 338                return 0;
 339        }
 340
 341        switch (intpll) {
 342        case ARM_PLL_CLK:
 343        case GPU_PLL_CLK:
 344        case VPU_PLL_CLK:
 345        case SYSTEM_PLL3_CLK:
 346        case SYSTEM_PLL1_800M_CLK:
 347        case SYSTEM_PLL2_1000M_CLK:
 348                pll_clke_mask = INTPLL_CLKE_MASK;
 349                div = 1;
 350                break;
 351
 352        case SYSTEM_PLL1_400M_CLK:
 353        case SYSTEM_PLL2_500M_CLK:
 354                pll_clke_mask = INTPLL_DIV2_CLKE_MASK;
 355                div = 2;
 356                break;
 357
 358        case SYSTEM_PLL1_266M_CLK:
 359        case SYSTEM_PLL2_333M_CLK:
 360                pll_clke_mask = INTPLL_DIV3_CLKE_MASK;
 361                div = 3;
 362                break;
 363
 364        case SYSTEM_PLL1_200M_CLK:
 365        case SYSTEM_PLL2_250M_CLK:
 366                pll_clke_mask = INTPLL_DIV4_CLKE_MASK;
 367                div = 4;
 368                break;
 369
 370        case SYSTEM_PLL1_160M_CLK:
 371        case SYSTEM_PLL2_200M_CLK:
 372                pll_clke_mask = INTPLL_DIV5_CLKE_MASK;
 373                div = 5;
 374                break;
 375
 376        case SYSTEM_PLL1_133M_CLK:
 377        case SYSTEM_PLL2_166M_CLK:
 378                pll_clke_mask = INTPLL_DIV6_CLKE_MASK;
 379                div = 6;
 380                break;
 381
 382        case SYSTEM_PLL1_100M_CLK:
 383        case SYSTEM_PLL2_125M_CLK:
 384                pll_clke_mask = INTPLL_DIV8_CLKE_MASK;
 385                div = 8;
 386                break;
 387
 388        case SYSTEM_PLL1_80M_CLK:
 389        case SYSTEM_PLL2_100M_CLK:
 390                pll_clke_mask = INTPLL_DIV10_CLKE_MASK;
 391                div = 10;
 392                break;
 393
 394        case SYSTEM_PLL1_40M_CLK:
 395        case SYSTEM_PLL2_50M_CLK:
 396                pll_clke_mask = INTPLL_DIV20_CLKE_MASK;
 397                div = 20;
 398                break;
 399        default:
 400                return -EINVAL;
 401        }
 402
 403        if ((pll_gnrl_ctl & pll_clke_mask) == 0)
 404                return 0;
 405
 406        main_div = (pll_div_ctl & INTPLL_MAIN_DIV_MASK) >>
 407                INTPLL_MAIN_DIV_SHIFT;
 408        pre_div = (pll_div_ctl & INTPLL_PRE_DIV_MASK) >>
 409                INTPLL_PRE_DIV_SHIFT;
 410        post_div = (pll_div_ctl & INTPLL_POST_DIV_MASK) >>
 411                INTPLL_POST_DIV_SHIFT;
 412
 413        /* FFVCO = (m * FFIN) / p, FFOUT = (m * FFIN) / (p * 2^s) */
 414        freq = 24000000ULL * main_div;
 415        return lldiv(freq, pre_div * (1 << post_div) * div);
 416}
 417
 418static u32 decode_fracpll(enum clk_root_src frac_pll)
 419{
 420        u32 pll_gnrl_ctl, pll_fdiv_ctl0, pll_fdiv_ctl1;
 421        u32 main_div, pre_div, post_div, k;
 422
 423        switch (frac_pll) {
 424        case DRAM_PLL1_CLK:
 425                pll_gnrl_ctl = readl(&ana_pll->dram_pll_gnrl_ctl);
 426                pll_fdiv_ctl0 = readl(&ana_pll->dram_pll_fdiv_ctl0);
 427                pll_fdiv_ctl1 = readl(&ana_pll->dram_pll_fdiv_ctl1);
 428                break;
 429        case AUDIO_PLL1_CLK:
 430                pll_gnrl_ctl = readl(&ana_pll->audio_pll1_gnrl_ctl);
 431                pll_fdiv_ctl0 = readl(&ana_pll->audio_pll1_fdiv_ctl0);
 432                pll_fdiv_ctl1 = readl(&ana_pll->audio_pll1_fdiv_ctl1);
 433                break;
 434        case AUDIO_PLL2_CLK:
 435                pll_gnrl_ctl = readl(&ana_pll->audio_pll2_gnrl_ctl);
 436                pll_fdiv_ctl0 = readl(&ana_pll->audio_pll2_fdiv_ctl0);
 437                pll_fdiv_ctl1 = readl(&ana_pll->audio_pll2_fdiv_ctl1);
 438                break;
 439        case VIDEO_PLL_CLK:
 440                pll_gnrl_ctl = readl(&ana_pll->video_pll1_gnrl_ctl);
 441                pll_fdiv_ctl0 = readl(&ana_pll->video_pll1_fdiv_ctl0);
 442                pll_fdiv_ctl1 = readl(&ana_pll->video_pll1_fdiv_ctl1);
 443                break;
 444        default:
 445                printf("Not supported\n");
 446                return 0;
 447        }
 448
 449        /* Only support SYS_XTAL 24M, PAD_CLK not take into consideration */
 450        if ((pll_gnrl_ctl & INTPLL_REF_CLK_SEL_MASK) != 0)
 451                return 0;
 452
 453        if ((pll_gnrl_ctl & INTPLL_RST_MASK) == 0)
 454                return 0;
 455        /*
 456         * When BYPASS is equal to 1, PLL enters the bypass mode
 457         * regardless of the values of RESETB
 458         */
 459        if (pll_gnrl_ctl & INTPLL_BYPASS_MASK)
 460                return 24000000u;
 461
 462        if (!(pll_gnrl_ctl & INTPLL_LOCK_MASK)) {
 463                puts("pll not locked\n");
 464                return 0;
 465        }
 466
 467        if (!(pll_gnrl_ctl & INTPLL_CLKE_MASK))
 468                return 0;
 469
 470        main_div = (pll_fdiv_ctl0 & INTPLL_MAIN_DIV_MASK) >>
 471                INTPLL_MAIN_DIV_SHIFT;
 472        pre_div = (pll_fdiv_ctl0 & INTPLL_PRE_DIV_MASK) >>
 473                INTPLL_PRE_DIV_SHIFT;
 474        post_div = (pll_fdiv_ctl0 & INTPLL_POST_DIV_MASK) >>
 475                INTPLL_POST_DIV_SHIFT;
 476
 477        k = pll_fdiv_ctl1 & GENMASK(15, 0);
 478
 479        return lldiv((main_div * 65536 + k) * 24000000ULL,
 480                     65536 * pre_div * (1 << post_div));
 481}
 482
 483static u32 get_root_src_clk(enum clk_root_src root_src)
 484{
 485        switch (root_src) {
 486        case OSC_24M_CLK:
 487                return 24000000u;
 488        case OSC_HDMI_CLK:
 489                return 26000000u;
 490        case OSC_32K_CLK:
 491                return 32000u;
 492        case ARM_PLL_CLK:
 493        case GPU_PLL_CLK:
 494        case VPU_PLL_CLK:
 495        case SYSTEM_PLL1_800M_CLK:
 496        case SYSTEM_PLL1_400M_CLK:
 497        case SYSTEM_PLL1_266M_CLK:
 498        case SYSTEM_PLL1_200M_CLK:
 499        case SYSTEM_PLL1_160M_CLK:
 500        case SYSTEM_PLL1_133M_CLK:
 501        case SYSTEM_PLL1_100M_CLK:
 502        case SYSTEM_PLL1_80M_CLK:
 503        case SYSTEM_PLL1_40M_CLK:
 504        case SYSTEM_PLL2_1000M_CLK:
 505        case SYSTEM_PLL2_500M_CLK:
 506        case SYSTEM_PLL2_333M_CLK:
 507        case SYSTEM_PLL2_250M_CLK:
 508        case SYSTEM_PLL2_200M_CLK:
 509        case SYSTEM_PLL2_166M_CLK:
 510        case SYSTEM_PLL2_125M_CLK:
 511        case SYSTEM_PLL2_100M_CLK:
 512        case SYSTEM_PLL2_50M_CLK:
 513        case SYSTEM_PLL3_CLK:
 514                return decode_intpll(root_src);
 515        case DRAM_PLL1_CLK:
 516        case AUDIO_PLL1_CLK:
 517        case AUDIO_PLL2_CLK:
 518        case VIDEO_PLL_CLK:
 519                return decode_fracpll(root_src);
 520        default:
 521                return 0;
 522        }
 523
 524        return 0;
 525}
 526
 527static u32 get_root_clk(enum clk_root_index clock_id)
 528{
 529        enum clk_root_src root_src;
 530        u32 post_podf, pre_podf, root_src_clk;
 531
 532        if (clock_root_enabled(clock_id) <= 0)
 533                return 0;
 534
 535        if (clock_get_prediv(clock_id, &pre_podf) < 0)
 536                return 0;
 537
 538        if (clock_get_postdiv(clock_id, &post_podf) < 0)
 539                return 0;
 540
 541        if (clock_get_src(clock_id, &root_src) < 0)
 542                return 0;
 543
 544        root_src_clk = get_root_src_clk(root_src);
 545
 546        return root_src_clk / (post_podf + 1) / (pre_podf + 1);
 547}
 548
 549u32 mxc_get_clock(enum mxc_clock clk)
 550{
 551        u32 val;
 552
 553        switch (clk) {
 554        case MXC_ARM_CLK:
 555                return get_root_clk(ARM_A53_CLK_ROOT);
 556        case MXC_IPG_CLK:
 557                clock_get_target_val(IPG_CLK_ROOT, &val);
 558                val = val & 0x3;
 559                return get_root_clk(AHB_CLK_ROOT) / 2 / (val + 1);
 560        case MXC_CSPI_CLK:
 561                return get_root_clk(ECSPI1_CLK_ROOT);
 562        case MXC_ESDHC_CLK:
 563                return get_root_clk(USDHC1_CLK_ROOT);
 564        case MXC_ESDHC2_CLK:
 565                return get_root_clk(USDHC2_CLK_ROOT);
 566        case MXC_ESDHC3_CLK:
 567                return get_root_clk(USDHC3_CLK_ROOT);
 568        case MXC_I2C_CLK:
 569                return get_root_clk(I2C1_CLK_ROOT);
 570        case MXC_UART_CLK:
 571                return get_root_clk(UART1_CLK_ROOT);
 572        case MXC_QSPI_CLK:
 573                return get_root_clk(QSPI_CLK_ROOT);
 574        default:
 575                printf("Unsupported mxc_clock %d\n", clk);
 576                break;
 577        }
 578
 579        return 0;
 580}
 581