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