1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org> 5 * Copyright (c) 2018 Val Packett <val@packett.cool> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/bus.h> 32 #include <sys/rman.h> 33 #include <sys/kernel.h> 34 #include <sys/module.h> 35 #include <machine/bus.h> 36 37 #include <dev/fdt/simplebus.h> 38 39 #include <dev/ofw/ofw_bus.h> 40 #include <dev/ofw/ofw_bus_subr.h> 41 42 #include <dev/clk/clk_div.h> 43 #include <dev/clk/clk_fixed.h> 44 #include <dev/clk/clk_mux.h> 45 46 #include <dev/clk/rockchip/rk_cru.h> 47 48 #define CRU_CLKSEL_CON(x) (0x80 + (x) * 0x4) 49 #define CRU_CLKGATE_CON(x) (0x100 + (x) * 0x4) 50 51 #define PLL_PPLL 1 52 #define SCLK_32K_SUSPEND_PMU 2 53 #define SCLK_SPI3_PMU 3 54 #define SCLK_TIMER12_PMU 4 55 #define SCLK_TIMER13_PMU 5 56 #define SCLK_UART4_PMU 6 57 #define SCLK_PVTM_PMU 7 58 #define SCLK_WIFI_PMU 8 59 #define SCLK_I2C0_PMU 9 60 #define SCLK_I2C4_PMU 10 61 #define SCLK_I2C8_PMU 11 62 63 #define PCLK_PMU_SRC 19 64 #define PCLK_PMU 20 65 #define PCLK_PMUGRF_PMU 21 66 #define PCLK_INTMEM1_PMU 22 67 #define PCLK_GPIO0_PMU 23 68 #define PCLK_GPIO1_PMU 24 69 #define PCLK_SGRF_PMU 25 70 #define PCLK_NOC_PMU 26 71 #define PCLK_I2C0_PMU 27 72 #define PCLK_I2C4_PMU 28 73 #define PCLK_I2C8_PMU 29 74 #define PCLK_RKPWM_PMU 30 75 #define PCLK_SPI3_PMU 31 76 #define PCLK_TIMER_PMU 32 77 #define PCLK_MAILBOX_PMU 33 78 #define PCLK_UART4_PMU 34 79 #define PCLK_WDT_M0_PMU 35 80 81 #define FCLK_CM0S_SRC_PMU 44 82 #define FCLK_CM0S_PMU 45 83 #define SCLK_CM0S_PMU 46 84 #define HCLK_CM0S_PMU 47 85 #define DCLK_CM0S_PMU 48 86 #define PCLK_INTR_ARB_PMU 49 87 #define HCLK_NOC_PMU 50 88 89 /* GATES */ 90 static struct rk_cru_gate rk3399_pmu_gates[] = { 91 /* PMUCRU_CLKGATE_CON0 */ 92 /* 0 Reserved */ 93 /* 1 fclk_cm0s_pmu_ppll_src_en */ 94 GATE(SCLK_SPI3_PMU, "clk_spi3_pmu", "clk_spi3_c", 0, 2), 95 GATE(SCLK_TIMER12_PMU, "clk_timer0_pmu", "clk_timer_sel", 0, 3), 96 GATE(SCLK_TIMER13_PMU, "clk_timer1_pmu", "clk_timer_sel", 0, 4), 97 GATE(SCLK_UART4_PMU, "clk_uart4_pmu", "clk_uart4_sel", 0, 5), 98 GATE(0, "clk_uart4_frac", "clk_uart4_frac_frac", 0, 6), 99 /* 7 clk_pvtm_pmu_en */ 100 GATE(SCLK_WIFI_PMU, "clk_wifi_pmu", "clk_wifi_sel", 0, 8), 101 GATE(SCLK_I2C0_PMU, "clk_i2c0_src", "clk_i2c0_div", 0, 9), 102 GATE(SCLK_I2C4_PMU, "clk_i2c4_src", "clk_i2c4_div", 0, 10), 103 GATE(SCLK_I2C8_PMU, "clk_i2c8_src", "clk_i2c8_div", 0, 11), 104 /* 12:15 Reserved */ 105 106 /* PMUCRU_CLKGATE_CON1 */ 107 GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", 1, 0), 108 /* 1 pclk_pmugrf_en */ 109 /* 2 pclk_intmem1_en */ 110 GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", 1, 3), 111 GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", 1, 4), 112 /* 5 pclk_sgrf_en */ 113 /* 6 pclk_noc_pmu_en */ 114 GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", 1, 7), 115 GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", 1, 8), 116 GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", 1, 9), 117 GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 1, 10), 118 GATE(PCLK_SPI3_PMU, "pclk_spi3_pmu", "pclk_pmu_src", 1, 11), 119 GATE(PCLK_TIMER_PMU, "pclk_timer_pmu", "pclk_pmu_src", 1, 12), 120 GATE(PCLK_MAILBOX_PMU, "pclk_mailbox_pmu", "pclk_pmu_src", 1, 13), 121 /* 14 pclk_uartm0_en */ 122 /* 15 pclk_wdt_m0_pmu_en */ 123 124 /* PMUCRU_CLKGATE_CON2 */ 125 /* 0 fclk_cm0s_en */ 126 /* 1 sclk_cm0s_en */ 127 /* 2 hclk_cm0s_en */ 128 /* 3 dclk_cm0s_en */ 129 /* 4 Reserved */ 130 /* 5 hclk_noc_pmu_en */ 131 /* 6:15 Reserved */ 132 }; 133 134 /* 135 * PLLs 136 */ 137 138 static struct rk_clk_pll_rate rk3399_pll_rates[] = { 139 { 140 .freq = 2208000000, 141 .refdiv = 1, 142 .fbdiv = 92, 143 .postdiv1 = 1, 144 .postdiv2 = 1, 145 .dsmpd = 1, 146 }, 147 { 148 .freq = 2184000000, 149 .refdiv = 1, 150 .fbdiv = 91, 151 .postdiv1 = 1, 152 .postdiv2 = 1, 153 .dsmpd = 1, 154 }, 155 { 156 .freq = 2160000000, 157 .refdiv = 1, 158 .fbdiv = 90, 159 .postdiv1 = 1, 160 .postdiv2 = 1, 161 .dsmpd = 1, 162 }, 163 { 164 .freq = 2136000000, 165 .refdiv = 1, 166 .fbdiv = 89, 167 .postdiv1 = 1, 168 .postdiv2 = 1, 169 .dsmpd = 1, 170 }, 171 { 172 .freq = 2112000000, 173 .refdiv = 1, 174 .fbdiv = 88, 175 .postdiv1 = 1, 176 .postdiv2 = 1, 177 .dsmpd = 1, 178 }, 179 { 180 .freq = 2088000000, 181 .refdiv = 1, 182 .fbdiv = 87, 183 .postdiv1 = 1, 184 .postdiv2 = 1, 185 .dsmpd = 1, 186 }, 187 { 188 .freq = 2064000000, 189 .refdiv = 1, 190 .fbdiv = 86, 191 .postdiv1 = 1, 192 .postdiv2 = 1, 193 .dsmpd = 1, 194 }, 195 { 196 .freq = 2040000000, 197 .refdiv = 1, 198 .fbdiv = 85, 199 .postdiv1 = 1, 200 .postdiv2 = 1, 201 .dsmpd = 1, 202 }, 203 { 204 .freq = 2016000000, 205 .refdiv = 1, 206 .fbdiv = 84, 207 .postdiv1 = 1, 208 .postdiv2 = 1, 209 .dsmpd = 1, 210 }, 211 { 212 .freq = 1992000000, 213 .refdiv = 1, 214 .fbdiv = 83, 215 .postdiv1 = 1, 216 .postdiv2 = 1, 217 .dsmpd = 1, 218 }, 219 { 220 .freq = 1968000000, 221 .refdiv = 1, 222 .fbdiv = 82, 223 .postdiv1 = 1, 224 .postdiv2 = 1, 225 .dsmpd = 1, 226 }, 227 { 228 .freq = 1944000000, 229 .refdiv = 1, 230 .fbdiv = 81, 231 .postdiv1 = 1, 232 .postdiv2 = 1, 233 .dsmpd = 1, 234 }, 235 { 236 .freq = 1920000000, 237 .refdiv = 1, 238 .fbdiv = 80, 239 .postdiv1 = 1, 240 .postdiv2 = 1, 241 .dsmpd = 1, 242 }, 243 { 244 .freq = 1896000000, 245 .refdiv = 1, 246 .fbdiv = 79, 247 .postdiv1 = 1, 248 .postdiv2 = 1, 249 .dsmpd = 1, 250 }, 251 { 252 .freq = 1872000000, 253 .refdiv = 1, 254 .fbdiv = 78, 255 .postdiv1 = 1, 256 .postdiv2 = 1, 257 .dsmpd = 1, 258 }, 259 { 260 .freq = 1848000000, 261 .refdiv = 1, 262 .fbdiv = 77, 263 .postdiv1 = 1, 264 .postdiv2 = 1, 265 .dsmpd = 1, 266 }, 267 { 268 .freq = 1824000000, 269 .refdiv = 1, 270 .fbdiv = 76, 271 .postdiv1 = 1, 272 .postdiv2 = 1, 273 .dsmpd = 1, 274 }, 275 { 276 .freq = 1800000000, 277 .refdiv = 1, 278 .fbdiv = 75, 279 .postdiv1 = 1, 280 .postdiv2 = 1, 281 .dsmpd = 1, 282 }, 283 { 284 .freq = 1776000000, 285 .refdiv = 1, 286 .fbdiv = 74, 287 .postdiv1 = 1, 288 .postdiv2 = 1, 289 .dsmpd = 1, 290 }, 291 { 292 .freq = 1752000000, 293 .refdiv = 1, 294 .fbdiv = 73, 295 .postdiv1 = 1, 296 .postdiv2 = 1, 297 .dsmpd = 1, 298 }, 299 { 300 .freq = 1728000000, 301 .refdiv = 1, 302 .fbdiv = 72, 303 .postdiv1 = 1, 304 .postdiv2 = 1, 305 .dsmpd = 1, 306 }, 307 { 308 .freq = 1704000000, 309 .refdiv = 1, 310 .fbdiv = 71, 311 .postdiv1 = 1, 312 .postdiv2 = 1, 313 .dsmpd = 1, 314 }, 315 { 316 .freq = 1680000000, 317 .refdiv = 1, 318 .fbdiv = 70, 319 .postdiv1 = 1, 320 .postdiv2 = 1, 321 .dsmpd = 1, 322 }, 323 { 324 .freq = 1656000000, 325 .refdiv = 1, 326 .fbdiv = 69, 327 .postdiv1 = 1, 328 .postdiv2 = 1, 329 .dsmpd = 1, 330 }, 331 { 332 .freq = 1632000000, 333 .refdiv = 1, 334 .fbdiv = 68, 335 .postdiv1 = 1, 336 .postdiv2 = 1, 337 .dsmpd = 1, 338 }, 339 { 340 .freq = 1608000000, 341 .refdiv = 1, 342 .fbdiv = 67, 343 .postdiv1 = 1, 344 .postdiv2 = 1, 345 .dsmpd = 1, 346 }, 347 { 348 .freq = 1600000000, 349 .refdiv = 3, 350 .fbdiv = 200, 351 .postdiv1 = 1, 352 .postdiv2 = 1, 353 .dsmpd = 1, 354 }, 355 { 356 .freq = 1584000000, 357 .refdiv = 1, 358 .fbdiv = 66, 359 .postdiv1 = 1, 360 .postdiv2 = 1, 361 .dsmpd = 1, 362 }, 363 { 364 .freq = 1560000000, 365 .refdiv = 1, 366 .fbdiv = 65, 367 .postdiv1 = 1, 368 .postdiv2 = 1, 369 .dsmpd = 1, 370 }, 371 { 372 .freq = 1536000000, 373 .refdiv = 1, 374 .fbdiv = 64, 375 .postdiv1 = 1, 376 .postdiv2 = 1, 377 .dsmpd = 1, 378 }, 379 { 380 .freq = 1512000000, 381 .refdiv = 1, 382 .fbdiv = 63, 383 .postdiv1 = 1, 384 .postdiv2 = 1, 385 .dsmpd = 1, 386 }, 387 { 388 .freq = 1488000000, 389 .refdiv = 1, 390 .fbdiv = 62, 391 .postdiv1 = 1, 392 .postdiv2 = 1, 393 .dsmpd = 1, 394 }, 395 { 396 .freq = 1464000000, 397 .refdiv = 1, 398 .fbdiv = 61, 399 .postdiv1 = 1, 400 .postdiv2 = 1, 401 .dsmpd = 1, 402 }, 403 { 404 .freq = 1440000000, 405 .refdiv = 1, 406 .fbdiv = 60, 407 .postdiv1 = 1, 408 .postdiv2 = 1, 409 .dsmpd = 1, 410 }, 411 { 412 .freq = 1416000000, 413 .refdiv = 1, 414 .fbdiv = 59, 415 .postdiv1 = 1, 416 .postdiv2 = 1, 417 .dsmpd = 1, 418 }, 419 { 420 .freq = 1392000000, 421 .refdiv = 1, 422 .fbdiv = 58, 423 .postdiv1 = 1, 424 .postdiv2 = 1, 425 .dsmpd = 1, 426 }, 427 { 428 .freq = 1368000000, 429 .refdiv = 1, 430 .fbdiv = 57, 431 .postdiv1 = 1, 432 .postdiv2 = 1, 433 .dsmpd = 1, 434 }, 435 { 436 .freq = 1344000000, 437 .refdiv = 1, 438 .fbdiv = 56, 439 .postdiv1 = 1, 440 .postdiv2 = 1, 441 .dsmpd = 1, 442 }, 443 { 444 .freq = 1320000000, 445 .refdiv = 1, 446 .fbdiv = 55, 447 .postdiv1 = 1, 448 .postdiv2 = 1, 449 .dsmpd = 1, 450 }, 451 { 452 .freq = 1296000000, 453 .refdiv = 1, 454 .fbdiv = 54, 455 .postdiv1 = 1, 456 .postdiv2 = 1, 457 .dsmpd = 1, 458 }, 459 { 460 .freq = 1272000000, 461 .refdiv = 1, 462 .fbdiv = 53, 463 .postdiv1 = 1, 464 .postdiv2 = 1, 465 .dsmpd = 1, 466 }, 467 { 468 .freq = 1248000000, 469 .refdiv = 1, 470 .fbdiv = 52, 471 .postdiv1 = 1, 472 .postdiv2 = 1, 473 .dsmpd = 1, 474 }, 475 { 476 .freq = 1200000000, 477 .refdiv = 1, 478 .fbdiv = 50, 479 .postdiv1 = 1, 480 .postdiv2 = 1, 481 .dsmpd = 1, 482 }, 483 { 484 .freq = 1188000000, 485 .refdiv = 2, 486 .fbdiv = 99, 487 .postdiv1 = 1, 488 .postdiv2 = 1, 489 .dsmpd = 1, 490 }, 491 { 492 .freq = 1104000000, 493 .refdiv = 1, 494 .fbdiv = 46, 495 .postdiv1 = 1, 496 .postdiv2 = 1, 497 .dsmpd = 1, 498 }, 499 { 500 .freq = 1100000000, 501 .refdiv = 12, 502 .fbdiv = 550, 503 .postdiv1 = 1, 504 .postdiv2 = 1, 505 .dsmpd = 1, 506 }, 507 { 508 .freq = 1008000000, 509 .refdiv = 1, 510 .fbdiv = 84, 511 .postdiv1 = 2, 512 .postdiv2 = 1, 513 .dsmpd = 1, 514 }, 515 { 516 .freq = 1000000000, 517 .refdiv = 1, 518 .fbdiv = 125, 519 .postdiv1 = 3, 520 .postdiv2 = 1, 521 .dsmpd = 1, 522 }, 523 { 524 .freq = 984000000, 525 .refdiv = 1, 526 .fbdiv = 82, 527 .postdiv1 = 2, 528 .postdiv2 = 1, 529 .dsmpd = 1, 530 }, 531 { 532 .freq = 960000000, 533 .refdiv = 1, 534 .fbdiv = 80, 535 .postdiv1 = 2, 536 .postdiv2 = 1, 537 .dsmpd = 1, 538 }, 539 { 540 .freq = 936000000, 541 .refdiv = 1, 542 .fbdiv = 78, 543 .postdiv1 = 2, 544 .postdiv2 = 1, 545 .dsmpd = 1, 546 }, 547 { 548 .freq = 912000000, 549 .refdiv = 1, 550 .fbdiv = 76, 551 .postdiv1 = 2, 552 .postdiv2 = 1, 553 .dsmpd = 1, 554 }, 555 { 556 .freq = 900000000, 557 .refdiv = 4, 558 .fbdiv = 300, 559 .postdiv1 = 2, 560 .postdiv2 = 1, 561 .dsmpd = 1, 562 }, 563 { 564 .freq = 888000000, 565 .refdiv = 1, 566 .fbdiv = 74, 567 .postdiv1 = 2, 568 .postdiv2 = 1, 569 .dsmpd = 1, 570 }, 571 { 572 .freq = 864000000, 573 .refdiv = 1, 574 .fbdiv = 72, 575 .postdiv1 = 2, 576 .postdiv2 = 1, 577 .dsmpd = 1, 578 }, 579 { 580 .freq = 840000000, 581 .refdiv = 1, 582 .fbdiv = 70, 583 .postdiv1 = 2, 584 .postdiv2 = 1, 585 .dsmpd = 1, 586 }, 587 { 588 .freq = 816000000, 589 .refdiv = 1, 590 .fbdiv = 68, 591 .postdiv1 = 2, 592 .postdiv2 = 1, 593 .dsmpd = 1, 594 }, 595 { 596 .freq = 800000000, 597 .refdiv = 1, 598 .fbdiv = 100, 599 .postdiv1 = 3, 600 .postdiv2 = 1, 601 .dsmpd = 1, 602 }, 603 { 604 .freq = 700000000, 605 .refdiv = 6, 606 .fbdiv = 350, 607 .postdiv1 = 2, 608 .postdiv2 = 1, 609 .dsmpd = 1, 610 }, 611 { 612 .freq = 696000000, 613 .refdiv = 1, 614 .fbdiv = 58, 615 .postdiv1 = 2, 616 .postdiv2 = 1, 617 .dsmpd = 1, 618 }, 619 { 620 .freq = 676000000, 621 .refdiv = 3, 622 .fbdiv = 169, 623 .postdiv1 = 2, 624 .postdiv2 = 1, 625 .dsmpd = 1, 626 }, 627 { 628 .freq = 600000000, 629 .refdiv = 1, 630 .fbdiv = 75, 631 .postdiv1 = 3, 632 .postdiv2 = 1, 633 .dsmpd = 1, 634 }, 635 { 636 .freq = 594000000, 637 .refdiv = 1, 638 .fbdiv = 99, 639 .postdiv1 = 4, 640 .postdiv2 = 1, 641 .dsmpd = 1, 642 }, 643 { 644 .freq = 533250000, 645 .refdiv = 8, 646 .fbdiv = 711, 647 .postdiv1 = 4, 648 .postdiv2 = 1, 649 .dsmpd = 1, 650 }, 651 { 652 .freq = 504000000, 653 .refdiv = 1, 654 .fbdiv = 63, 655 .postdiv1 = 3, 656 .postdiv2 = 1, 657 .dsmpd = 1, 658 }, 659 { 660 .freq = 500000000, 661 .refdiv = 6, 662 .fbdiv = 250, 663 .postdiv1 = 2, 664 .postdiv2 = 1, 665 .dsmpd = 1, 666 }, 667 { 668 .freq = 408000000, 669 .refdiv = 1, 670 .fbdiv = 68, 671 .postdiv1 = 2, 672 .postdiv2 = 2, 673 .dsmpd = 1, 674 }, 675 { 676 .freq = 312000000, 677 .refdiv = 1, 678 .fbdiv = 52, 679 .postdiv1 = 2, 680 .postdiv2 = 2, 681 .dsmpd = 1, 682 }, 683 { 684 .freq = 297000000, 685 .refdiv = 1, 686 .fbdiv = 99, 687 .postdiv1 = 4, 688 .postdiv2 = 2, 689 .dsmpd = 1, 690 }, 691 { 692 .freq = 216000000, 693 .refdiv = 1, 694 .fbdiv = 72, 695 .postdiv1 = 4, 696 .postdiv2 = 2, 697 .dsmpd = 1, 698 }, 699 { 700 .freq = 148500000, 701 .refdiv = 1, 702 .fbdiv = 99, 703 .postdiv1 = 4, 704 .postdiv2 = 4, 705 .dsmpd = 1, 706 }, 707 { 708 .freq = 106500000, 709 .refdiv = 1, 710 .fbdiv = 71, 711 .postdiv1 = 4, 712 .postdiv2 = 4, 713 .dsmpd = 1, 714 }, 715 { 716 .freq = 96000000, 717 .refdiv = 1, 718 .fbdiv = 64, 719 .postdiv1 = 4, 720 .postdiv2 = 4, 721 .dsmpd = 1, 722 }, 723 { 724 .freq = 74250000, 725 .refdiv = 2, 726 .fbdiv = 99, 727 .postdiv1 = 4, 728 .postdiv2 = 4, 729 .dsmpd = 1, 730 }, 731 { 732 .freq = 65000000, 733 .refdiv = 1, 734 .fbdiv = 65, 735 .postdiv1 = 6, 736 .postdiv2 = 4, 737 .dsmpd = 1, 738 }, 739 { 740 .freq = 54000000, 741 .refdiv = 1, 742 .fbdiv = 54, 743 .postdiv1 = 6, 744 .postdiv2 = 4, 745 .dsmpd = 1, 746 }, 747 { 748 .freq = 27000000, 749 .refdiv = 1, 750 .fbdiv = 27, 751 .postdiv1 = 6, 752 .postdiv2 = 4, 753 .dsmpd = 1, 754 }, 755 {}, 756 }; 757 758 PLIST(xin24m_p) = {"xin24m"}; 759 PLIST(xin24m_xin32k_p) = {"xin24m", "xin32k"}; 760 PLIST(xin24m_ppll_p) = {"xin24m", "ppll"}; 761 PLIST(uart4_p) = {"clk_uart4_c", "clk_uart4_frac", "xin24m"}; 762 PLIST(wifi_p) = {"clk_wifi_c", "clk_wifi_frac"}; 763 764 static struct rk_clk_pll_def ppll = { 765 .clkdef = { 766 .id = PLL_PPLL, 767 .name = "ppll", 768 .parent_names = xin24m_p, 769 .parent_cnt = nitems(xin24m_p), 770 }, 771 .base_offset = 0x00, 772 773 .rates = rk3399_pll_rates, 774 }; 775 776 static struct rk_clk rk3399_pmu_clks[] = { 777 /* Linked clocks */ 778 LINK("xin32k"), 779 780 { 781 .type = RK3399_CLK_PLL, 782 .clk.pll = &ppll 783 }, 784 785 /* PMUCRU_CLKSEL_CON0 */ 786 CDIV(PCLK_PMU_SRC, "pclk_pmu_src", "ppll", 0, 0, 0, 5), 787 /* 5:7 Reserved */ 788 /* 8:12 cm0s_div */ 789 /* 13:14 Reserved */ 790 /* 15 cm0s_clk_pll_sel */ 791 792 /* PMUCRU_CLKSEL_CON1 */ 793 COMP(0, "clk_spi3_c", xin24m_ppll_p, 0, 1, 0, 7, 7, 1), 794 COMP(0, "clk_wifi_c", xin24m_ppll_p, 0, 1, 8, 5, 13, 1), 795 MUX(0, "clk_wifi_sel", wifi_p, 0, 1, 14, 1), 796 MUX(0, "clk_timer_sel", xin24m_xin32k_p, 0, 1, 15, 1), 797 798 /* PMUCRU_CLKSEL_CON2 */ 799 CDIV(0, "clk_i2c0_div", "ppll", 0, 2, 0, 7), 800 /* 7 Reserved */ 801 CDIV(0, "clk_i2c8_div", "ppll", 0, 2, 8, 7), 802 /* 15 Reserved */ 803 804 /* PMUCRU_CLKSEL_CON3 */ 805 CDIV(0, "clk_i2c4_div", "ppll", 0, 3, 0, 7), 806 /* 7:15 Reserved */ 807 808 /* PMUCRU_CLKSEL_CON4 */ 809 /* 0:9 clk_32k_suspend_div */ 810 /* 10:14 Reserved */ 811 /* 15 clk_32k_suspend_sel */ 812 813 /* PMUCRU_CLKSEL_CON5 */ 814 COMP(0, "clk_uart4_c", xin24m_ppll_p, 0, 5, 0, 7, 10, 1), 815 /* 7 Reserved */ 816 MUX(0, "clk_uart4_sel", uart4_p, 0, 5, 8, 2), 817 /* 11:15 Reserved */ 818 819 /* PMUCRU_CLKFRAC_CON0 / PMUCRU_CLKSEL_CON6 */ 820 FRACT(0, "clk_uart4_frac_frac", "clk_uart4_sel", 0, 6), 821 822 /* PMUCRU_CLKFRAC_CON1 / PMUCRU_CLKSEL_CON7 */ 823 FRACT(0, "clk_wifi_frac", "clk_wifi_c", 0, 7), 824 }; 825 826 static int 827 rk3399_pmucru_probe(device_t dev) 828 { 829 830 if (!ofw_bus_status_okay(dev)) 831 return (ENXIO); 832 833 if (ofw_bus_is_compatible(dev, "rockchip,rk3399-pmucru")) { 834 device_set_desc(dev, "Rockchip RK3399 PMU Clock and Reset Unit"); 835 return (BUS_PROBE_DEFAULT); 836 } 837 838 return (ENXIO); 839 } 840 841 static int 842 rk3399_pmucru_attach(device_t dev) 843 { 844 struct rk_cru_softc *sc; 845 846 sc = device_get_softc(dev); 847 sc->dev = dev; 848 849 sc->gates = rk3399_pmu_gates; 850 sc->ngates = nitems(rk3399_pmu_gates); 851 852 sc->clks = rk3399_pmu_clks; 853 sc->nclks = nitems(rk3399_pmu_clks); 854 855 sc->reset_offset = 0x110; 856 sc->reset_num = 30; 857 858 return (rk_cru_attach(dev)); 859 } 860 861 static device_method_t rk3399_pmucru_methods[] = { 862 /* Device interface */ 863 DEVMETHOD(device_probe, rk3399_pmucru_probe), 864 DEVMETHOD(device_attach, rk3399_pmucru_attach), 865 866 DEVMETHOD_END 867 }; 868 869 DEFINE_CLASS_1(rk3399_pmucru, rk3399_pmucru_driver, rk3399_pmucru_methods, 870 sizeof(struct rk_cru_softc), rk_cru_driver); 871 872 EARLY_DRIVER_MODULE(rk3399_pmucru, simplebus, rk3399_pmucru_driver, 0, 0, 873 BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); 874