1*508791a0SLey Foon Tan // SPDX-License-Identifier: GPL-2.0 2*508791a0SLey Foon Tan /* 3*508791a0SLey Foon Tan * Copyright (C) 2016-2018 Intel Corporation <www.intel.com> 4*508791a0SLey Foon Tan * 5*508791a0SLey Foon Tan */ 6*508791a0SLey Foon Tan 7*508791a0SLey Foon Tan #include <common.h> 8*508791a0SLey Foon Tan #include <asm/io.h> 9*508791a0SLey Foon Tan #include <asm/arch/clock_manager.h> 10*508791a0SLey Foon Tan #include <asm/arch/handoff_s10.h> 11*508791a0SLey Foon Tan #include <asm/arch/system_manager.h> 12*508791a0SLey Foon Tan 13*508791a0SLey Foon Tan DECLARE_GLOBAL_DATA_PTR; 14*508791a0SLey Foon Tan 15*508791a0SLey Foon Tan static const struct socfpga_clock_manager *clock_manager_base = 16*508791a0SLey Foon Tan (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; 17*508791a0SLey Foon Tan static const struct socfpga_system_manager *sysmgr_regs = 18*508791a0SLey Foon Tan (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; 19*508791a0SLey Foon Tan 20*508791a0SLey Foon Tan /* 21*508791a0SLey Foon Tan * function to write the bypass register which requires a poll of the 22*508791a0SLey Foon Tan * busy bit 23*508791a0SLey Foon Tan */ 24*508791a0SLey Foon Tan static void cm_write_bypass_mainpll(u32 val) 25*508791a0SLey Foon Tan { 26*508791a0SLey Foon Tan writel(val, &clock_manager_base->main_pll.bypass); 27*508791a0SLey Foon Tan cm_wait_for_fsm(); 28*508791a0SLey Foon Tan } 29*508791a0SLey Foon Tan 30*508791a0SLey Foon Tan static void cm_write_bypass_perpll(u32 val) 31*508791a0SLey Foon Tan { 32*508791a0SLey Foon Tan writel(val, &clock_manager_base->per_pll.bypass); 33*508791a0SLey Foon Tan cm_wait_for_fsm(); 34*508791a0SLey Foon Tan } 35*508791a0SLey Foon Tan 36*508791a0SLey Foon Tan /* function to write the ctrl register which requires a poll of the busy bit */ 37*508791a0SLey Foon Tan static void cm_write_ctrl(u32 val) 38*508791a0SLey Foon Tan { 39*508791a0SLey Foon Tan writel(val, &clock_manager_base->ctrl); 40*508791a0SLey Foon Tan cm_wait_for_fsm(); 41*508791a0SLey Foon Tan } 42*508791a0SLey Foon Tan 43*508791a0SLey Foon Tan /* 44*508791a0SLey Foon Tan * Setup clocks while making no assumptions about previous state of the clocks. 45*508791a0SLey Foon Tan */ 46*508791a0SLey Foon Tan void cm_basic_init(const struct cm_config * const cfg) 47*508791a0SLey Foon Tan { 48*508791a0SLey Foon Tan u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib; 49*508791a0SLey Foon Tan 50*508791a0SLey Foon Tan if (cfg == 0) 51*508791a0SLey Foon Tan return; 52*508791a0SLey Foon Tan 53*508791a0SLey Foon Tan /* Put all plls in bypass */ 54*508791a0SLey Foon Tan cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL); 55*508791a0SLey Foon Tan cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL); 56*508791a0SLey Foon Tan 57*508791a0SLey Foon Tan /* setup main PLL dividers where calculate the vcocalib value */ 58*508791a0SLey Foon Tan mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) & 59*508791a0SLey Foon Tan CLKMGR_FDBCK_MDIV_MASK; 60*508791a0SLey Foon Tan refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & 61*508791a0SLey Foon Tan CLKMGR_PLLGLOB_REFCLKDIV_MASK; 62*508791a0SLey Foon Tan mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv; 63*508791a0SLey Foon Tan hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv - 64*508791a0SLey Foon Tan CLKMGR_HSCNT_CONST; 65*508791a0SLey Foon Tan vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) | 66*508791a0SLey Foon Tan ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) << 67*508791a0SLey Foon Tan CLKMGR_VCOCALIB_MSCNT_OFFSET); 68*508791a0SLey Foon Tan 69*508791a0SLey Foon Tan writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK & 70*508791a0SLey Foon Tan ~CLKMGR_PLLGLOB_RST_MASK), 71*508791a0SLey Foon Tan &clock_manager_base->main_pll.pllglob); 72*508791a0SLey Foon Tan writel(cfg->main_pll_fdbck, &clock_manager_base->main_pll.fdbck); 73*508791a0SLey Foon Tan writel(vcocalib, &clock_manager_base->main_pll.vcocalib); 74*508791a0SLey Foon Tan writel(cfg->main_pll_pllc0, &clock_manager_base->main_pll.pllc0); 75*508791a0SLey Foon Tan writel(cfg->main_pll_pllc1, &clock_manager_base->main_pll.pllc1); 76*508791a0SLey Foon Tan writel(cfg->main_pll_nocdiv, &clock_manager_base->main_pll.nocdiv); 77*508791a0SLey Foon Tan 78*508791a0SLey Foon Tan /* setup peripheral PLL dividers */ 79*508791a0SLey Foon Tan /* calculate the vcocalib value */ 80*508791a0SLey Foon Tan mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) & 81*508791a0SLey Foon Tan CLKMGR_FDBCK_MDIV_MASK; 82*508791a0SLey Foon Tan refclkdiv = (cfg->per_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & 83*508791a0SLey Foon Tan CLKMGR_PLLGLOB_REFCLKDIV_MASK; 84*508791a0SLey Foon Tan mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv; 85*508791a0SLey Foon Tan hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv - 86*508791a0SLey Foon Tan CLKMGR_HSCNT_CONST; 87*508791a0SLey Foon Tan vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) | 88*508791a0SLey Foon Tan ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) << 89*508791a0SLey Foon Tan CLKMGR_VCOCALIB_MSCNT_OFFSET); 90*508791a0SLey Foon Tan 91*508791a0SLey Foon Tan writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK & 92*508791a0SLey Foon Tan ~CLKMGR_PLLGLOB_RST_MASK), 93*508791a0SLey Foon Tan &clock_manager_base->per_pll.pllglob); 94*508791a0SLey Foon Tan writel(cfg->per_pll_fdbck, &clock_manager_base->per_pll.fdbck); 95*508791a0SLey Foon Tan writel(vcocalib, &clock_manager_base->per_pll.vcocalib); 96*508791a0SLey Foon Tan writel(cfg->per_pll_pllc0, &clock_manager_base->per_pll.pllc0); 97*508791a0SLey Foon Tan writel(cfg->per_pll_pllc1, &clock_manager_base->per_pll.pllc1); 98*508791a0SLey Foon Tan writel(cfg->per_pll_emacctl, &clock_manager_base->per_pll.emacctl); 99*508791a0SLey Foon Tan writel(cfg->per_pll_gpiodiv, &clock_manager_base->per_pll.gpiodiv); 100*508791a0SLey Foon Tan 101*508791a0SLey Foon Tan /* Take both PLL out of reset and power up */ 102*508791a0SLey Foon Tan setbits_le32(&clock_manager_base->main_pll.pllglob, 103*508791a0SLey Foon Tan CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK); 104*508791a0SLey Foon Tan setbits_le32(&clock_manager_base->per_pll.pllglob, 105*508791a0SLey Foon Tan CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK); 106*508791a0SLey Foon Tan 107*508791a0SLey Foon Tan #define LOCKED_MASK \ 108*508791a0SLey Foon Tan (CLKMGR_STAT_MAINPLL_LOCKED | \ 109*508791a0SLey Foon Tan CLKMGR_STAT_PERPLL_LOCKED) 110*508791a0SLey Foon Tan 111*508791a0SLey Foon Tan cm_wait_for_lock(LOCKED_MASK); 112*508791a0SLey Foon Tan 113*508791a0SLey Foon Tan /* 114*508791a0SLey Foon Tan * Dividers for C2 to C9 only init after PLLs are lock. As dividers 115*508791a0SLey Foon Tan * only take effect upon value change, we shall set a maximum value as 116*508791a0SLey Foon Tan * default value. 117*508791a0SLey Foon Tan */ 118*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.mpuclk); 119*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.nocclk); 120*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr2clk); 121*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr3clk); 122*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr4clk); 123*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr5clk); 124*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr6clk); 125*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr7clk); 126*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr8clk); 127*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->main_pll.cntr9clk); 128*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr2clk); 129*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr3clk); 130*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr4clk); 131*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr5clk); 132*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr6clk); 133*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr7clk); 134*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr8clk); 135*508791a0SLey Foon Tan writel(0xff, &clock_manager_base->per_pll.cntr9clk); 136*508791a0SLey Foon Tan 137*508791a0SLey Foon Tan writel(cfg->main_pll_mpuclk, &clock_manager_base->main_pll.mpuclk); 138*508791a0SLey Foon Tan writel(cfg->main_pll_nocclk, &clock_manager_base->main_pll.nocclk); 139*508791a0SLey Foon Tan writel(cfg->main_pll_cntr2clk, &clock_manager_base->main_pll.cntr2clk); 140*508791a0SLey Foon Tan writel(cfg->main_pll_cntr3clk, &clock_manager_base->main_pll.cntr3clk); 141*508791a0SLey Foon Tan writel(cfg->main_pll_cntr4clk, &clock_manager_base->main_pll.cntr4clk); 142*508791a0SLey Foon Tan writel(cfg->main_pll_cntr5clk, &clock_manager_base->main_pll.cntr5clk); 143*508791a0SLey Foon Tan writel(cfg->main_pll_cntr6clk, &clock_manager_base->main_pll.cntr6clk); 144*508791a0SLey Foon Tan writel(cfg->main_pll_cntr7clk, &clock_manager_base->main_pll.cntr7clk); 145*508791a0SLey Foon Tan writel(cfg->main_pll_cntr8clk, &clock_manager_base->main_pll.cntr8clk); 146*508791a0SLey Foon Tan writel(cfg->main_pll_cntr9clk, &clock_manager_base->main_pll.cntr9clk); 147*508791a0SLey Foon Tan writel(cfg->per_pll_cntr2clk, &clock_manager_base->per_pll.cntr2clk); 148*508791a0SLey Foon Tan writel(cfg->per_pll_cntr3clk, &clock_manager_base->per_pll.cntr3clk); 149*508791a0SLey Foon Tan writel(cfg->per_pll_cntr4clk, &clock_manager_base->per_pll.cntr4clk); 150*508791a0SLey Foon Tan writel(cfg->per_pll_cntr5clk, &clock_manager_base->per_pll.cntr5clk); 151*508791a0SLey Foon Tan writel(cfg->per_pll_cntr6clk, &clock_manager_base->per_pll.cntr6clk); 152*508791a0SLey Foon Tan writel(cfg->per_pll_cntr7clk, &clock_manager_base->per_pll.cntr7clk); 153*508791a0SLey Foon Tan writel(cfg->per_pll_cntr8clk, &clock_manager_base->per_pll.cntr8clk); 154*508791a0SLey Foon Tan writel(cfg->per_pll_cntr9clk, &clock_manager_base->per_pll.cntr9clk); 155*508791a0SLey Foon Tan 156*508791a0SLey Foon Tan /* Take all PLLs out of bypass */ 157*508791a0SLey Foon Tan cm_write_bypass_mainpll(0); 158*508791a0SLey Foon Tan cm_write_bypass_perpll(0); 159*508791a0SLey Foon Tan 160*508791a0SLey Foon Tan /* clear safe mode / out of boot mode */ 161*508791a0SLey Foon Tan cm_write_ctrl(readl(&clock_manager_base->ctrl) 162*508791a0SLey Foon Tan & ~(CLKMGR_CTRL_SAFEMODE)); 163*508791a0SLey Foon Tan 164*508791a0SLey Foon Tan /* Now ungate non-hw-managed clocks */ 165*508791a0SLey Foon Tan writel(~0, &clock_manager_base->main_pll.en); 166*508791a0SLey Foon Tan writel(~0, &clock_manager_base->per_pll.en); 167*508791a0SLey Foon Tan 168*508791a0SLey Foon Tan /* Clear the loss of lock bits (write 1 to clear) */ 169*508791a0SLey Foon Tan writel(CLKMGR_INTER_PERPLLLOST_MASK | CLKMGR_INTER_MAINPLLLOST_MASK, 170*508791a0SLey Foon Tan &clock_manager_base->intrclr); 171*508791a0SLey Foon Tan } 172*508791a0SLey Foon Tan 173*508791a0SLey Foon Tan static unsigned long cm_get_main_vco_clk_hz(void) 174*508791a0SLey Foon Tan { 175*508791a0SLey Foon Tan unsigned long fref, refdiv, mdiv, reg, vco; 176*508791a0SLey Foon Tan 177*508791a0SLey Foon Tan reg = readl(&clock_manager_base->main_pll.pllglob); 178*508791a0SLey Foon Tan 179*508791a0SLey Foon Tan fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) & 180*508791a0SLey Foon Tan CLKMGR_PLLGLOB_VCO_PSRC_MASK; 181*508791a0SLey Foon Tan switch (fref) { 182*508791a0SLey Foon Tan case CLKMGR_VCO_PSRC_EOSC1: 183*508791a0SLey Foon Tan fref = cm_get_osc_clk_hz(); 184*508791a0SLey Foon Tan break; 185*508791a0SLey Foon Tan case CLKMGR_VCO_PSRC_INTOSC: 186*508791a0SLey Foon Tan fref = cm_get_intosc_clk_hz(); 187*508791a0SLey Foon Tan break; 188*508791a0SLey Foon Tan case CLKMGR_VCO_PSRC_F2S: 189*508791a0SLey Foon Tan fref = cm_get_fpga_clk_hz(); 190*508791a0SLey Foon Tan break; 191*508791a0SLey Foon Tan } 192*508791a0SLey Foon Tan 193*508791a0SLey Foon Tan refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & 194*508791a0SLey Foon Tan CLKMGR_PLLGLOB_REFCLKDIV_MASK; 195*508791a0SLey Foon Tan 196*508791a0SLey Foon Tan reg = readl(&clock_manager_base->main_pll.fdbck); 197*508791a0SLey Foon Tan mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK; 198*508791a0SLey Foon Tan 199*508791a0SLey Foon Tan vco = fref / refdiv; 200*508791a0SLey Foon Tan vco = vco * (CLKMGR_MDIV_CONST + mdiv); 201*508791a0SLey Foon Tan return vco; 202*508791a0SLey Foon Tan } 203*508791a0SLey Foon Tan 204*508791a0SLey Foon Tan static unsigned long cm_get_per_vco_clk_hz(void) 205*508791a0SLey Foon Tan { 206*508791a0SLey Foon Tan unsigned long fref, refdiv, mdiv, reg, vco; 207*508791a0SLey Foon Tan 208*508791a0SLey Foon Tan reg = readl(&clock_manager_base->per_pll.pllglob); 209*508791a0SLey Foon Tan 210*508791a0SLey Foon Tan fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) & 211*508791a0SLey Foon Tan CLKMGR_PLLGLOB_VCO_PSRC_MASK; 212*508791a0SLey Foon Tan switch (fref) { 213*508791a0SLey Foon Tan case CLKMGR_VCO_PSRC_EOSC1: 214*508791a0SLey Foon Tan fref = cm_get_osc_clk_hz(); 215*508791a0SLey Foon Tan break; 216*508791a0SLey Foon Tan case CLKMGR_VCO_PSRC_INTOSC: 217*508791a0SLey Foon Tan fref = cm_get_intosc_clk_hz(); 218*508791a0SLey Foon Tan break; 219*508791a0SLey Foon Tan case CLKMGR_VCO_PSRC_F2S: 220*508791a0SLey Foon Tan fref = cm_get_fpga_clk_hz(); 221*508791a0SLey Foon Tan break; 222*508791a0SLey Foon Tan } 223*508791a0SLey Foon Tan 224*508791a0SLey Foon Tan refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & 225*508791a0SLey Foon Tan CLKMGR_PLLGLOB_REFCLKDIV_MASK; 226*508791a0SLey Foon Tan 227*508791a0SLey Foon Tan reg = readl(&clock_manager_base->per_pll.fdbck); 228*508791a0SLey Foon Tan mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK; 229*508791a0SLey Foon Tan 230*508791a0SLey Foon Tan vco = fref / refdiv; 231*508791a0SLey Foon Tan vco = vco * (CLKMGR_MDIV_CONST + mdiv); 232*508791a0SLey Foon Tan return vco; 233*508791a0SLey Foon Tan } 234*508791a0SLey Foon Tan 235*508791a0SLey Foon Tan unsigned long cm_get_mpu_clk_hz(void) 236*508791a0SLey Foon Tan { 237*508791a0SLey Foon Tan unsigned long clock = readl(&clock_manager_base->main_pll.mpuclk); 238*508791a0SLey Foon Tan 239*508791a0SLey Foon Tan clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; 240*508791a0SLey Foon Tan 241*508791a0SLey Foon Tan switch (clock) { 242*508791a0SLey Foon Tan case CLKMGR_CLKSRC_MAIN: 243*508791a0SLey Foon Tan clock = cm_get_main_vco_clk_hz(); 244*508791a0SLey Foon Tan clock /= (readl(&clock_manager_base->main_pll.pllc0) & 245*508791a0SLey Foon Tan CLKMGR_PLLC0_DIV_MASK); 246*508791a0SLey Foon Tan break; 247*508791a0SLey Foon Tan 248*508791a0SLey Foon Tan case CLKMGR_CLKSRC_PER: 249*508791a0SLey Foon Tan clock = cm_get_per_vco_clk_hz(); 250*508791a0SLey Foon Tan clock /= (readl(&clock_manager_base->per_pll.pllc0) & 251*508791a0SLey Foon Tan CLKMGR_CLKCNT_MSK); 252*508791a0SLey Foon Tan break; 253*508791a0SLey Foon Tan 254*508791a0SLey Foon Tan case CLKMGR_CLKSRC_OSC1: 255*508791a0SLey Foon Tan clock = cm_get_osc_clk_hz(); 256*508791a0SLey Foon Tan break; 257*508791a0SLey Foon Tan 258*508791a0SLey Foon Tan case CLKMGR_CLKSRC_INTOSC: 259*508791a0SLey Foon Tan clock = cm_get_intosc_clk_hz(); 260*508791a0SLey Foon Tan break; 261*508791a0SLey Foon Tan 262*508791a0SLey Foon Tan case CLKMGR_CLKSRC_FPGA: 263*508791a0SLey Foon Tan clock = cm_get_fpga_clk_hz(); 264*508791a0SLey Foon Tan break; 265*508791a0SLey Foon Tan } 266*508791a0SLey Foon Tan 267*508791a0SLey Foon Tan clock /= 1 + (readl(&clock_manager_base->main_pll.mpuclk) & 268*508791a0SLey Foon Tan CLKMGR_CLKCNT_MSK); 269*508791a0SLey Foon Tan return clock; 270*508791a0SLey Foon Tan } 271*508791a0SLey Foon Tan 272*508791a0SLey Foon Tan unsigned int cm_get_l3_main_clk_hz(void) 273*508791a0SLey Foon Tan { 274*508791a0SLey Foon Tan u32 clock = readl(&clock_manager_base->main_pll.nocclk); 275*508791a0SLey Foon Tan 276*508791a0SLey Foon Tan clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; 277*508791a0SLey Foon Tan 278*508791a0SLey Foon Tan switch (clock) { 279*508791a0SLey Foon Tan case CLKMGR_CLKSRC_MAIN: 280*508791a0SLey Foon Tan clock = cm_get_main_vco_clk_hz(); 281*508791a0SLey Foon Tan clock /= (readl(&clock_manager_base->main_pll.pllc1) & 282*508791a0SLey Foon Tan CLKMGR_PLLC0_DIV_MASK); 283*508791a0SLey Foon Tan break; 284*508791a0SLey Foon Tan 285*508791a0SLey Foon Tan case CLKMGR_CLKSRC_PER: 286*508791a0SLey Foon Tan clock = cm_get_per_vco_clk_hz(); 287*508791a0SLey Foon Tan clock /= (readl(&clock_manager_base->per_pll.pllc1) & 288*508791a0SLey Foon Tan CLKMGR_CLKCNT_MSK); 289*508791a0SLey Foon Tan break; 290*508791a0SLey Foon Tan 291*508791a0SLey Foon Tan case CLKMGR_CLKSRC_OSC1: 292*508791a0SLey Foon Tan clock = cm_get_osc_clk_hz(); 293*508791a0SLey Foon Tan break; 294*508791a0SLey Foon Tan 295*508791a0SLey Foon Tan case CLKMGR_CLKSRC_INTOSC: 296*508791a0SLey Foon Tan clock = cm_get_intosc_clk_hz(); 297*508791a0SLey Foon Tan break; 298*508791a0SLey Foon Tan 299*508791a0SLey Foon Tan case CLKMGR_CLKSRC_FPGA: 300*508791a0SLey Foon Tan clock = cm_get_fpga_clk_hz(); 301*508791a0SLey Foon Tan break; 302*508791a0SLey Foon Tan } 303*508791a0SLey Foon Tan 304*508791a0SLey Foon Tan clock /= 1 + (readl(&clock_manager_base->main_pll.nocclk) & 305*508791a0SLey Foon Tan CLKMGR_CLKCNT_MSK); 306*508791a0SLey Foon Tan return clock; 307*508791a0SLey Foon Tan } 308*508791a0SLey Foon Tan 309*508791a0SLey Foon Tan unsigned int cm_get_mmc_controller_clk_hz(void) 310*508791a0SLey Foon Tan { 311*508791a0SLey Foon Tan u32 clock = readl(&clock_manager_base->per_pll.cntr6clk); 312*508791a0SLey Foon Tan 313*508791a0SLey Foon Tan clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; 314*508791a0SLey Foon Tan 315*508791a0SLey Foon Tan switch (clock) { 316*508791a0SLey Foon Tan case CLKMGR_CLKSRC_MAIN: 317*508791a0SLey Foon Tan clock = cm_get_l3_main_clk_hz(); 318*508791a0SLey Foon Tan clock /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) & 319*508791a0SLey Foon Tan CLKMGR_CLKCNT_MSK); 320*508791a0SLey Foon Tan break; 321*508791a0SLey Foon Tan 322*508791a0SLey Foon Tan case CLKMGR_CLKSRC_PER: 323*508791a0SLey Foon Tan clock = cm_get_l3_main_clk_hz(); 324*508791a0SLey Foon Tan clock /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) & 325*508791a0SLey Foon Tan CLKMGR_CLKCNT_MSK); 326*508791a0SLey Foon Tan break; 327*508791a0SLey Foon Tan 328*508791a0SLey Foon Tan case CLKMGR_CLKSRC_OSC1: 329*508791a0SLey Foon Tan clock = cm_get_osc_clk_hz(); 330*508791a0SLey Foon Tan break; 331*508791a0SLey Foon Tan 332*508791a0SLey Foon Tan case CLKMGR_CLKSRC_INTOSC: 333*508791a0SLey Foon Tan clock = cm_get_intosc_clk_hz(); 334*508791a0SLey Foon Tan break; 335*508791a0SLey Foon Tan 336*508791a0SLey Foon Tan case CLKMGR_CLKSRC_FPGA: 337*508791a0SLey Foon Tan clock = cm_get_fpga_clk_hz(); 338*508791a0SLey Foon Tan break; 339*508791a0SLey Foon Tan } 340*508791a0SLey Foon Tan return clock / 4; 341*508791a0SLey Foon Tan } 342*508791a0SLey Foon Tan 343*508791a0SLey Foon Tan unsigned int cm_get_l4_sp_clk_hz(void) 344*508791a0SLey Foon Tan { 345*508791a0SLey Foon Tan u32 clock = cm_get_l3_main_clk_hz(); 346*508791a0SLey Foon Tan 347*508791a0SLey Foon Tan clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >> 348*508791a0SLey Foon Tan CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK)); 349*508791a0SLey Foon Tan return clock; 350*508791a0SLey Foon Tan } 351*508791a0SLey Foon Tan 352*508791a0SLey Foon Tan unsigned int cm_get_qspi_controller_clk_hz(void) 353*508791a0SLey Foon Tan { 354*508791a0SLey Foon Tan return readl(&sysmgr_regs->boot_scratch_cold0); 355*508791a0SLey Foon Tan } 356*508791a0SLey Foon Tan 357*508791a0SLey Foon Tan unsigned int cm_get_spi_controller_clk_hz(void) 358*508791a0SLey Foon Tan { 359*508791a0SLey Foon Tan u32 clock = cm_get_l3_main_clk_hz(); 360*508791a0SLey Foon Tan 361*508791a0SLey Foon Tan clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >> 362*508791a0SLey Foon Tan CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK)); 363*508791a0SLey Foon Tan return clock; 364*508791a0SLey Foon Tan } 365*508791a0SLey Foon Tan 366*508791a0SLey Foon Tan unsigned int cm_get_l4_sys_free_clk_hz(void) 367*508791a0SLey Foon Tan { 368*508791a0SLey Foon Tan return cm_get_l3_main_clk_hz() / 4; 369*508791a0SLey Foon Tan } 370*508791a0SLey Foon Tan 371*508791a0SLey Foon Tan void cm_print_clock_quick_summary(void) 372*508791a0SLey Foon Tan { 373*508791a0SLey Foon Tan printf("MPU %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000)); 374*508791a0SLey Foon Tan printf("L3 main %d kHz\n", cm_get_l3_main_clk_hz() / 1000); 375*508791a0SLey Foon Tan printf("Main VCO %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000)); 376*508791a0SLey Foon Tan printf("Per VCO %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000)); 377*508791a0SLey Foon Tan printf("EOSC1 %d kHz\n", cm_get_osc_clk_hz() / 1000); 378*508791a0SLey Foon Tan printf("HPS MMC %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); 379*508791a0SLey Foon Tan printf("UART %d kHz\n", cm_get_l4_sp_clk_hz() / 1000); 380*508791a0SLey Foon Tan } 381