Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / arch / arm / cpu / armv7 / bcm281xx / clk-bcm281xx.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Broadcom Corporation.
4  */
5
6 /*
7  *
8  * bcm281xx-specific clock tables
9  *
10  */
11
12 #include <common.h>
13 #include <asm/io.h>
14 #include <linux/errno.h>
15 #include <asm/arch/sysmap.h>
16 #include <asm/kona-common/clk.h>
17 #include "clk-core.h"
18
19 #define CLOCK_1K                1000
20 #define CLOCK_1M                (CLOCK_1K * 1000)
21
22 /* declare a reference clock */
23 #define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \
24 static struct refclk clk_name = { \
25         .clk    =       { \
26                 .name   =       #clk_name, \
27                 .parent =       clk_parent, \
28                 .rate   =       clk_rate, \
29                 .div    =       clk_div, \
30                 .ops    =       &ref_clk_ops, \
31         }, \
32 }
33
34 /*
35  * Reference clocks
36  */
37
38 /* Declare a list of reference clocks */
39 DECLARE_REF_CLK(ref_crystal,    0,              26  * CLOCK_1M, 1);
40 DECLARE_REF_CLK(var_96m,        0,              96  * CLOCK_1M, 1);
41 DECLARE_REF_CLK(ref_96m,        0,              96  * CLOCK_1M, 1);
42 DECLARE_REF_CLK(ref_312m,       0,              312 * CLOCK_1M, 0);
43 DECLARE_REF_CLK(ref_104m,       &ref_312m.clk,  104 * CLOCK_1M, 3);
44 DECLARE_REF_CLK(ref_52m,        &ref_104m.clk,  52  * CLOCK_1M, 2);
45 DECLARE_REF_CLK(ref_13m,        &ref_52m.clk,   13  * CLOCK_1M, 4);
46 DECLARE_REF_CLK(var_312m,       0,              312 * CLOCK_1M, 0);
47 DECLARE_REF_CLK(var_104m,       &var_312m.clk,  104 * CLOCK_1M, 3);
48 DECLARE_REF_CLK(var_52m,        &var_104m.clk,  52  * CLOCK_1M, 2);
49 DECLARE_REF_CLK(var_13m,        &var_52m.clk,   13  * CLOCK_1M, 4);
50
51 struct refclk_lkup {
52         struct refclk *procclk;
53         const char *name;
54 };
55
56 /* Lookup table for string to clk tranlation */
57 #define MKSTR(x) {&x, #x}
58 static struct refclk_lkup refclk_str_tbl[] = {
59         MKSTR(ref_crystal), MKSTR(var_96m), MKSTR(ref_96m),
60         MKSTR(ref_312m), MKSTR(ref_104m), MKSTR(ref_52m),
61         MKSTR(ref_13m), MKSTR(var_312m), MKSTR(var_104m),
62         MKSTR(var_52m), MKSTR(var_13m),
63 };
64
65 int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]);
66
67 /* convert ref clock string to clock structure pointer */
68 struct refclk *refclk_str_to_clk(const char *name)
69 {
70         int i;
71         struct refclk_lkup *tblp = refclk_str_tbl;
72         for (i = 0; i < refclk_entries; i++, tblp++) {
73                 if (!(strcmp(name, tblp->name)))
74                         return tblp->procclk;
75         }
76         return NULL;
77 }
78
79 /* frequency tables indexed by freq_id */
80 unsigned long master_axi_freq_tbl[8] = {
81         26 * CLOCK_1M,
82         52 * CLOCK_1M,
83         104 * CLOCK_1M,
84         156 * CLOCK_1M,
85         156 * CLOCK_1M,
86         208 * CLOCK_1M,
87         312 * CLOCK_1M,
88         312 * CLOCK_1M
89 };
90
91 unsigned long master_ahb_freq_tbl[8] = {
92         26 * CLOCK_1M,
93         52 * CLOCK_1M,
94         52 * CLOCK_1M,
95         52 * CLOCK_1M,
96         78 * CLOCK_1M,
97         104 * CLOCK_1M,
98         104 * CLOCK_1M,
99         156 * CLOCK_1M
100 };
101
102 unsigned long slave_axi_freq_tbl[8] = {
103         26 * CLOCK_1M,
104         52 * CLOCK_1M,
105         78 * CLOCK_1M,
106         104 * CLOCK_1M,
107         156 * CLOCK_1M,
108         156 * CLOCK_1M
109 };
110
111 unsigned long slave_apb_freq_tbl[8] = {
112         26 * CLOCK_1M,
113         26 * CLOCK_1M,
114         39 * CLOCK_1M,
115         52 * CLOCK_1M,
116         52 * CLOCK_1M,
117         78 * CLOCK_1M
118 };
119
120 unsigned long esub_freq_tbl[8] = {
121         78 * CLOCK_1M,
122         156 * CLOCK_1M,
123         156 * CLOCK_1M,
124         156 * CLOCK_1M,
125         208 * CLOCK_1M,
126         208 * CLOCK_1M,
127         208 * CLOCK_1M
128 };
129
130 static struct bus_clk_data bsc1_apb_data = {
131         .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1),
132 };
133
134 static struct bus_clk_data bsc2_apb_data = {
135         .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1),
136 };
137
138 static struct bus_clk_data bsc3_apb_data = {
139         .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1),
140 };
141
142 /* * Master CCU clocks */
143 static struct peri_clk_data sdio1_data = {
144         .gate           = HW_SW_GATE(0x0358, 18, 2, 3),
145         .clocks         = CLOCKS("ref_crystal",
146                                  "var_52m",
147                                  "ref_52m",
148                                  "var_96m",
149                                  "ref_96m"),
150         .sel            = SELECTOR(0x0a28, 0, 3),
151         .div            = DIVIDER(0x0a28, 4, 14),
152         .trig           = TRIGGER(0x0afc, 9),
153 };
154
155 static struct peri_clk_data sdio2_data = {
156         .gate           = HW_SW_GATE(0x035c, 18, 2, 3),
157         .clocks         = CLOCKS("ref_crystal",
158                                  "var_52m",
159                                  "ref_52m",
160                                  "var_96m",
161                                  "ref_96m"),
162         .sel            = SELECTOR(0x0a2c, 0, 3),
163         .div            = DIVIDER(0x0a2c, 4, 14),
164         .trig           = TRIGGER(0x0afc, 10),
165 };
166
167 static struct peri_clk_data sdio3_data = {
168         .gate           = HW_SW_GATE(0x0364, 18, 2, 3),
169         .clocks         = CLOCKS("ref_crystal",
170                                  "var_52m",
171                                  "ref_52m",
172                                  "var_96m",
173                                  "ref_96m"),
174         .sel            = SELECTOR(0x0a34, 0, 3),
175         .div            = DIVIDER(0x0a34, 4, 14),
176         .trig           = TRIGGER(0x0afc, 12),
177 };
178
179 static struct peri_clk_data sdio4_data = {
180         .gate           = HW_SW_GATE(0x0360, 18, 2, 3),
181         .clocks         = CLOCKS("ref_crystal",
182                                  "var_52m",
183                                  "ref_52m",
184                                  "var_96m",
185                                  "ref_96m"),
186         .sel            = SELECTOR(0x0a30, 0, 3),
187         .div            = DIVIDER(0x0a30, 4, 14),
188         .trig           = TRIGGER(0x0afc, 11),
189 };
190
191 static struct peri_clk_data sdio1_sleep_data = {
192         .clocks         = CLOCKS("ref_32k"),
193         .gate           = SW_ONLY_GATE(0x0358, 20, 4),
194 };
195
196 static struct peri_clk_data sdio2_sleep_data = {
197         .clocks         = CLOCKS("ref_32k"),
198         .gate           = SW_ONLY_GATE(0x035c, 20, 4),
199 };
200
201 static struct peri_clk_data sdio3_sleep_data = {
202         .clocks         = CLOCKS("ref_32k"),
203         .gate           = SW_ONLY_GATE(0x0364, 20, 4),
204 };
205
206 static struct peri_clk_data sdio4_sleep_data = {
207         .clocks         = CLOCKS("ref_32k"),
208         .gate           = SW_ONLY_GATE(0x0360, 20, 4),
209 };
210
211 static struct bus_clk_data usb_otg_ahb_data = {
212         .gate           = HW_SW_GATE_AUTO(0x0348, 16, 0, 1),
213 };
214
215 static struct bus_clk_data sdio1_ahb_data = {
216         .gate           = HW_SW_GATE_AUTO(0x0358, 16, 0, 1),
217 };
218
219 static struct bus_clk_data sdio2_ahb_data = {
220         .gate           = HW_SW_GATE_AUTO(0x035c, 16, 0, 1),
221 };
222
223 static struct bus_clk_data sdio3_ahb_data = {
224         .gate           = HW_SW_GATE_AUTO(0x0364, 16, 0, 1),
225 };
226
227 static struct bus_clk_data sdio4_ahb_data = {
228         .gate           = HW_SW_GATE_AUTO(0x0360, 16, 0, 1),
229 };
230
231 /* * Slave CCU clocks */
232 static struct peri_clk_data bsc1_data = {
233         .gate           = HW_SW_GATE(0x0458, 18, 2, 3),
234         .clocks         = CLOCKS("ref_crystal",
235                                  "var_104m",
236                                  "ref_104m",
237                                  "var_13m",
238                                  "ref_13m"),
239         .sel            = SELECTOR(0x0a64, 0, 3),
240         .trig           = TRIGGER(0x0afc, 23),
241 };
242
243 static struct peri_clk_data bsc2_data = {
244         .gate           = HW_SW_GATE(0x045c, 18, 2, 3),
245         .clocks         = CLOCKS("ref_crystal",
246                                  "var_104m",
247                                  "ref_104m",
248                                  "var_13m",
249                                  "ref_13m"),
250         .sel            = SELECTOR(0x0a68, 0, 3),
251         .trig           = TRIGGER(0x0afc, 24),
252 };
253
254 static struct peri_clk_data bsc3_data = {
255         .gate           = HW_SW_GATE(0x0484, 18, 2, 3),
256         .clocks         = CLOCKS("ref_crystal",
257                                  "var_104m",
258                                  "ref_104m",
259                                  "var_13m",
260                                  "ref_13m"),
261         .sel            = SELECTOR(0x0a84, 0, 3),
262         .trig           = TRIGGER(0x0b00, 2),
263 };
264
265 /*
266  * CCU clocks
267  */
268
269 static struct ccu_clock kpm_ccu_clk = {
270         .clk = {
271                 .name = "kpm_ccu_clk",
272                 .ops = &ccu_clk_ops,
273                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
274         },
275         .num_policy_masks = 1,
276         .policy_freq_offset = 0x00000008,
277         .freq_bit_shift = 8,
278         .policy_ctl_offset = 0x0000000c,
279         .policy0_mask_offset = 0x00000010,
280         .policy1_mask_offset = 0x00000014,
281         .policy2_mask_offset = 0x00000018,
282         .policy3_mask_offset = 0x0000001c,
283         .lvm_en_offset = 0x00000034,
284         .freq_id = 2,
285         .freq_tbl = master_axi_freq_tbl,
286 };
287
288 static struct ccu_clock kps_ccu_clk = {
289         .clk = {
290                 .name = "kps_ccu_clk",
291                 .ops = &ccu_clk_ops,
292                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
293         },
294         .num_policy_masks = 2,
295         .policy_freq_offset = 0x00000008,
296         .freq_bit_shift = 8,
297         .policy_ctl_offset = 0x0000000c,
298         .policy0_mask_offset = 0x00000010,
299         .policy1_mask_offset = 0x00000014,
300         .policy2_mask_offset = 0x00000018,
301         .policy3_mask_offset = 0x0000001c,
302         .policy0_mask2_offset = 0x00000048,
303         .policy1_mask2_offset = 0x0000004c,
304         .policy2_mask2_offset = 0x00000050,
305         .policy3_mask2_offset = 0x00000054,
306         .lvm_en_offset = 0x00000034,
307         .freq_id = 2,
308         .freq_tbl = slave_axi_freq_tbl,
309 };
310
311 #ifdef CONFIG_BCM_SF2_ETH
312 static struct ccu_clock esub_ccu_clk = {
313         .clk = {
314                 .name = "esub_ccu_clk",
315                 .ops = &ccu_clk_ops,
316                 .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR,
317         },
318         .num_policy_masks = 1,
319         .policy_freq_offset = 0x00000008,
320         .freq_bit_shift = 8,
321         .policy_ctl_offset = 0x0000000c,
322         .policy0_mask_offset = 0x00000010,
323         .policy1_mask_offset = 0x00000014,
324         .policy2_mask_offset = 0x00000018,
325         .policy3_mask_offset = 0x0000001c,
326         .lvm_en_offset = 0x00000034,
327         .freq_id = 2,
328         .freq_tbl = esub_freq_tbl,
329 };
330 #endif
331
332 /*
333  * Bus clocks
334  */
335
336 /* KPM bus clocks */
337 static struct bus_clock usb_otg_ahb_clk = {
338         .clk = {
339                 .name = "usb_otg_ahb_clk",
340                 .parent = &kpm_ccu_clk.clk,
341                 .ops = &bus_clk_ops,
342                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
343         },
344         .freq_tbl = master_ahb_freq_tbl,
345         .data = &usb_otg_ahb_data,
346 };
347
348 static struct bus_clock sdio1_ahb_clk = {
349         .clk = {
350                 .name = "sdio1_ahb_clk",
351                 .parent = &kpm_ccu_clk.clk,
352                 .ops = &bus_clk_ops,
353                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
354         },
355         .freq_tbl = master_ahb_freq_tbl,
356         .data = &sdio1_ahb_data,
357 };
358
359 static struct bus_clock sdio2_ahb_clk = {
360         .clk = {
361                 .name = "sdio2_ahb_clk",
362                 .parent = &kpm_ccu_clk.clk,
363                 .ops = &bus_clk_ops,
364                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
365         },
366         .freq_tbl = master_ahb_freq_tbl,
367         .data = &sdio2_ahb_data,
368 };
369
370 static struct bus_clock sdio3_ahb_clk = {
371         .clk = {
372                 .name = "sdio3_ahb_clk",
373                 .parent = &kpm_ccu_clk.clk,
374                 .ops = &bus_clk_ops,
375                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
376         },
377         .freq_tbl = master_ahb_freq_tbl,
378         .data = &sdio3_ahb_data,
379 };
380
381 static struct bus_clock sdio4_ahb_clk = {
382         .clk = {
383                 .name = "sdio4_ahb_clk",
384                 .parent = &kpm_ccu_clk.clk,
385                 .ops = &bus_clk_ops,
386                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
387         },
388         .freq_tbl = master_ahb_freq_tbl,
389         .data = &sdio4_ahb_data,
390 };
391
392 static struct bus_clock bsc1_apb_clk = {
393         .clk = {
394                 .name = "bsc1_apb_clk",
395                 .parent = &kps_ccu_clk.clk,
396                 .ops = &bus_clk_ops,
397                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
398         },
399         .freq_tbl = slave_apb_freq_tbl,
400         .data = &bsc1_apb_data,
401 };
402
403 static struct bus_clock bsc2_apb_clk = {
404         .clk = {
405                 .name = "bsc2_apb_clk",
406                 .parent = &kps_ccu_clk.clk,
407                 .ops = &bus_clk_ops,
408                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
409                 },
410         .freq_tbl = slave_apb_freq_tbl,
411         .data = &bsc2_apb_data,
412 };
413
414 static struct bus_clock bsc3_apb_clk = {
415         .clk = {
416                 .name = "bsc3_apb_clk",
417                 .parent = &kps_ccu_clk.clk,
418                 .ops = &bus_clk_ops,
419                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
420                 },
421         .freq_tbl = slave_apb_freq_tbl,
422         .data = &bsc3_apb_data,
423 };
424
425 /* KPM peripheral */
426 static struct peri_clock sdio1_clk = {
427         .clk = {
428                 .name = "sdio1_clk",
429                 .parent = &ref_52m.clk,
430                 .ops = &peri_clk_ops,
431                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
432         },
433         .data = &sdio1_data,
434 };
435
436 static struct peri_clock sdio2_clk = {
437         .clk = {
438                 .name = "sdio2_clk",
439                 .parent = &ref_52m.clk,
440                 .ops = &peri_clk_ops,
441                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
442         },
443         .data = &sdio2_data,
444 };
445
446 static struct peri_clock sdio3_clk = {
447         .clk = {
448                 .name = "sdio3_clk",
449                 .parent = &ref_52m.clk,
450                 .ops = &peri_clk_ops,
451                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
452         },
453         .data = &sdio3_data,
454 };
455
456 static struct peri_clock sdio4_clk = {
457         .clk = {
458                 .name = "sdio4_clk",
459                 .parent = &ref_52m.clk,
460                 .ops = &peri_clk_ops,
461                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
462         },
463         .data = &sdio4_data,
464 };
465
466 static struct peri_clock sdio1_sleep_clk = {
467         .clk = {
468                 .name = "sdio1_sleep_clk",
469                 .parent = &kpm_ccu_clk.clk,
470                 .ops = &bus_clk_ops,
471                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
472         },
473         .data = &sdio1_sleep_data,
474 };
475
476 static struct peri_clock sdio2_sleep_clk = {
477         .clk = {
478                 .name = "sdio2_sleep_clk",
479                 .parent = &kpm_ccu_clk.clk,
480                 .ops = &bus_clk_ops,
481                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
482         },
483         .data = &sdio2_sleep_data,
484 };
485
486 static struct peri_clock sdio3_sleep_clk = {
487         .clk = {
488                 .name = "sdio3_sleep_clk",
489                 .parent = &kpm_ccu_clk.clk,
490                 .ops = &bus_clk_ops,
491                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
492         },
493         .data = &sdio3_sleep_data,
494 };
495
496 static struct peri_clock sdio4_sleep_clk = {
497         .clk = {
498                 .name = "sdio4_sleep_clk",
499                 .parent = &kpm_ccu_clk.clk,
500                 .ops = &bus_clk_ops,
501                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
502         },
503         .data = &sdio4_sleep_data,
504 };
505
506 /* KPS peripheral clock */
507 static struct peri_clock bsc1_clk = {
508         .clk = {
509                 .name = "bsc1_clk",
510                 .parent = &ref_13m.clk,
511                 .rate = 13 * CLOCK_1M,
512                 .div = 1,
513                 .ops = &peri_clk_ops,
514                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
515         },
516         .data = &bsc1_data,
517 };
518
519 static struct peri_clock bsc2_clk = {
520         .clk = {
521                 .name = "bsc2_clk",
522                 .parent = &ref_13m.clk,
523                 .rate = 13 * CLOCK_1M,
524                 .div = 1,
525                 .ops = &peri_clk_ops,
526                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
527         },
528         .data = &bsc2_data,
529 };
530
531 static struct peri_clock bsc3_clk = {
532         .clk = {
533                 .name = "bsc3_clk",
534                 .parent = &ref_13m.clk,
535                 .rate = 13 * CLOCK_1M,
536                 .div = 1,
537                 .ops = &peri_clk_ops,
538                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
539         },
540         .data = &bsc3_data,
541 };
542
543 /* public table for registering clocks */
544 struct clk_lookup arch_clk_tbl[] = {
545         /* Peripheral clocks */
546         CLK_LK(sdio1),
547         CLK_LK(sdio2),
548         CLK_LK(sdio3),
549         CLK_LK(sdio4),
550         CLK_LK(sdio1_sleep),
551         CLK_LK(sdio2_sleep),
552         CLK_LK(sdio3_sleep),
553         CLK_LK(sdio4_sleep),
554         CLK_LK(bsc1),
555         CLK_LK(bsc2),
556         CLK_LK(bsc3),
557         /* Bus clocks */
558         CLK_LK(usb_otg_ahb),
559         CLK_LK(sdio1_ahb),
560         CLK_LK(sdio2_ahb),
561         CLK_LK(sdio3_ahb),
562         CLK_LK(sdio4_ahb),
563         CLK_LK(bsc1_apb),
564         CLK_LK(bsc2_apb),
565         CLK_LK(bsc3_apb),
566 #ifdef CONFIG_BCM_SF2_ETH
567         CLK_LK(esub_ccu),
568 #endif
569 };
570
571 /* public array size */
572 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);