]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv7/bcm235xx/clk-bcm235xx.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / arch / arm / cpu / armv7 / bcm235xx / clk-bcm235xx.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Broadcom Corporation.
4  */
5
6 /*
7  *
8  * bcm235xx-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 = 1,
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         .lvm_en_offset = 0x00000034,
303         .freq_id = 2,
304         .freq_tbl = slave_axi_freq_tbl,
305 };
306
307 #ifdef CONFIG_BCM_SF2_ETH
308 static struct ccu_clock esub_ccu_clk = {
309         .clk = {
310                 .name = "esub_ccu_clk",
311                 .ops = &ccu_clk_ops,
312                 .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR,
313         },
314         .num_policy_masks = 1,
315         .policy_freq_offset = 0x00000008,
316         .freq_bit_shift = 8,
317         .policy_ctl_offset = 0x0000000c,
318         .policy0_mask_offset = 0x00000010,
319         .policy1_mask_offset = 0x00000014,
320         .policy2_mask_offset = 0x00000018,
321         .policy3_mask_offset = 0x0000001c,
322         .lvm_en_offset = 0x00000034,
323         .freq_id = 2,
324         .freq_tbl = esub_freq_tbl,
325 };
326 #endif
327
328 /*
329  * Bus clocks
330  */
331
332 /* KPM bus clocks */
333 static struct bus_clock usb_otg_ahb_clk = {
334         .clk = {
335                 .name = "usb_otg_ahb_clk",
336                 .parent = &kpm_ccu_clk.clk,
337                 .ops = &bus_clk_ops,
338                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
339         },
340         .freq_tbl = master_ahb_freq_tbl,
341         .data = &usb_otg_ahb_data,
342 };
343
344 static struct bus_clock sdio1_ahb_clk = {
345         .clk = {
346                 .name = "sdio1_ahb_clk",
347                 .parent = &kpm_ccu_clk.clk,
348                 .ops = &bus_clk_ops,
349                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
350         },
351         .freq_tbl = master_ahb_freq_tbl,
352         .data = &sdio1_ahb_data,
353 };
354
355 static struct bus_clock sdio2_ahb_clk = {
356         .clk = {
357                 .name = "sdio2_ahb_clk",
358                 .parent = &kpm_ccu_clk.clk,
359                 .ops = &bus_clk_ops,
360                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
361         },
362         .freq_tbl = master_ahb_freq_tbl,
363         .data = &sdio2_ahb_data,
364 };
365
366 static struct bus_clock sdio3_ahb_clk = {
367         .clk = {
368                 .name = "sdio3_ahb_clk",
369                 .parent = &kpm_ccu_clk.clk,
370                 .ops = &bus_clk_ops,
371                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
372         },
373         .freq_tbl = master_ahb_freq_tbl,
374         .data = &sdio3_ahb_data,
375 };
376
377 static struct bus_clock sdio4_ahb_clk = {
378         .clk = {
379                 .name = "sdio4_ahb_clk",
380                 .parent = &kpm_ccu_clk.clk,
381                 .ops = &bus_clk_ops,
382                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
383         },
384         .freq_tbl = master_ahb_freq_tbl,
385         .data = &sdio4_ahb_data,
386 };
387
388 static struct bus_clock bsc1_apb_clk = {
389         .clk = {
390                 .name = "bsc1_apb_clk",
391                 .parent = &kps_ccu_clk.clk,
392                 .ops = &bus_clk_ops,
393                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
394         },
395         .freq_tbl = slave_apb_freq_tbl,
396         .data = &bsc1_apb_data,
397 };
398
399 static struct bus_clock bsc2_apb_clk = {
400         .clk = {
401                 .name = "bsc2_apb_clk",
402                 .parent = &kps_ccu_clk.clk,
403                 .ops = &bus_clk_ops,
404                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
405                 },
406         .freq_tbl = slave_apb_freq_tbl,
407         .data = &bsc2_apb_data,
408 };
409
410 static struct bus_clock bsc3_apb_clk = {
411         .clk = {
412                 .name = "bsc3_apb_clk",
413                 .parent = &kps_ccu_clk.clk,
414                 .ops = &bus_clk_ops,
415                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
416                 },
417         .freq_tbl = slave_apb_freq_tbl,
418         .data = &bsc3_apb_data,
419 };
420
421 /* KPM peripheral */
422 static struct peri_clock sdio1_clk = {
423         .clk = {
424                 .name = "sdio1_clk",
425                 .parent = &ref_52m.clk,
426                 .ops = &peri_clk_ops,
427                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
428         },
429         .data = &sdio1_data,
430 };
431
432 static struct peri_clock sdio2_clk = {
433         .clk = {
434                 .name = "sdio2_clk",
435                 .parent = &ref_52m.clk,
436                 .ops = &peri_clk_ops,
437                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
438         },
439         .data = &sdio2_data,
440 };
441
442 static struct peri_clock sdio3_clk = {
443         .clk = {
444                 .name = "sdio3_clk",
445                 .parent = &ref_52m.clk,
446                 .ops = &peri_clk_ops,
447                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
448         },
449         .data = &sdio3_data,
450 };
451
452 static struct peri_clock sdio4_clk = {
453         .clk = {
454                 .name = "sdio4_clk",
455                 .parent = &ref_52m.clk,
456                 .ops = &peri_clk_ops,
457                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
458         },
459         .data = &sdio4_data,
460 };
461
462 static struct peri_clock sdio1_sleep_clk = {
463         .clk = {
464                 .name = "sdio1_sleep_clk",
465                 .parent = &kpm_ccu_clk.clk,
466                 .ops = &bus_clk_ops,
467                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
468         },
469         .data = &sdio1_sleep_data,
470 };
471
472 static struct peri_clock sdio2_sleep_clk = {
473         .clk = {
474                 .name = "sdio2_sleep_clk",
475                 .parent = &kpm_ccu_clk.clk,
476                 .ops = &bus_clk_ops,
477                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
478         },
479         .data = &sdio2_sleep_data,
480 };
481
482 static struct peri_clock sdio3_sleep_clk = {
483         .clk = {
484                 .name = "sdio3_sleep_clk",
485                 .parent = &kpm_ccu_clk.clk,
486                 .ops = &bus_clk_ops,
487                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
488         },
489         .data = &sdio3_sleep_data,
490 };
491
492 static struct peri_clock sdio4_sleep_clk = {
493         .clk = {
494                 .name = "sdio4_sleep_clk",
495                 .parent = &kpm_ccu_clk.clk,
496                 .ops = &bus_clk_ops,
497                 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
498         },
499         .data = &sdio4_sleep_data,
500 };
501
502 /* KPS peripheral clock */
503 static struct peri_clock bsc1_clk = {
504         .clk = {
505                 .name = "bsc1_clk",
506                 .parent = &ref_13m.clk,
507                 .rate = 13 * CLOCK_1M,
508                 .div = 1,
509                 .ops = &peri_clk_ops,
510                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
511         },
512         .data = &bsc1_data,
513 };
514
515 static struct peri_clock bsc2_clk = {
516         .clk = {
517                 .name = "bsc2_clk",
518                 .parent = &ref_13m.clk,
519                 .rate = 13 * CLOCK_1M,
520                 .div = 1,
521                 .ops = &peri_clk_ops,
522                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
523         },
524         .data = &bsc2_data,
525 };
526
527 static struct peri_clock bsc3_clk = {
528         .clk = {
529                 .name = "bsc3_clk",
530                 .parent = &ref_13m.clk,
531                 .rate = 13 * CLOCK_1M,
532                 .div = 1,
533                 .ops = &peri_clk_ops,
534                 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
535         },
536         .data = &bsc3_data,
537 };
538
539 /* public table for registering clocks */
540 struct clk_lookup arch_clk_tbl[] = {
541         /* Peripheral clocks */
542         CLK_LK(sdio1),
543         CLK_LK(sdio2),
544         CLK_LK(sdio3),
545         CLK_LK(sdio4),
546         CLK_LK(sdio1_sleep),
547         CLK_LK(sdio2_sleep),
548         CLK_LK(sdio3_sleep),
549         CLK_LK(sdio4_sleep),
550         CLK_LK(bsc1),
551         CLK_LK(bsc2),
552         CLK_LK(bsc3),
553         /* Bus clocks */
554         CLK_LK(usb_otg_ahb),
555         CLK_LK(sdio1_ahb),
556         CLK_LK(sdio2_ahb),
557         CLK_LK(sdio3_ahb),
558         CLK_LK(sdio4_ahb),
559         CLK_LK(bsc1_apb),
560         CLK_LK(bsc2_apb),
561         CLK_LK(bsc3_apb),
562 #ifdef CONFIG_BCM_SF2_ETH
563         CLK_LK(esub_ccu),
564 #endif
565 };
566
567 /* public array size */
568 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);