arm: am57xx: cl-som-am57x: remove board support
[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 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 }