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