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