1 /* 2 * Copyright 2013 Broadcom Corporation. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* 8 * 9 * bcm281xx-specific clock tables 10 * 11 */ 12 13 #include <common.h> 14 #include <asm/io.h> 15 #include <linux/errno.h> 16 #include <asm/arch/sysmap.h> 17 #include <asm/kona-common/clk.h> 18 #include "clk-core.h" 19 20 #define CLOCK_1K 1000 21 #define CLOCK_1M (CLOCK_1K * 1000) 22 23 /* declare a reference clock */ 24 #define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \ 25 static struct refclk clk_name = { \ 26 .clk = { \ 27 .name = #clk_name, \ 28 .parent = clk_parent, \ 29 .rate = clk_rate, \ 30 .div = clk_div, \ 31 .ops = &ref_clk_ops, \ 32 }, \ 33 } 34 35 /* 36 * Reference clocks 37 */ 38 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); 51 52 struct refclk_lkup { 53 struct refclk *procclk; 54 const char *name; 55 }; 56 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), 64 }; 65 66 int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]); 67 68 /* convert ref clock string to clock structure pointer */ 69 struct refclk *refclk_str_to_clk(const char *name) 70 { 71 int i; 72 struct refclk_lkup *tblp = refclk_str_tbl; 73 for (i = 0; i < refclk_entries; i++, tblp++) { 74 if (!(strcmp(name, tblp->name))) 75 return tblp->procclk; 76 } 77 return NULL; 78 } 79 80 /* frequency tables indexed by freq_id */ 81 unsigned long master_axi_freq_tbl[8] = { 82 26 * CLOCK_1M, 83 52 * CLOCK_1M, 84 104 * CLOCK_1M, 85 156 * CLOCK_1M, 86 156 * CLOCK_1M, 87 208 * CLOCK_1M, 88 312 * CLOCK_1M, 89 312 * CLOCK_1M 90 }; 91 92 unsigned long master_ahb_freq_tbl[8] = { 93 26 * CLOCK_1M, 94 52 * CLOCK_1M, 95 52 * CLOCK_1M, 96 52 * CLOCK_1M, 97 78 * CLOCK_1M, 98 104 * CLOCK_1M, 99 104 * CLOCK_1M, 100 156 * CLOCK_1M 101 }; 102 103 unsigned long slave_axi_freq_tbl[8] = { 104 26 * CLOCK_1M, 105 52 * CLOCK_1M, 106 78 * CLOCK_1M, 107 104 * CLOCK_1M, 108 156 * CLOCK_1M, 109 156 * CLOCK_1M 110 }; 111 112 unsigned long slave_apb_freq_tbl[8] = { 113 26 * CLOCK_1M, 114 26 * CLOCK_1M, 115 39 * CLOCK_1M, 116 52 * CLOCK_1M, 117 52 * CLOCK_1M, 118 78 * CLOCK_1M 119 }; 120 121 unsigned long esub_freq_tbl[8] = { 122 78 * CLOCK_1M, 123 156 * CLOCK_1M, 124 156 * CLOCK_1M, 125 156 * CLOCK_1M, 126 208 * CLOCK_1M, 127 208 * CLOCK_1M, 128 208 * CLOCK_1M 129 }; 130 131 static struct bus_clk_data bsc1_apb_data = { 132 .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1), 133 }; 134 135 static struct bus_clk_data bsc2_apb_data = { 136 .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1), 137 }; 138 139 static struct bus_clk_data bsc3_apb_data = { 140 .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1), 141 }; 142 143 /* * Master CCU clocks */ 144 static struct peri_clk_data sdio1_data = { 145 .gate = HW_SW_GATE(0x0358, 18, 2, 3), 146 .clocks = CLOCKS("ref_crystal", 147 "var_52m", 148 "ref_52m", 149 "var_96m", 150 "ref_96m"), 151 .sel = SELECTOR(0x0a28, 0, 3), 152 .div = DIVIDER(0x0a28, 4, 14), 153 .trig = TRIGGER(0x0afc, 9), 154 }; 155 156 static struct peri_clk_data sdio2_data = { 157 .gate = HW_SW_GATE(0x035c, 18, 2, 3), 158 .clocks = CLOCKS("ref_crystal", 159 "var_52m", 160 "ref_52m", 161 "var_96m", 162 "ref_96m"), 163 .sel = SELECTOR(0x0a2c, 0, 3), 164 .div = DIVIDER(0x0a2c, 4, 14), 165 .trig = TRIGGER(0x0afc, 10), 166 }; 167 168 static struct peri_clk_data sdio3_data = { 169 .gate = HW_SW_GATE(0x0364, 18, 2, 3), 170 .clocks = CLOCKS("ref_crystal", 171 "var_52m", 172 "ref_52m", 173 "var_96m", 174 "ref_96m"), 175 .sel = SELECTOR(0x0a34, 0, 3), 176 .div = DIVIDER(0x0a34, 4, 14), 177 .trig = TRIGGER(0x0afc, 12), 178 }; 179 180 static struct peri_clk_data sdio4_data = { 181 .gate = HW_SW_GATE(0x0360, 18, 2, 3), 182 .clocks = CLOCKS("ref_crystal", 183 "var_52m", 184 "ref_52m", 185 "var_96m", 186 "ref_96m"), 187 .sel = SELECTOR(0x0a30, 0, 3), 188 .div = DIVIDER(0x0a30, 4, 14), 189 .trig = TRIGGER(0x0afc, 11), 190 }; 191 192 static struct peri_clk_data sdio1_sleep_data = { 193 .clocks = CLOCKS("ref_32k"), 194 .gate = SW_ONLY_GATE(0x0358, 20, 4), 195 }; 196 197 static struct peri_clk_data sdio2_sleep_data = { 198 .clocks = CLOCKS("ref_32k"), 199 .gate = SW_ONLY_GATE(0x035c, 20, 4), 200 }; 201 202 static struct peri_clk_data sdio3_sleep_data = { 203 .clocks = CLOCKS("ref_32k"), 204 .gate = SW_ONLY_GATE(0x0364, 20, 4), 205 }; 206 207 static struct peri_clk_data sdio4_sleep_data = { 208 .clocks = CLOCKS("ref_32k"), 209 .gate = SW_ONLY_GATE(0x0360, 20, 4), 210 }; 211 212 static struct bus_clk_data usb_otg_ahb_data = { 213 .gate = HW_SW_GATE_AUTO(0x0348, 16, 0, 1), 214 }; 215 216 static struct bus_clk_data sdio1_ahb_data = { 217 .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1), 218 }; 219 220 static struct bus_clk_data sdio2_ahb_data = { 221 .gate = HW_SW_GATE_AUTO(0x035c, 16, 0, 1), 222 }; 223 224 static struct bus_clk_data sdio3_ahb_data = { 225 .gate = HW_SW_GATE_AUTO(0x0364, 16, 0, 1), 226 }; 227 228 static struct bus_clk_data sdio4_ahb_data = { 229 .gate = HW_SW_GATE_AUTO(0x0360, 16, 0, 1), 230 }; 231 232 /* * Slave CCU clocks */ 233 static struct peri_clk_data bsc1_data = { 234 .gate = HW_SW_GATE(0x0458, 18, 2, 3), 235 .clocks = CLOCKS("ref_crystal", 236 "var_104m", 237 "ref_104m", 238 "var_13m", 239 "ref_13m"), 240 .sel = SELECTOR(0x0a64, 0, 3), 241 .trig = TRIGGER(0x0afc, 23), 242 }; 243 244 static struct peri_clk_data bsc2_data = { 245 .gate = HW_SW_GATE(0x045c, 18, 2, 3), 246 .clocks = CLOCKS("ref_crystal", 247 "var_104m", 248 "ref_104m", 249 "var_13m", 250 "ref_13m"), 251 .sel = SELECTOR(0x0a68, 0, 3), 252 .trig = TRIGGER(0x0afc, 24), 253 }; 254 255 static struct peri_clk_data bsc3_data = { 256 .gate = HW_SW_GATE(0x0484, 18, 2, 3), 257 .clocks = CLOCKS("ref_crystal", 258 "var_104m", 259 "ref_104m", 260 "var_13m", 261 "ref_13m"), 262 .sel = SELECTOR(0x0a84, 0, 3), 263 .trig = TRIGGER(0x0b00, 2), 264 }; 265 266 /* 267 * CCU clocks 268 */ 269 270 static struct ccu_clock kpm_ccu_clk = { 271 .clk = { 272 .name = "kpm_ccu_clk", 273 .ops = &ccu_clk_ops, 274 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 275 }, 276 .num_policy_masks = 1, 277 .policy_freq_offset = 0x00000008, 278 .freq_bit_shift = 8, 279 .policy_ctl_offset = 0x0000000c, 280 .policy0_mask_offset = 0x00000010, 281 .policy1_mask_offset = 0x00000014, 282 .policy2_mask_offset = 0x00000018, 283 .policy3_mask_offset = 0x0000001c, 284 .lvm_en_offset = 0x00000034, 285 .freq_id = 2, 286 .freq_tbl = master_axi_freq_tbl, 287 }; 288 289 static struct ccu_clock kps_ccu_clk = { 290 .clk = { 291 .name = "kps_ccu_clk", 292 .ops = &ccu_clk_ops, 293 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 294 }, 295 .num_policy_masks = 2, 296 .policy_freq_offset = 0x00000008, 297 .freq_bit_shift = 8, 298 .policy_ctl_offset = 0x0000000c, 299 .policy0_mask_offset = 0x00000010, 300 .policy1_mask_offset = 0x00000014, 301 .policy2_mask_offset = 0x00000018, 302 .policy3_mask_offset = 0x0000001c, 303 .policy0_mask2_offset = 0x00000048, 304 .policy1_mask2_offset = 0x0000004c, 305 .policy2_mask2_offset = 0x00000050, 306 .policy3_mask2_offset = 0x00000054, 307 .lvm_en_offset = 0x00000034, 308 .freq_id = 2, 309 .freq_tbl = slave_axi_freq_tbl, 310 }; 311 312 #ifdef CONFIG_BCM_SF2_ETH 313 static struct ccu_clock esub_ccu_clk = { 314 .clk = { 315 .name = "esub_ccu_clk", 316 .ops = &ccu_clk_ops, 317 .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR, 318 }, 319 .num_policy_masks = 1, 320 .policy_freq_offset = 0x00000008, 321 .freq_bit_shift = 8, 322 .policy_ctl_offset = 0x0000000c, 323 .policy0_mask_offset = 0x00000010, 324 .policy1_mask_offset = 0x00000014, 325 .policy2_mask_offset = 0x00000018, 326 .policy3_mask_offset = 0x0000001c, 327 .lvm_en_offset = 0x00000034, 328 .freq_id = 2, 329 .freq_tbl = esub_freq_tbl, 330 }; 331 #endif 332 333 /* 334 * Bus clocks 335 */ 336 337 /* KPM bus clocks */ 338 static struct bus_clock usb_otg_ahb_clk = { 339 .clk = { 340 .name = "usb_otg_ahb_clk", 341 .parent = &kpm_ccu_clk.clk, 342 .ops = &bus_clk_ops, 343 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 344 }, 345 .freq_tbl = master_ahb_freq_tbl, 346 .data = &usb_otg_ahb_data, 347 }; 348 349 static struct bus_clock sdio1_ahb_clk = { 350 .clk = { 351 .name = "sdio1_ahb_clk", 352 .parent = &kpm_ccu_clk.clk, 353 .ops = &bus_clk_ops, 354 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 355 }, 356 .freq_tbl = master_ahb_freq_tbl, 357 .data = &sdio1_ahb_data, 358 }; 359 360 static struct bus_clock sdio2_ahb_clk = { 361 .clk = { 362 .name = "sdio2_ahb_clk", 363 .parent = &kpm_ccu_clk.clk, 364 .ops = &bus_clk_ops, 365 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 366 }, 367 .freq_tbl = master_ahb_freq_tbl, 368 .data = &sdio2_ahb_data, 369 }; 370 371 static struct bus_clock sdio3_ahb_clk = { 372 .clk = { 373 .name = "sdio3_ahb_clk", 374 .parent = &kpm_ccu_clk.clk, 375 .ops = &bus_clk_ops, 376 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 377 }, 378 .freq_tbl = master_ahb_freq_tbl, 379 .data = &sdio3_ahb_data, 380 }; 381 382 static struct bus_clock sdio4_ahb_clk = { 383 .clk = { 384 .name = "sdio4_ahb_clk", 385 .parent = &kpm_ccu_clk.clk, 386 .ops = &bus_clk_ops, 387 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 388 }, 389 .freq_tbl = master_ahb_freq_tbl, 390 .data = &sdio4_ahb_data, 391 }; 392 393 static struct bus_clock bsc1_apb_clk = { 394 .clk = { 395 .name = "bsc1_apb_clk", 396 .parent = &kps_ccu_clk.clk, 397 .ops = &bus_clk_ops, 398 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 399 }, 400 .freq_tbl = slave_apb_freq_tbl, 401 .data = &bsc1_apb_data, 402 }; 403 404 static struct bus_clock bsc2_apb_clk = { 405 .clk = { 406 .name = "bsc2_apb_clk", 407 .parent = &kps_ccu_clk.clk, 408 .ops = &bus_clk_ops, 409 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 410 }, 411 .freq_tbl = slave_apb_freq_tbl, 412 .data = &bsc2_apb_data, 413 }; 414 415 static struct bus_clock bsc3_apb_clk = { 416 .clk = { 417 .name = "bsc3_apb_clk", 418 .parent = &kps_ccu_clk.clk, 419 .ops = &bus_clk_ops, 420 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 421 }, 422 .freq_tbl = slave_apb_freq_tbl, 423 .data = &bsc3_apb_data, 424 }; 425 426 /* KPM peripheral */ 427 static struct peri_clock sdio1_clk = { 428 .clk = { 429 .name = "sdio1_clk", 430 .parent = &ref_52m.clk, 431 .ops = &peri_clk_ops, 432 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 433 }, 434 .data = &sdio1_data, 435 }; 436 437 static struct peri_clock sdio2_clk = { 438 .clk = { 439 .name = "sdio2_clk", 440 .parent = &ref_52m.clk, 441 .ops = &peri_clk_ops, 442 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 443 }, 444 .data = &sdio2_data, 445 }; 446 447 static struct peri_clock sdio3_clk = { 448 .clk = { 449 .name = "sdio3_clk", 450 .parent = &ref_52m.clk, 451 .ops = &peri_clk_ops, 452 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 453 }, 454 .data = &sdio3_data, 455 }; 456 457 static struct peri_clock sdio4_clk = { 458 .clk = { 459 .name = "sdio4_clk", 460 .parent = &ref_52m.clk, 461 .ops = &peri_clk_ops, 462 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 463 }, 464 .data = &sdio4_data, 465 }; 466 467 static struct peri_clock sdio1_sleep_clk = { 468 .clk = { 469 .name = "sdio1_sleep_clk", 470 .parent = &kpm_ccu_clk.clk, 471 .ops = &bus_clk_ops, 472 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 473 }, 474 .data = &sdio1_sleep_data, 475 }; 476 477 static struct peri_clock sdio2_sleep_clk = { 478 .clk = { 479 .name = "sdio2_sleep_clk", 480 .parent = &kpm_ccu_clk.clk, 481 .ops = &bus_clk_ops, 482 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 483 }, 484 .data = &sdio2_sleep_data, 485 }; 486 487 static struct peri_clock sdio3_sleep_clk = { 488 .clk = { 489 .name = "sdio3_sleep_clk", 490 .parent = &kpm_ccu_clk.clk, 491 .ops = &bus_clk_ops, 492 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 493 }, 494 .data = &sdio3_sleep_data, 495 }; 496 497 static struct peri_clock sdio4_sleep_clk = { 498 .clk = { 499 .name = "sdio4_sleep_clk", 500 .parent = &kpm_ccu_clk.clk, 501 .ops = &bus_clk_ops, 502 .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, 503 }, 504 .data = &sdio4_sleep_data, 505 }; 506 507 /* KPS peripheral clock */ 508 static struct peri_clock bsc1_clk = { 509 .clk = { 510 .name = "bsc1_clk", 511 .parent = &ref_13m.clk, 512 .rate = 13 * CLOCK_1M, 513 .div = 1, 514 .ops = &peri_clk_ops, 515 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 516 }, 517 .data = &bsc1_data, 518 }; 519 520 static struct peri_clock bsc2_clk = { 521 .clk = { 522 .name = "bsc2_clk", 523 .parent = &ref_13m.clk, 524 .rate = 13 * CLOCK_1M, 525 .div = 1, 526 .ops = &peri_clk_ops, 527 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 528 }, 529 .data = &bsc2_data, 530 }; 531 532 static struct peri_clock bsc3_clk = { 533 .clk = { 534 .name = "bsc3_clk", 535 .parent = &ref_13m.clk, 536 .rate = 13 * CLOCK_1M, 537 .div = 1, 538 .ops = &peri_clk_ops, 539 .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, 540 }, 541 .data = &bsc3_data, 542 }; 543 544 /* public table for registering clocks */ 545 struct clk_lookup arch_clk_tbl[] = { 546 /* Peripheral clocks */ 547 CLK_LK(sdio1), 548 CLK_LK(sdio2), 549 CLK_LK(sdio3), 550 CLK_LK(sdio4), 551 CLK_LK(sdio1_sleep), 552 CLK_LK(sdio2_sleep), 553 CLK_LK(sdio3_sleep), 554 CLK_LK(sdio4_sleep), 555 CLK_LK(bsc1), 556 CLK_LK(bsc2), 557 CLK_LK(bsc3), 558 /* Bus clocks */ 559 CLK_LK(usb_otg_ahb), 560 CLK_LK(sdio1_ahb), 561 CLK_LK(sdio2_ahb), 562 CLK_LK(sdio3_ahb), 563 CLK_LK(sdio4_ahb), 564 CLK_LK(bsc1_apb), 565 CLK_LK(bsc2_apb), 566 CLK_LK(bsc3_apb), 567 #ifdef CONFIG_BCM_SF2_ETH 568 CLK_LK(esub_ccu), 569 #endif 570 }; 571 572 /* public array size */ 573 unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl); 574