1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2013 Broadcom Corporation.
8 * bcm235xx-specific clock tables
14 #include <linux/errno.h>
15 #include <asm/arch/sysmap.h>
16 #include <asm/kona-common/clk.h>
20 #define CLOCK_1M (CLOCK_1K * 1000)
22 /* declare a reference clock */
23 #define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \
24 static struct refclk clk_name = { \
27 .parent = clk_parent, \
30 .ops = &ref_clk_ops, \
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);
52 struct refclk *procclk;
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),
65 int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]);
67 /* convert ref clock string to clock structure pointer */
68 struct refclk *refclk_str_to_clk(const char *name)
71 struct refclk_lkup *tblp = refclk_str_tbl;
72 for (i = 0; i < refclk_entries; i++, tblp++) {
73 if (!(strcmp(name, tblp->name)))
79 /* frequency tables indexed by freq_id */
80 unsigned long master_axi_freq_tbl[8] = {
91 unsigned long master_ahb_freq_tbl[8] = {
102 unsigned long slave_axi_freq_tbl[8] = {
111 unsigned long slave_apb_freq_tbl[8] = {
120 unsigned long esub_freq_tbl[8] = {
130 static struct bus_clk_data bsc1_apb_data = {
131 .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1),
134 static struct bus_clk_data bsc2_apb_data = {
135 .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1),
138 static struct bus_clk_data bsc3_apb_data = {
139 .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1),
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",
150 .sel = SELECTOR(0x0a28, 0, 3),
151 .div = DIVIDER(0x0a28, 4, 14),
152 .trig = TRIGGER(0x0afc, 9),
155 static struct peri_clk_data sdio2_data = {
156 .gate = HW_SW_GATE(0x035c, 18, 2, 3),
157 .clocks = CLOCKS("ref_crystal",
162 .sel = SELECTOR(0x0a2c, 0, 3),
163 .div = DIVIDER(0x0a2c, 4, 14),
164 .trig = TRIGGER(0x0afc, 10),
167 static struct peri_clk_data sdio3_data = {
168 .gate = HW_SW_GATE(0x0364, 18, 2, 3),
169 .clocks = CLOCKS("ref_crystal",
174 .sel = SELECTOR(0x0a34, 0, 3),
175 .div = DIVIDER(0x0a34, 4, 14),
176 .trig = TRIGGER(0x0afc, 12),
179 static struct peri_clk_data sdio4_data = {
180 .gate = HW_SW_GATE(0x0360, 18, 2, 3),
181 .clocks = CLOCKS("ref_crystal",
186 .sel = SELECTOR(0x0a30, 0, 3),
187 .div = DIVIDER(0x0a30, 4, 14),
188 .trig = TRIGGER(0x0afc, 11),
191 static struct peri_clk_data sdio1_sleep_data = {
192 .clocks = CLOCKS("ref_32k"),
193 .gate = SW_ONLY_GATE(0x0358, 20, 4),
196 static struct peri_clk_data sdio2_sleep_data = {
197 .clocks = CLOCKS("ref_32k"),
198 .gate = SW_ONLY_GATE(0x035c, 20, 4),
201 static struct peri_clk_data sdio3_sleep_data = {
202 .clocks = CLOCKS("ref_32k"),
203 .gate = SW_ONLY_GATE(0x0364, 20, 4),
206 static struct peri_clk_data sdio4_sleep_data = {
207 .clocks = CLOCKS("ref_32k"),
208 .gate = SW_ONLY_GATE(0x0360, 20, 4),
211 static struct bus_clk_data usb_otg_ahb_data = {
212 .gate = HW_SW_GATE_AUTO(0x0348, 16, 0, 1),
215 static struct bus_clk_data sdio1_ahb_data = {
216 .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1),
219 static struct bus_clk_data sdio2_ahb_data = {
220 .gate = HW_SW_GATE_AUTO(0x035c, 16, 0, 1),
223 static struct bus_clk_data sdio3_ahb_data = {
224 .gate = HW_SW_GATE_AUTO(0x0364, 16, 0, 1),
227 static struct bus_clk_data sdio4_ahb_data = {
228 .gate = HW_SW_GATE_AUTO(0x0360, 16, 0, 1),
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",
239 .sel = SELECTOR(0x0a64, 0, 3),
240 .trig = TRIGGER(0x0afc, 23),
243 static struct peri_clk_data bsc2_data = {
244 .gate = HW_SW_GATE(0x045c, 18, 2, 3),
245 .clocks = CLOCKS("ref_crystal",
250 .sel = SELECTOR(0x0a68, 0, 3),
251 .trig = TRIGGER(0x0afc, 24),
254 static struct peri_clk_data bsc3_data = {
255 .gate = HW_SW_GATE(0x0484, 18, 2, 3),
256 .clocks = CLOCKS("ref_crystal",
261 .sel = SELECTOR(0x0a84, 0, 3),
262 .trig = TRIGGER(0x0b00, 2),
269 static struct ccu_clock kpm_ccu_clk = {
271 .name = "kpm_ccu_clk",
273 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
275 .num_policy_masks = 1,
276 .policy_freq_offset = 0x00000008,
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,
285 .freq_tbl = master_axi_freq_tbl,
288 static struct ccu_clock kps_ccu_clk = {
290 .name = "kps_ccu_clk",
292 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
294 .num_policy_masks = 1,
295 .policy_freq_offset = 0x00000008,
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 .lvm_en_offset = 0x00000034,
304 .freq_tbl = slave_axi_freq_tbl,
307 #ifdef CONFIG_BCM_SF2_ETH
308 static struct ccu_clock esub_ccu_clk = {
310 .name = "esub_ccu_clk",
312 .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR,
314 .num_policy_masks = 1,
315 .policy_freq_offset = 0x00000008,
317 .policy_ctl_offset = 0x0000000c,
318 .policy0_mask_offset = 0x00000010,
319 .policy1_mask_offset = 0x00000014,
320 .policy2_mask_offset = 0x00000018,
321 .policy3_mask_offset = 0x0000001c,
322 .lvm_en_offset = 0x00000034,
324 .freq_tbl = esub_freq_tbl,
333 static struct bus_clock usb_otg_ahb_clk = {
335 .name = "usb_otg_ahb_clk",
336 .parent = &kpm_ccu_clk.clk,
338 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
340 .freq_tbl = master_ahb_freq_tbl,
341 .data = &usb_otg_ahb_data,
344 static struct bus_clock sdio1_ahb_clk = {
346 .name = "sdio1_ahb_clk",
347 .parent = &kpm_ccu_clk.clk,
349 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
351 .freq_tbl = master_ahb_freq_tbl,
352 .data = &sdio1_ahb_data,
355 static struct bus_clock sdio2_ahb_clk = {
357 .name = "sdio2_ahb_clk",
358 .parent = &kpm_ccu_clk.clk,
360 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
362 .freq_tbl = master_ahb_freq_tbl,
363 .data = &sdio2_ahb_data,
366 static struct bus_clock sdio3_ahb_clk = {
368 .name = "sdio3_ahb_clk",
369 .parent = &kpm_ccu_clk.clk,
371 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
373 .freq_tbl = master_ahb_freq_tbl,
374 .data = &sdio3_ahb_data,
377 static struct bus_clock sdio4_ahb_clk = {
379 .name = "sdio4_ahb_clk",
380 .parent = &kpm_ccu_clk.clk,
382 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
384 .freq_tbl = master_ahb_freq_tbl,
385 .data = &sdio4_ahb_data,
388 static struct bus_clock bsc1_apb_clk = {
390 .name = "bsc1_apb_clk",
391 .parent = &kps_ccu_clk.clk,
393 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
395 .freq_tbl = slave_apb_freq_tbl,
396 .data = &bsc1_apb_data,
399 static struct bus_clock bsc2_apb_clk = {
401 .name = "bsc2_apb_clk",
402 .parent = &kps_ccu_clk.clk,
404 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
406 .freq_tbl = slave_apb_freq_tbl,
407 .data = &bsc2_apb_data,
410 static struct bus_clock bsc3_apb_clk = {
412 .name = "bsc3_apb_clk",
413 .parent = &kps_ccu_clk.clk,
415 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
417 .freq_tbl = slave_apb_freq_tbl,
418 .data = &bsc3_apb_data,
422 static struct peri_clock sdio1_clk = {
425 .parent = &ref_52m.clk,
426 .ops = &peri_clk_ops,
427 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
432 static struct peri_clock sdio2_clk = {
435 .parent = &ref_52m.clk,
436 .ops = &peri_clk_ops,
437 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
442 static struct peri_clock sdio3_clk = {
445 .parent = &ref_52m.clk,
446 .ops = &peri_clk_ops,
447 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
452 static struct peri_clock sdio4_clk = {
455 .parent = &ref_52m.clk,
456 .ops = &peri_clk_ops,
457 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
462 static struct peri_clock sdio1_sleep_clk = {
464 .name = "sdio1_sleep_clk",
465 .parent = &kpm_ccu_clk.clk,
467 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
469 .data = &sdio1_sleep_data,
472 static struct peri_clock sdio2_sleep_clk = {
474 .name = "sdio2_sleep_clk",
475 .parent = &kpm_ccu_clk.clk,
477 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
479 .data = &sdio2_sleep_data,
482 static struct peri_clock sdio3_sleep_clk = {
484 .name = "sdio3_sleep_clk",
485 .parent = &kpm_ccu_clk.clk,
487 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
489 .data = &sdio3_sleep_data,
492 static struct peri_clock sdio4_sleep_clk = {
494 .name = "sdio4_sleep_clk",
495 .parent = &kpm_ccu_clk.clk,
497 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
499 .data = &sdio4_sleep_data,
502 /* KPS peripheral clock */
503 static struct peri_clock bsc1_clk = {
506 .parent = &ref_13m.clk,
507 .rate = 13 * CLOCK_1M,
509 .ops = &peri_clk_ops,
510 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
515 static struct peri_clock bsc2_clk = {
518 .parent = &ref_13m.clk,
519 .rate = 13 * CLOCK_1M,
521 .ops = &peri_clk_ops,
522 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
527 static struct peri_clock bsc3_clk = {
530 .parent = &ref_13m.clk,
531 .rate = 13 * CLOCK_1M,
533 .ops = &peri_clk_ops,
534 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
539 /* public table for registering clocks */
540 struct clk_lookup arch_clk_tbl[] = {
541 /* Peripheral clocks */
562 #ifdef CONFIG_BCM_SF2_ETH
567 /* public array size */
568 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);