1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
9 #include <asm/arch/clock_manager.h>
10 #include <asm/arch/handoff_s10.h>
11 #include <asm/arch/system_manager.h>
13 DECLARE_GLOBAL_DATA_PTR;
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;
21 * function to write the bypass register which requires a poll of the
24 static void cm_write_bypass_mainpll(u32 val)
26 writel(val, &clock_manager_base->main_pll.bypass);
30 static void cm_write_bypass_perpll(u32 val)
32 writel(val, &clock_manager_base->per_pll.bypass);
36 /* function to write the ctrl register which requires a poll of the busy bit */
37 static void cm_write_ctrl(u32 val)
39 writel(val, &clock_manager_base->ctrl);
44 * Setup clocks while making no assumptions about previous state of the clocks.
46 void cm_basic_init(const struct cm_config * const cfg)
48 u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib;
53 /* Put all plls in bypass */
54 cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL);
55 cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL);
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 -
65 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
66 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
67 CLKMGR_VCOCALIB_MSCNT_OFFSET);
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);
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 -
87 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
88 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
89 CLKMGR_VCOCALIB_MSCNT_OFFSET);
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);
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);
107 #define LOCKED_MASK \
108 (CLKMGR_STAT_MAINPLL_LOCKED | \
109 CLKMGR_STAT_PERPLL_LOCKED)
111 cm_wait_for_lock(LOCKED_MASK);
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
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);
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);
156 /* Take all PLLs out of bypass */
157 cm_write_bypass_mainpll(0);
158 cm_write_bypass_perpll(0);
160 /* clear safe mode / out of boot mode */
161 cm_write_ctrl(readl(&clock_manager_base->ctrl)
162 & ~(CLKMGR_CTRL_SAFEMODE));
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);
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);
173 static unsigned long cm_get_main_vco_clk_hz(void)
175 unsigned long fref, refdiv, mdiv, reg, vco;
177 reg = readl(&clock_manager_base->main_pll.pllglob);
179 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
180 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
182 case CLKMGR_VCO_PSRC_EOSC1:
183 fref = cm_get_osc_clk_hz();
185 case CLKMGR_VCO_PSRC_INTOSC:
186 fref = cm_get_intosc_clk_hz();
188 case CLKMGR_VCO_PSRC_F2S:
189 fref = cm_get_fpga_clk_hz();
193 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
194 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
196 reg = readl(&clock_manager_base->main_pll.fdbck);
197 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
200 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
204 static unsigned long cm_get_per_vco_clk_hz(void)
206 unsigned long fref, refdiv, mdiv, reg, vco;
208 reg = readl(&clock_manager_base->per_pll.pllglob);
210 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
211 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
213 case CLKMGR_VCO_PSRC_EOSC1:
214 fref = cm_get_osc_clk_hz();
216 case CLKMGR_VCO_PSRC_INTOSC:
217 fref = cm_get_intosc_clk_hz();
219 case CLKMGR_VCO_PSRC_F2S:
220 fref = cm_get_fpga_clk_hz();
224 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
225 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
227 reg = readl(&clock_manager_base->per_pll.fdbck);
228 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
231 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
235 unsigned long cm_get_mpu_clk_hz(void)
237 unsigned long clock = readl(&clock_manager_base->main_pll.mpuclk);
239 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
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);
248 case CLKMGR_CLKSRC_PER:
249 clock = cm_get_per_vco_clk_hz();
250 clock /= (readl(&clock_manager_base->per_pll.pllc0) &
254 case CLKMGR_CLKSRC_OSC1:
255 clock = cm_get_osc_clk_hz();
258 case CLKMGR_CLKSRC_INTOSC:
259 clock = cm_get_intosc_clk_hz();
262 case CLKMGR_CLKSRC_FPGA:
263 clock = cm_get_fpga_clk_hz();
267 clock /= 1 + (readl(&clock_manager_base->main_pll.mpuclk) &
272 unsigned int cm_get_l3_main_clk_hz(void)
274 u32 clock = readl(&clock_manager_base->main_pll.nocclk);
276 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
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);
285 case CLKMGR_CLKSRC_PER:
286 clock = cm_get_per_vco_clk_hz();
287 clock /= (readl(&clock_manager_base->per_pll.pllc1) &
291 case CLKMGR_CLKSRC_OSC1:
292 clock = cm_get_osc_clk_hz();
295 case CLKMGR_CLKSRC_INTOSC:
296 clock = cm_get_intosc_clk_hz();
299 case CLKMGR_CLKSRC_FPGA:
300 clock = cm_get_fpga_clk_hz();
304 clock /= 1 + (readl(&clock_manager_base->main_pll.nocclk) &
309 unsigned int cm_get_mmc_controller_clk_hz(void)
311 u32 clock = readl(&clock_manager_base->per_pll.cntr6clk);
313 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
316 case CLKMGR_CLKSRC_MAIN:
317 clock = cm_get_l3_main_clk_hz();
318 clock /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) &
322 case CLKMGR_CLKSRC_PER:
323 clock = cm_get_l3_main_clk_hz();
324 clock /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) &
328 case CLKMGR_CLKSRC_OSC1:
329 clock = cm_get_osc_clk_hz();
332 case CLKMGR_CLKSRC_INTOSC:
333 clock = cm_get_intosc_clk_hz();
336 case CLKMGR_CLKSRC_FPGA:
337 clock = cm_get_fpga_clk_hz();
343 unsigned int cm_get_l4_sp_clk_hz(void)
345 u32 clock = cm_get_l3_main_clk_hz();
347 clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >>
348 CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
352 unsigned int cm_get_qspi_controller_clk_hz(void)
354 return readl(&sysmgr_regs->boot_scratch_cold0);
357 unsigned int cm_get_spi_controller_clk_hz(void)
359 u32 clock = cm_get_l3_main_clk_hz();
361 clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >>
362 CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK));
366 unsigned int cm_get_l4_sys_free_clk_hz(void)
368 return cm_get_l3_main_clk_hz() / 4;
371 void cm_print_clock_quick_summary(void)
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);