• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
refclk_str_to_clk(const char * name)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);
573