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