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 static struct bus_clk_data bsc1_apb_data = {
122 	.gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1),
123 };
124 
125 static struct bus_clk_data bsc2_apb_data = {
126 	.gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1),
127 };
128 
129 static struct bus_clk_data bsc3_apb_data = {
130 	.gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1),
131 };
132 
133 /* * Master CCU clocks */
134 static struct peri_clk_data sdio1_data = {
135 	.gate		= HW_SW_GATE(0x0358, 18, 2, 3),
136 	.clocks		= CLOCKS("ref_crystal",
137 				 "var_52m",
138 				 "ref_52m",
139 				 "var_96m",
140 				 "ref_96m"),
141 	.sel		= SELECTOR(0x0a28, 0, 3),
142 	.div		= DIVIDER(0x0a28, 4, 14),
143 	.trig		= TRIGGER(0x0afc, 9),
144 };
145 
146 static struct peri_clk_data sdio2_data = {
147 	.gate		= HW_SW_GATE(0x035c, 18, 2, 3),
148 	.clocks		= CLOCKS("ref_crystal",
149 				 "var_52m",
150 				 "ref_52m",
151 				 "var_96m",
152 				 "ref_96m"),
153 	.sel		= SELECTOR(0x0a2c, 0, 3),
154 	.div		= DIVIDER(0x0a2c, 4, 14),
155 	.trig		= TRIGGER(0x0afc, 10),
156 };
157 
158 static struct peri_clk_data sdio3_data = {
159 	.gate		= HW_SW_GATE(0x0364, 18, 2, 3),
160 	.clocks		= CLOCKS("ref_crystal",
161 				 "var_52m",
162 				 "ref_52m",
163 				 "var_96m",
164 				 "ref_96m"),
165 	.sel		= SELECTOR(0x0a34, 0, 3),
166 	.div		= DIVIDER(0x0a34, 4, 14),
167 	.trig		= TRIGGER(0x0afc, 12),
168 };
169 
170 static struct peri_clk_data sdio4_data = {
171 	.gate		= HW_SW_GATE(0x0360, 18, 2, 3),
172 	.clocks		= CLOCKS("ref_crystal",
173 				 "var_52m",
174 				 "ref_52m",
175 				 "var_96m",
176 				 "ref_96m"),
177 	.sel		= SELECTOR(0x0a30, 0, 3),
178 	.div		= DIVIDER(0x0a30, 4, 14),
179 	.trig		= TRIGGER(0x0afc, 11),
180 };
181 
182 static struct peri_clk_data sdio1_sleep_data = {
183 	.clocks		= CLOCKS("ref_32k"),
184 	.gate		= SW_ONLY_GATE(0x0358, 20, 4),
185 };
186 
187 static struct peri_clk_data sdio2_sleep_data = {
188 	.clocks		= CLOCKS("ref_32k"),
189 	.gate		= SW_ONLY_GATE(0x035c, 20, 4),
190 };
191 
192 static struct peri_clk_data sdio3_sleep_data = {
193 	.clocks		= CLOCKS("ref_32k"),
194 	.gate		= SW_ONLY_GATE(0x0364, 20, 4),
195 };
196 
197 static struct peri_clk_data sdio4_sleep_data = {
198 	.clocks		= CLOCKS("ref_32k"),
199 	.gate		= SW_ONLY_GATE(0x0360, 20, 4),
200 };
201 
202 static struct bus_clk_data sdio1_ahb_data = {
203 	.gate		= HW_SW_GATE_AUTO(0x0358, 16, 0, 1),
204 };
205 
206 static struct bus_clk_data sdio2_ahb_data = {
207 	.gate		= HW_SW_GATE_AUTO(0x035c, 16, 0, 1),
208 };
209 
210 static struct bus_clk_data sdio3_ahb_data = {
211 	.gate		= HW_SW_GATE_AUTO(0x0364, 16, 0, 1),
212 };
213 
214 static struct bus_clk_data sdio4_ahb_data = {
215 	.gate		= HW_SW_GATE_AUTO(0x0360, 16, 0, 1),
216 };
217 
218 /* * Slave CCU clocks */
219 static struct peri_clk_data bsc1_data = {
220 	.gate		= HW_SW_GATE(0x0458, 18, 2, 3),
221 	.clocks		= CLOCKS("ref_crystal",
222 				 "var_104m",
223 				 "ref_104m",
224 				 "var_13m",
225 				 "ref_13m"),
226 	.sel		= SELECTOR(0x0a64, 0, 3),
227 	.trig		= TRIGGER(0x0afc, 23),
228 };
229 
230 static struct peri_clk_data bsc2_data = {
231 	.gate		= HW_SW_GATE(0x045c, 18, 2, 3),
232 	.clocks		= CLOCKS("ref_crystal",
233 				 "var_104m",
234 				 "ref_104m",
235 				 "var_13m",
236 				 "ref_13m"),
237 	.sel		= SELECTOR(0x0a68, 0, 3),
238 	.trig		= TRIGGER(0x0afc, 24),
239 };
240 
241 static struct peri_clk_data bsc3_data = {
242 	.gate		= HW_SW_GATE(0x0484, 18, 2, 3),
243 	.clocks		= CLOCKS("ref_crystal",
244 				 "var_104m",
245 				 "ref_104m",
246 				 "var_13m",
247 				 "ref_13m"),
248 	.sel		= SELECTOR(0x0a84, 0, 3),
249 	.trig		= TRIGGER(0x0b00, 2),
250 };
251 
252 /*
253  * CCU clocks
254  */
255 
256 static struct ccu_clock kpm_ccu_clk = {
257 	.clk = {
258 		.name = "kpm_ccu_clk",
259 		.ops = &ccu_clk_ops,
260 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
261 	},
262 	.num_policy_masks = 1,
263 	.policy_freq_offset = 0x00000008,
264 	.freq_bit_shift = 8,
265 	.policy_ctl_offset = 0x0000000c,
266 	.policy0_mask_offset = 0x00000010,
267 	.policy1_mask_offset = 0x00000014,
268 	.policy2_mask_offset = 0x00000018,
269 	.policy3_mask_offset = 0x0000001c,
270 	.lvm_en_offset = 0x00000034,
271 	.freq_id = 2,
272 	.freq_tbl = master_axi_freq_tbl,
273 };
274 
275 static struct ccu_clock kps_ccu_clk = {
276 	.clk = {
277 		.name = "kps_ccu_clk",
278 		.ops = &ccu_clk_ops,
279 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
280 	},
281 	.num_policy_masks = 2,
282 	.policy_freq_offset = 0x00000008,
283 	.freq_bit_shift = 8,
284 	.policy_ctl_offset = 0x0000000c,
285 	.policy0_mask_offset = 0x00000010,
286 	.policy1_mask_offset = 0x00000014,
287 	.policy2_mask_offset = 0x00000018,
288 	.policy3_mask_offset = 0x0000001c,
289 	.policy0_mask2_offset = 0x00000048,
290 	.policy1_mask2_offset = 0x0000004c,
291 	.policy2_mask2_offset = 0x00000050,
292 	.policy3_mask2_offset = 0x00000054,
293 	.lvm_en_offset = 0x00000034,
294 	.freq_id = 2,
295 	.freq_tbl = slave_axi_freq_tbl,
296 };
297 
298 /*
299  * Bus clocks
300  */
301 
302 /* KPM bus clocks */
303 static struct bus_clock sdio1_ahb_clk = {
304 	.clk = {
305 		.name = "sdio1_ahb_clk",
306 		.parent = &kpm_ccu_clk.clk,
307 		.ops = &bus_clk_ops,
308 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
309 	},
310 	.freq_tbl = master_ahb_freq_tbl,
311 	.data = &sdio1_ahb_data,
312 };
313 
314 static struct bus_clock sdio2_ahb_clk = {
315 	.clk = {
316 		.name = "sdio2_ahb_clk",
317 		.parent = &kpm_ccu_clk.clk,
318 		.ops = &bus_clk_ops,
319 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
320 	},
321 	.freq_tbl = master_ahb_freq_tbl,
322 	.data = &sdio2_ahb_data,
323 };
324 
325 static struct bus_clock sdio3_ahb_clk = {
326 	.clk = {
327 		.name = "sdio3_ahb_clk",
328 		.parent = &kpm_ccu_clk.clk,
329 		.ops = &bus_clk_ops,
330 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
331 	},
332 	.freq_tbl = master_ahb_freq_tbl,
333 	.data = &sdio3_ahb_data,
334 };
335 
336 static struct bus_clock sdio4_ahb_clk = {
337 	.clk = {
338 		.name = "sdio4_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 = &sdio4_ahb_data,
345 };
346 
347 static struct bus_clock bsc1_apb_clk = {
348 	.clk = {
349 		.name = "bsc1_apb_clk",
350 		.parent = &kps_ccu_clk.clk,
351 		.ops = &bus_clk_ops,
352 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
353 	},
354 	.freq_tbl = slave_apb_freq_tbl,
355 	.data = &bsc1_apb_data,
356 };
357 
358 static struct bus_clock bsc2_apb_clk = {
359 	.clk = {
360 		.name = "bsc2_apb_clk",
361 		.parent = &kps_ccu_clk.clk,
362 		.ops = &bus_clk_ops,
363 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
364 		},
365 	.freq_tbl = slave_apb_freq_tbl,
366 	.data = &bsc2_apb_data,
367 };
368 
369 static struct bus_clock bsc3_apb_clk = {
370 	.clk = {
371 		.name = "bsc3_apb_clk",
372 		.parent = &kps_ccu_clk.clk,
373 		.ops = &bus_clk_ops,
374 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
375 		},
376 	.freq_tbl = slave_apb_freq_tbl,
377 	.data = &bsc3_apb_data,
378 };
379 
380 /* KPM peripheral */
381 static struct peri_clock sdio1_clk = {
382 	.clk = {
383 		.name = "sdio1_clk",
384 		.parent = &ref_52m.clk,
385 		.ops = &peri_clk_ops,
386 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
387 	},
388 	.data = &sdio1_data,
389 };
390 
391 static struct peri_clock sdio2_clk = {
392 	.clk = {
393 		.name = "sdio2_clk",
394 		.parent = &ref_52m.clk,
395 		.ops = &peri_clk_ops,
396 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
397 	},
398 	.data = &sdio2_data,
399 };
400 
401 static struct peri_clock sdio3_clk = {
402 	.clk = {
403 		.name = "sdio3_clk",
404 		.parent = &ref_52m.clk,
405 		.ops = &peri_clk_ops,
406 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
407 	},
408 	.data = &sdio3_data,
409 };
410 
411 static struct peri_clock sdio4_clk = {
412 	.clk = {
413 		.name = "sdio4_clk",
414 		.parent = &ref_52m.clk,
415 		.ops = &peri_clk_ops,
416 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
417 	},
418 	.data = &sdio4_data,
419 };
420 
421 static struct peri_clock sdio1_sleep_clk = {
422 	.clk = {
423 		.name = "sdio1_sleep_clk",
424 		.parent = &kpm_ccu_clk.clk,
425 		.ops = &bus_clk_ops,
426 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
427 	},
428 	.data = &sdio1_sleep_data,
429 };
430 
431 static struct peri_clock sdio2_sleep_clk = {
432 	.clk = {
433 		.name = "sdio2_sleep_clk",
434 		.parent = &kpm_ccu_clk.clk,
435 		.ops = &bus_clk_ops,
436 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
437 	},
438 	.data = &sdio2_sleep_data,
439 };
440 
441 static struct peri_clock sdio3_sleep_clk = {
442 	.clk = {
443 		.name = "sdio3_sleep_clk",
444 		.parent = &kpm_ccu_clk.clk,
445 		.ops = &bus_clk_ops,
446 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
447 	},
448 	.data = &sdio3_sleep_data,
449 };
450 
451 static struct peri_clock sdio4_sleep_clk = {
452 	.clk = {
453 		.name = "sdio4_sleep_clk",
454 		.parent = &kpm_ccu_clk.clk,
455 		.ops = &bus_clk_ops,
456 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
457 	},
458 	.data = &sdio4_sleep_data,
459 };
460 
461 /* KPS peripheral clock */
462 static struct peri_clock bsc1_clk = {
463 	.clk = {
464 		.name = "bsc1_clk",
465 		.parent = &ref_13m.clk,
466 		.rate = 13 * CLOCK_1M,
467 		.div = 1,
468 		.ops = &peri_clk_ops,
469 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
470 	},
471 	.data = &bsc1_data,
472 };
473 
474 static struct peri_clock bsc2_clk = {
475 	.clk = {
476 		.name = "bsc2_clk",
477 		.parent = &ref_13m.clk,
478 		.rate = 13 * CLOCK_1M,
479 		.div = 1,
480 		.ops = &peri_clk_ops,
481 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
482 	},
483 	.data = &bsc2_data,
484 };
485 
486 static struct peri_clock bsc3_clk = {
487 	.clk = {
488 		.name = "bsc3_clk",
489 		.parent = &ref_13m.clk,
490 		.rate = 13 * CLOCK_1M,
491 		.div = 1,
492 		.ops = &peri_clk_ops,
493 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
494 	},
495 	.data = &bsc3_data,
496 };
497 
498 /* public table for registering clocks */
499 struct clk_lookup arch_clk_tbl[] = {
500 	/* Peripheral clocks */
501 	CLK_LK(sdio1),
502 	CLK_LK(sdio2),
503 	CLK_LK(sdio3),
504 	CLK_LK(sdio4),
505 	CLK_LK(sdio1_sleep),
506 	CLK_LK(sdio2_sleep),
507 	CLK_LK(sdio3_sleep),
508 	CLK_LK(sdio4_sleep),
509 	CLK_LK(bsc1),
510 	CLK_LK(bsc2),
511 	CLK_LK(bsc3),
512 	/* Bus clocks */
513 	CLK_LK(sdio1_ahb),
514 	CLK_LK(sdio2_ahb),
515 	CLK_LK(sdio3_ahb),
516 	CLK_LK(sdio4_ahb),
517 	CLK_LK(bsc1_apb),
518 	CLK_LK(bsc2_apb),
519 	CLK_LK(bsc3_apb),
520 };
521 
522 /* public array size */
523 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);
524