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