Home | History | Annotate | Download | only in bcm235xx
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright 2013 Broadcom Corporation.
      4  */
      5 
      6 /*
      7  *
      8  * bcm235xx-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 */
     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 = 1,
    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 	.lvm_en_offset = 0x00000034,
    303 	.freq_id = 2,
    304 	.freq_tbl = slave_axi_freq_tbl,
    305 };
    306 
    307 #ifdef CONFIG_BCM_SF2_ETH
    308 static struct ccu_clock esub_ccu_clk = {
    309 	.clk = {
    310 		.name = "esub_ccu_clk",
    311 		.ops = &ccu_clk_ops,
    312 		.ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR,
    313 	},
    314 	.num_policy_masks = 1,
    315 	.policy_freq_offset = 0x00000008,
    316 	.freq_bit_shift = 8,
    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,
    323 	.freq_id = 2,
    324 	.freq_tbl = esub_freq_tbl,
    325 };
    326 #endif
    327 
    328 /*
    329  * Bus clocks
    330  */
    331 
    332 /* KPM bus clocks */
    333 static struct bus_clock usb_otg_ahb_clk = {
    334 	.clk = {
    335 		.name = "usb_otg_ahb_clk",
    336 		.parent = &kpm_ccu_clk.clk,
    337 		.ops = &bus_clk_ops,
    338 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    339 	},
    340 	.freq_tbl = master_ahb_freq_tbl,
    341 	.data = &usb_otg_ahb_data,
    342 };
    343 
    344 static struct bus_clock sdio1_ahb_clk = {
    345 	.clk = {
    346 		.name = "sdio1_ahb_clk",
    347 		.parent = &kpm_ccu_clk.clk,
    348 		.ops = &bus_clk_ops,
    349 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    350 	},
    351 	.freq_tbl = master_ahb_freq_tbl,
    352 	.data = &sdio1_ahb_data,
    353 };
    354 
    355 static struct bus_clock sdio2_ahb_clk = {
    356 	.clk = {
    357 		.name = "sdio2_ahb_clk",
    358 		.parent = &kpm_ccu_clk.clk,
    359 		.ops = &bus_clk_ops,
    360 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    361 	},
    362 	.freq_tbl = master_ahb_freq_tbl,
    363 	.data = &sdio2_ahb_data,
    364 };
    365 
    366 static struct bus_clock sdio3_ahb_clk = {
    367 	.clk = {
    368 		.name = "sdio3_ahb_clk",
    369 		.parent = &kpm_ccu_clk.clk,
    370 		.ops = &bus_clk_ops,
    371 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    372 	},
    373 	.freq_tbl = master_ahb_freq_tbl,
    374 	.data = &sdio3_ahb_data,
    375 };
    376 
    377 static struct bus_clock sdio4_ahb_clk = {
    378 	.clk = {
    379 		.name = "sdio4_ahb_clk",
    380 		.parent = &kpm_ccu_clk.clk,
    381 		.ops = &bus_clk_ops,
    382 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    383 	},
    384 	.freq_tbl = master_ahb_freq_tbl,
    385 	.data = &sdio4_ahb_data,
    386 };
    387 
    388 static struct bus_clock bsc1_apb_clk = {
    389 	.clk = {
    390 		.name = "bsc1_apb_clk",
    391 		.parent = &kps_ccu_clk.clk,
    392 		.ops = &bus_clk_ops,
    393 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
    394 	},
    395 	.freq_tbl = slave_apb_freq_tbl,
    396 	.data = &bsc1_apb_data,
    397 };
    398 
    399 static struct bus_clock bsc2_apb_clk = {
    400 	.clk = {
    401 		.name = "bsc2_apb_clk",
    402 		.parent = &kps_ccu_clk.clk,
    403 		.ops = &bus_clk_ops,
    404 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
    405 		},
    406 	.freq_tbl = slave_apb_freq_tbl,
    407 	.data = &bsc2_apb_data,
    408 };
    409 
    410 static struct bus_clock bsc3_apb_clk = {
    411 	.clk = {
    412 		.name = "bsc3_apb_clk",
    413 		.parent = &kps_ccu_clk.clk,
    414 		.ops = &bus_clk_ops,
    415 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
    416 		},
    417 	.freq_tbl = slave_apb_freq_tbl,
    418 	.data = &bsc3_apb_data,
    419 };
    420 
    421 /* KPM peripheral */
    422 static struct peri_clock sdio1_clk = {
    423 	.clk = {
    424 		.name = "sdio1_clk",
    425 		.parent = &ref_52m.clk,
    426 		.ops = &peri_clk_ops,
    427 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    428 	},
    429 	.data = &sdio1_data,
    430 };
    431 
    432 static struct peri_clock sdio2_clk = {
    433 	.clk = {
    434 		.name = "sdio2_clk",
    435 		.parent = &ref_52m.clk,
    436 		.ops = &peri_clk_ops,
    437 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    438 	},
    439 	.data = &sdio2_data,
    440 };
    441 
    442 static struct peri_clock sdio3_clk = {
    443 	.clk = {
    444 		.name = "sdio3_clk",
    445 		.parent = &ref_52m.clk,
    446 		.ops = &peri_clk_ops,
    447 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    448 	},
    449 	.data = &sdio3_data,
    450 };
    451 
    452 static struct peri_clock sdio4_clk = {
    453 	.clk = {
    454 		.name = "sdio4_clk",
    455 		.parent = &ref_52m.clk,
    456 		.ops = &peri_clk_ops,
    457 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    458 	},
    459 	.data = &sdio4_data,
    460 };
    461 
    462 static struct peri_clock sdio1_sleep_clk = {
    463 	.clk = {
    464 		.name = "sdio1_sleep_clk",
    465 		.parent = &kpm_ccu_clk.clk,
    466 		.ops = &bus_clk_ops,
    467 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    468 	},
    469 	.data = &sdio1_sleep_data,
    470 };
    471 
    472 static struct peri_clock sdio2_sleep_clk = {
    473 	.clk = {
    474 		.name = "sdio2_sleep_clk",
    475 		.parent = &kpm_ccu_clk.clk,
    476 		.ops = &bus_clk_ops,
    477 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    478 	},
    479 	.data = &sdio2_sleep_data,
    480 };
    481 
    482 static struct peri_clock sdio3_sleep_clk = {
    483 	.clk = {
    484 		.name = "sdio3_sleep_clk",
    485 		.parent = &kpm_ccu_clk.clk,
    486 		.ops = &bus_clk_ops,
    487 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    488 	},
    489 	.data = &sdio3_sleep_data,
    490 };
    491 
    492 static struct peri_clock sdio4_sleep_clk = {
    493 	.clk = {
    494 		.name = "sdio4_sleep_clk",
    495 		.parent = &kpm_ccu_clk.clk,
    496 		.ops = &bus_clk_ops,
    497 		.ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
    498 	},
    499 	.data = &sdio4_sleep_data,
    500 };
    501 
    502 /* KPS peripheral clock */
    503 static struct peri_clock bsc1_clk = {
    504 	.clk = {
    505 		.name = "bsc1_clk",
    506 		.parent = &ref_13m.clk,
    507 		.rate = 13 * CLOCK_1M,
    508 		.div = 1,
    509 		.ops = &peri_clk_ops,
    510 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
    511 	},
    512 	.data = &bsc1_data,
    513 };
    514 
    515 static struct peri_clock bsc2_clk = {
    516 	.clk = {
    517 		.name = "bsc2_clk",
    518 		.parent = &ref_13m.clk,
    519 		.rate = 13 * CLOCK_1M,
    520 		.div = 1,
    521 		.ops = &peri_clk_ops,
    522 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
    523 	},
    524 	.data = &bsc2_data,
    525 };
    526 
    527 static struct peri_clock bsc3_clk = {
    528 	.clk = {
    529 		.name = "bsc3_clk",
    530 		.parent = &ref_13m.clk,
    531 		.rate = 13 * CLOCK_1M,
    532 		.div = 1,
    533 		.ops = &peri_clk_ops,
    534 		.ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
    535 	},
    536 	.data = &bsc3_data,
    537 };
    538 
    539 /* public table for registering clocks */
    540 struct clk_lookup arch_clk_tbl[] = {
    541 	/* Peripheral clocks */
    542 	CLK_LK(sdio1),
    543 	CLK_LK(sdio2),
    544 	CLK_LK(sdio3),
    545 	CLK_LK(sdio4),
    546 	CLK_LK(sdio1_sleep),
    547 	CLK_LK(sdio2_sleep),
    548 	CLK_LK(sdio3_sleep),
    549 	CLK_LK(sdio4_sleep),
    550 	CLK_LK(bsc1),
    551 	CLK_LK(bsc2),
    552 	CLK_LK(bsc3),
    553 	/* Bus clocks */
    554 	CLK_LK(usb_otg_ahb),
    555 	CLK_LK(sdio1_ahb),
    556 	CLK_LK(sdio2_ahb),
    557 	CLK_LK(sdio3_ahb),
    558 	CLK_LK(sdio4_ahb),
    559 	CLK_LK(bsc1_apb),
    560 	CLK_LK(bsc2_apb),
    561 	CLK_LK(bsc3_apb),
    562 #ifdef CONFIG_BCM_SF2_ETH
    563 	CLK_LK(esub_ccu),
    564 #endif
    565 };
    566 
    567 /* public array size */
    568 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);
    569