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