2 * Copyright 2013 Broadcom Corporation.
4 * SPDX-License-Identifier: GPL-2.0+
9 * bcm281xx-specific clock tables
15 #include <asm/errno.h>
16 #include <asm/arch/sysmap.h>
17 #include <asm/kona-common/clk.h>
21 #define CLOCK_1M (CLOCK_1K * 1000)
23 /* declare a reference clock */
24 #define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \
25 static struct refclk clk_name = { \
28 .parent = clk_parent, \
31 .ops = &ref_clk_ops, \
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);
53 struct refclk *procclk;
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),
66 int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]);
68 /* convert ref clock string to clock structure pointer */
69 struct refclk *refclk_str_to_clk(const char *name)
72 struct refclk_lkup *tblp = refclk_str_tbl;
73 for (i = 0; i < refclk_entries; i++, tblp++) {
74 if (!(strcmp(name, tblp->name)))
80 /* frequency tables indexed by freq_id */
81 unsigned long master_axi_freq_tbl[8] = {
92 unsigned long master_ahb_freq_tbl[8] = {
103 unsigned long slave_axi_freq_tbl[8] = {
112 unsigned long slave_apb_freq_tbl[8] = {
121 static struct bus_clk_data bsc1_apb_data = {
122 .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1),
125 static struct bus_clk_data bsc2_apb_data = {
126 .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1),
129 static struct bus_clk_data bsc3_apb_data = {
130 .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1),
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",
141 .sel = SELECTOR(0x0a28, 0, 3),
142 .div = DIVIDER(0x0a28, 4, 14),
143 .trig = TRIGGER(0x0afc, 9),
146 static struct peri_clk_data sdio2_data = {
147 .gate = HW_SW_GATE(0x035c, 18, 2, 3),
148 .clocks = CLOCKS("ref_crystal",
153 .sel = SELECTOR(0x0a2c, 0, 3),
154 .div = DIVIDER(0x0a2c, 4, 14),
155 .trig = TRIGGER(0x0afc, 10),
158 static struct peri_clk_data sdio3_data = {
159 .gate = HW_SW_GATE(0x0364, 18, 2, 3),
160 .clocks = CLOCKS("ref_crystal",
165 .sel = SELECTOR(0x0a34, 0, 3),
166 .div = DIVIDER(0x0a34, 4, 14),
167 .trig = TRIGGER(0x0afc, 12),
170 static struct peri_clk_data sdio4_data = {
171 .gate = HW_SW_GATE(0x0360, 18, 2, 3),
172 .clocks = CLOCKS("ref_crystal",
177 .sel = SELECTOR(0x0a30, 0, 3),
178 .div = DIVIDER(0x0a30, 4, 14),
179 .trig = TRIGGER(0x0afc, 11),
182 static struct peri_clk_data sdio1_sleep_data = {
183 .clocks = CLOCKS("ref_32k"),
184 .gate = SW_ONLY_GATE(0x0358, 20, 4),
187 static struct peri_clk_data sdio2_sleep_data = {
188 .clocks = CLOCKS("ref_32k"),
189 .gate = SW_ONLY_GATE(0x035c, 20, 4),
192 static struct peri_clk_data sdio3_sleep_data = {
193 .clocks = CLOCKS("ref_32k"),
194 .gate = SW_ONLY_GATE(0x0364, 20, 4),
197 static struct peri_clk_data sdio4_sleep_data = {
198 .clocks = CLOCKS("ref_32k"),
199 .gate = SW_ONLY_GATE(0x0360, 20, 4),
202 static struct bus_clk_data sdio1_ahb_data = {
203 .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1),
206 static struct bus_clk_data sdio2_ahb_data = {
207 .gate = HW_SW_GATE_AUTO(0x035c, 16, 0, 1),
210 static struct bus_clk_data sdio3_ahb_data = {
211 .gate = HW_SW_GATE_AUTO(0x0364, 16, 0, 1),
214 static struct bus_clk_data sdio4_ahb_data = {
215 .gate = HW_SW_GATE_AUTO(0x0360, 16, 0, 1),
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",
226 .sel = SELECTOR(0x0a64, 0, 3),
227 .trig = TRIGGER(0x0afc, 23),
230 static struct peri_clk_data bsc2_data = {
231 .gate = HW_SW_GATE(0x045c, 18, 2, 3),
232 .clocks = CLOCKS("ref_crystal",
237 .sel = SELECTOR(0x0a68, 0, 3),
238 .trig = TRIGGER(0x0afc, 24),
241 static struct peri_clk_data bsc3_data = {
242 .gate = HW_SW_GATE(0x0484, 18, 2, 3),
243 .clocks = CLOCKS("ref_crystal",
248 .sel = SELECTOR(0x0a84, 0, 3),
249 .trig = TRIGGER(0x0b00, 2),
256 static struct ccu_clock kpm_ccu_clk = {
258 .name = "kpm_ccu_clk",
260 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
262 .num_policy_masks = 1,
263 .policy_freq_offset = 0x00000008,
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,
272 .freq_tbl = master_axi_freq_tbl,
275 static struct ccu_clock kps_ccu_clk = {
277 .name = "kps_ccu_clk",
279 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
281 .num_policy_masks = 2,
282 .policy_freq_offset = 0x00000008,
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,
295 .freq_tbl = slave_axi_freq_tbl,
303 static struct bus_clock sdio1_ahb_clk = {
305 .name = "sdio1_ahb_clk",
306 .parent = &kpm_ccu_clk.clk,
308 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
310 .freq_tbl = master_ahb_freq_tbl,
311 .data = &sdio1_ahb_data,
314 static struct bus_clock sdio2_ahb_clk = {
316 .name = "sdio2_ahb_clk",
317 .parent = &kpm_ccu_clk.clk,
319 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
321 .freq_tbl = master_ahb_freq_tbl,
322 .data = &sdio2_ahb_data,
325 static struct bus_clock sdio3_ahb_clk = {
327 .name = "sdio3_ahb_clk",
328 .parent = &kpm_ccu_clk.clk,
330 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
332 .freq_tbl = master_ahb_freq_tbl,
333 .data = &sdio3_ahb_data,
336 static struct bus_clock sdio4_ahb_clk = {
338 .name = "sdio4_ahb_clk",
339 .parent = &kpm_ccu_clk.clk,
341 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
343 .freq_tbl = master_ahb_freq_tbl,
344 .data = &sdio4_ahb_data,
347 static struct bus_clock bsc1_apb_clk = {
349 .name = "bsc1_apb_clk",
350 .parent = &kps_ccu_clk.clk,
352 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
354 .freq_tbl = slave_apb_freq_tbl,
355 .data = &bsc1_apb_data,
358 static struct bus_clock bsc2_apb_clk = {
360 .name = "bsc2_apb_clk",
361 .parent = &kps_ccu_clk.clk,
363 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
365 .freq_tbl = slave_apb_freq_tbl,
366 .data = &bsc2_apb_data,
369 static struct bus_clock bsc3_apb_clk = {
371 .name = "bsc3_apb_clk",
372 .parent = &kps_ccu_clk.clk,
374 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
376 .freq_tbl = slave_apb_freq_tbl,
377 .data = &bsc3_apb_data,
381 static struct peri_clock sdio1_clk = {
384 .parent = &ref_52m.clk,
385 .ops = &peri_clk_ops,
386 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
391 static struct peri_clock sdio2_clk = {
394 .parent = &ref_52m.clk,
395 .ops = &peri_clk_ops,
396 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
401 static struct peri_clock sdio3_clk = {
404 .parent = &ref_52m.clk,
405 .ops = &peri_clk_ops,
406 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
411 static struct peri_clock sdio4_clk = {
414 .parent = &ref_52m.clk,
415 .ops = &peri_clk_ops,
416 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
421 static struct peri_clock sdio1_sleep_clk = {
423 .name = "sdio1_sleep_clk",
424 .parent = &kpm_ccu_clk.clk,
426 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
428 .data = &sdio1_sleep_data,
431 static struct peri_clock sdio2_sleep_clk = {
433 .name = "sdio2_sleep_clk",
434 .parent = &kpm_ccu_clk.clk,
436 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
438 .data = &sdio2_sleep_data,
441 static struct peri_clock sdio3_sleep_clk = {
443 .name = "sdio3_sleep_clk",
444 .parent = &kpm_ccu_clk.clk,
446 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
448 .data = &sdio3_sleep_data,
451 static struct peri_clock sdio4_sleep_clk = {
453 .name = "sdio4_sleep_clk",
454 .parent = &kpm_ccu_clk.clk,
456 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
458 .data = &sdio4_sleep_data,
461 /* KPS peripheral clock */
462 static struct peri_clock bsc1_clk = {
465 .parent = &ref_13m.clk,
466 .rate = 13 * CLOCK_1M,
468 .ops = &peri_clk_ops,
469 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
474 static struct peri_clock bsc2_clk = {
477 .parent = &ref_13m.clk,
478 .rate = 13 * CLOCK_1M,
480 .ops = &peri_clk_ops,
481 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
486 static struct peri_clock bsc3_clk = {
489 .parent = &ref_13m.clk,
490 .rate = 13 * CLOCK_1M,
492 .ops = &peri_clk_ops,
493 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
498 /* public table for registering clocks */
499 struct clk_lookup arch_clk_tbl[] = {
500 /* Peripheral clocks */
522 /* public array size */
523 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);