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