1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD$"); 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/rman.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <machine/bus.h> 40 41#include <dev/fdt/simplebus.h> 42 43#include <dev/ofw/ofw_bus.h> 44#include <dev/ofw/ofw_bus_subr.h> 45 46#include <dev/extres/clk/clk_div.h> 47#include <dev/extres/clk/clk_fixed.h> 48#include <dev/extres/clk/clk_mux.h> 49 50#include <arm64/rockchip/clk/rk_cru.h> 51 52/* Registers */ 53#define RK3328_GRF_SOC_CON4 0x410 54#define RK3328_GRF_MAC_CON1 0x904 55#define RK3328_GRF_MAC_CON2 0x908 56 57/* GATES */ 58 59#define SCLK_I2S0 41 60#define SCLK_I2S1 42 61#define SCLK_I2S2 43 62#define SCLK_I2S1_OUT 44 63#define SCLK_I2S2_OUT 45 64#define SCLK_MAC2PHY_RXTX 83 65#define SCLK_MAC2PHY_SRC 84 66#define SCLK_MAC2PHY_REF 85 67#define SCLK_MAC2PHY_OUT 86 68#define SCLK_MAC2IO_RX 87 69#define SCLK_MAC2IO_TX 88 70#define SCLK_MAC2IO_REFOUT 89 71#define SCLK_MAC2IO_REF 90 72#define SCLK_MAC2IO_OUT 91 73#define SCLK_USB3OTG_REF 96 74#define SCLK_MAC2IO_SRC 99 75#define SCLK_MAC2IO 100 76#define SCLK_MAC2PHY 101 77#define SCLK_MAC2IO_EXT 102 78#define ACLK_USB3OTG 132 79#define ACLK_GMAC 146 80#define ACLK_MAC2PHY 149 81#define ACLK_MAC2IO 150 82#define ACLK_PERI 153 83#define PCLK_GPIO0 200 84#define PCLK_GPIO1 201 85#define PCLK_GPIO2 202 86#define PCLK_GPIO3 203 87#define PCLK_I2C0 205 88#define PCLK_I2C1 206 89#define PCLK_I2C2 207 90#define PCLK_I2C3 208 91#define PCLK_TSADC 213 92#define PCLK_GMAC 220 93#define PCLK_MAC2PHY 222 94#define PCLK_MAC2IO 223 95#define PCLK_USB3PHY_OTG 224 96#define PCLK_USB3PHY_PIPE 225 97#define PCLK_USB3_GRF 226 98#define PCLK_ACODECPHY 235 99#define HCLK_I2S0_8CH 311 100#define HCLK_I2S1_8CH 312 101#define HCLK_I2S2_2CH 313 102#define HCLK_SDMMC 317 103#define HCLK_SDIO 318 104#define HCLK_EMMC 319 105#define HCLK_SDMMC_EXT 320 106 107static struct rk_cru_gate rk3328_gates[] = { 108 /* CRU_CLKGATE_CON0 */ 109 CRU_GATE(0, "apll_core", "apll", 0x200, 0) 110 CRU_GATE(0, "dpll_core", "dpll", 0x200, 1) 111 CRU_GATE(0, "gpll_core", "gpll", 0x200, 2) 112 CRU_GATE(0, "npll_core", "npll", 0x200, 12) 113 114 /* CRU_CLKGATE_CON1 */ 115 CRU_GATE(SCLK_I2S0, "clk_i2s0", "clk_i2s0_mux", 0x204, 3) 116 CRU_GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", 0x204, 6) 117 CRU_GATE(SCLK_I2S2, "clk_i2s2", "clk_i2s2_mux", 0x204, 10) 118 119 /* CRU_CLKGATE_CON4 */ 120 CRU_GATE(0, "gpll_peri", "gpll", 0x210, 0) 121 CRU_GATE(0, "cpll_peri", "cpll", 0x210, 1) 122 CRU_GATE(SCLK_USB3OTG_REF, "clk_usb3otg_ref", "xin24m", 0x210, 7) 123 124 /* CRU_CLKGATE_CON8 */ 125 CRU_GATE(0, "pclk_bus", "pclk_bus_pre", 0x220, 3) 126 CRU_GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0x220, 4) 127 128 /* CRU_CLKGATE_CON8 */ 129 CRU_GATE(SCLK_MAC2IO_REF, "clk_mac2io_ref", "clk_mac2io", 0x224, 7) 130 CRU_GATE(SCLK_MAC2IO_REFOUT, "clk_mac2io_refout", "clk_mac2io", 0x224, 6) 131 CRU_GATE(SCLK_MAC2IO_TX, "clk_mac2io_tx", "clk_mac2io", 0x224, 5) 132 CRU_GATE(SCLK_MAC2IO_RX, "clk_mac2io_rx", "clk_mac2io", 0x224, 4) 133 CRU_GATE(SCLK_MAC2PHY_REF, "clk_mac2phy_ref", "clk_mac2phy", 0x224, 3) 134 CRU_GATE(SCLK_MAC2PHY_RXTX, "clk_mac2phy_rxtx", "clk_mac2phy", 0x224, 1) 135 136 /* CRU_CLKGATE_CON10 */ 137 CRU_GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0x228, 0) 138 139 /* CRU_CLKGATE_CON15*/ 140 CRU_GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0x23C, 3) 141 CRU_GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_bus_pre", 0x23C, 4) 142 CRU_GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0x23C, 5) 143 CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0x23C, 10) 144 145 /* CRU_CLKGATE_CON16 */ 146 CRU_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0x23C, 0) 147 CRU_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0x23C, 1) 148 CRU_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0x23C, 2) 149 CRU_GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0x23C, 14) 150 151 CRU_GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0x240, 7) 152 CRU_GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0x240, 8) 153 CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0x240, 9) 154 CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0x240, 10) 155 156 /* CRU_CLKGATE_CON17 */ 157 CRU_GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", 0x244, 2) 158 CRU_GATE(PCLK_ACODECPHY, "pclk_acodecphy", "pclk_phy_pre", 0x244, 5) 159 160 /* CRU_CLKGATE_CON19 */ 161 CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0x24C, 0) 162 CRU_GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0x24C, 1) 163 CRU_GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0x24C, 2) 164 CRU_GATE(0, "hclk_peri_niu", "hclk_peri", 0x24C, 12) 165 CRU_GATE(0, "pclk_peri_niu", "hclk_peri", 0x24C, 13) 166 CRU_GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0x24C, 14) 167 CRU_GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0x24C, 15) 168 169 /* CRU_CLKGATE_CON26 */ 170 CRU_GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0x268, 0) 171 CRU_GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0x268, 1) 172 CRU_GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0x268, 2) 173 CRU_GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0x268, 3) 174 175 /* CRU_CLKGATE_CON28 */ 176 CRU_GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0x270, 1) 177 CRU_GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0x270, 2) 178}; 179 180/* 181 * PLLs 182 */ 183 184#define PLL_APLL 1 185#define PLL_DPLL 2 186#define PLL_CPLL 3 187#define PLL_GPLL 4 188#define PLL_NPLL 5 189 190static struct rk_clk_pll_rate rk3328_pll_rates[] = { 191 { 192 .freq = 1608000000, 193 .refdiv = 1, 194 .fbdiv = 67, 195 .postdiv1 = 1, 196 .postdiv2 = 1, 197 .dsmpd = 1, 198 }, 199 { 200 .freq = 1584000000, 201 .refdiv = 1, 202 .fbdiv = 66, 203 .postdiv1 = 1, 204 .postdiv2 = 1, 205 .dsmpd = 1, 206 }, 207 { 208 .freq = 1560000000, 209 .refdiv = 1, 210 .fbdiv = 65, 211 .postdiv1 = 1, 212 .postdiv2 = 1, 213 .dsmpd = 1, 214 }, 215 { 216 .freq = 1536000000, 217 .refdiv = 1, 218 .fbdiv = 64, 219 .postdiv1 = 1, 220 .postdiv2 = 1, 221 .dsmpd = 1, 222 }, 223 { 224 .freq = 1512000000, 225 .refdiv = 1, 226 .fbdiv = 63, 227 .postdiv1 = 1, 228 .postdiv2 = 1, 229 .dsmpd = 1, 230 }, 231 { 232 .freq = 1488000000, 233 .refdiv = 1, 234 .fbdiv = 62, 235 .postdiv1 = 1, 236 .postdiv2 = 1, 237 .dsmpd = 1, 238 }, 239 { 240 .freq = 1464000000, 241 .refdiv = 1, 242 .fbdiv = 61, 243 .postdiv1 = 1, 244 .postdiv2 = 1, 245 .dsmpd = 1, 246 }, 247 { 248 .freq = 1440000000, 249 .refdiv = 1, 250 .fbdiv = 60, 251 .postdiv1 = 1, 252 .postdiv2 = 1, 253 .dsmpd = 1, 254 }, 255 { 256 .freq = 1416000000, 257 .refdiv = 1, 258 .fbdiv = 59, 259 .postdiv1 = 1, 260 .postdiv2 = 1, 261 .dsmpd = 1, 262 }, 263 { 264 .freq = 1392000000, 265 .refdiv = 1, 266 .fbdiv = 58, 267 .postdiv1 = 1, 268 .postdiv2 = 1, 269 .dsmpd = 1, 270 }, 271 { 272 .freq = 1368000000, 273 .refdiv = 1, 274 .fbdiv = 57, 275 .postdiv1 = 1, 276 .postdiv2 = 1, 277 .dsmpd = 1, 278 }, 279 { 280 .freq = 1344000000, 281 .refdiv = 1, 282 .fbdiv = 56, 283 .postdiv1 = 1, 284 .postdiv2 = 1, 285 .dsmpd = 1, 286 }, 287 { 288 .freq = 1320000000, 289 .refdiv = 1, 290 .fbdiv = 55, 291 .postdiv1 = 1, 292 .postdiv2 = 1, 293 .dsmpd = 1, 294 }, 295 { 296 .freq = 1296000000, 297 .refdiv = 1, 298 .fbdiv = 54, 299 .postdiv1 = 1, 300 .postdiv2 = 1, 301 .dsmpd = 1, 302 }, 303 { 304 .freq = 1272000000, 305 .refdiv = 1, 306 .fbdiv = 53, 307 .postdiv1 = 1, 308 .postdiv2 = 1, 309 .dsmpd = 1, 310 }, 311 { 312 .freq = 1248000000, 313 .refdiv = 1, 314 .fbdiv = 52, 315 .postdiv1 = 1, 316 .postdiv2 = 1, 317 .dsmpd = 1, 318 }, 319 { 320 .freq = 1200000000, 321 .refdiv = 1, 322 .fbdiv = 50, 323 .postdiv1 = 1, 324 .postdiv2 = 1, 325 .dsmpd = 1, 326 }, 327 { 328 .freq = 1188000000, 329 .refdiv = 2, 330 .fbdiv = 99, 331 .postdiv1 = 1, 332 .postdiv2 = 1, 333 .dsmpd = 1, 334 }, 335 { 336 .freq = 1104000000, 337 .refdiv = 1, 338 .fbdiv = 46, 339 .postdiv1 = 1, 340 .postdiv2 = 1, 341 .dsmpd = 1, 342 }, 343 { 344 .freq = 1100000000, 345 .refdiv = 12, 346 .fbdiv = 550, 347 .postdiv1 = 1, 348 .postdiv2 = 1, 349 .dsmpd = 1, 350 }, 351 { 352 .freq = 1008000000, 353 .refdiv = 1, 354 .fbdiv = 84, 355 .postdiv1 = 2, 356 .postdiv2 = 1, 357 .dsmpd = 1, 358 }, 359 { 360 .freq = 1000000000, 361 .refdiv = 6, 362 .fbdiv = 500, 363 .postdiv1 = 2, 364 .postdiv2 = 1, 365 .dsmpd = 1, 366 }, 367 { 368 .freq = 984000000, 369 .refdiv = 1, 370 .fbdiv = 82, 371 .postdiv1 = 2, 372 .postdiv2 = 1, 373 .dsmpd = 1, 374 }, 375 { 376 .freq = 960000000, 377 .refdiv = 1, 378 .fbdiv = 80, 379 .postdiv1 = 2, 380 .postdiv2 = 1, 381 .dsmpd = 1, 382 }, 383 { 384 .freq = 936000000, 385 .refdiv = 1, 386 .fbdiv = 78, 387 .postdiv1 = 2, 388 .postdiv2 = 1, 389 .dsmpd = 1, 390 }, 391 { 392 .freq = 912000000, 393 .refdiv = 1, 394 .fbdiv = 76, 395 .postdiv1 = 2, 396 .postdiv2 = 1, 397 .dsmpd = 1, 398 }, 399 { 400 .freq = 900000000, 401 .refdiv = 4, 402 .fbdiv = 300, 403 .postdiv1 = 2, 404 .postdiv2 = 1, 405 .dsmpd = 1, 406 }, 407 { 408 .freq = 888000000, 409 .refdiv = 1, 410 .fbdiv = 74, 411 .postdiv1 = 2, 412 .postdiv2 = 1, 413 .dsmpd = 1, 414 }, 415 { 416 .freq = 864000000, 417 .refdiv = 1, 418 .fbdiv = 72, 419 .postdiv1 = 2, 420 .postdiv2 = 1, 421 .dsmpd = 1, 422 }, 423 { 424 .freq = 840000000, 425 .refdiv = 1, 426 .fbdiv = 70, 427 .postdiv1 = 2, 428 .postdiv2 = 1, 429 .dsmpd = 1, 430 }, 431 { 432 .freq = 816000000, 433 .refdiv = 1, 434 .fbdiv = 68, 435 .postdiv1 = 2, 436 .postdiv2 = 1, 437 .dsmpd = 1, 438 }, 439 { 440 .freq = 800000000, 441 .refdiv = 6, 442 .fbdiv = 400, 443 .postdiv1 = 2, 444 .postdiv2 = 1, 445 .dsmpd = 1, 446 }, 447 { 448 .freq = 700000000, 449 .refdiv = 6, 450 .fbdiv = 350, 451 .postdiv1 = 2, 452 .postdiv2 = 1, 453 .dsmpd = 1, 454 }, 455 { 456 .freq = 696000000, 457 .refdiv = 1, 458 .fbdiv = 58, 459 .postdiv1 = 2, 460 .postdiv2 = 1, 461 .dsmpd = 1, 462 }, 463 { 464 .freq = 600000000, 465 .refdiv = 1, 466 .fbdiv = 75, 467 .postdiv1 = 3, 468 .postdiv2 = 1, 469 .dsmpd = 1, 470 }, 471 { 472 .freq = 594000000, 473 .refdiv = 2, 474 .fbdiv = 99, 475 .postdiv1 = 2, 476 .postdiv2 = 1, 477 .dsmpd = 1, 478 }, 479 { 480 .freq = 504000000, 481 .refdiv = 1, 482 .fbdiv = 63, 483 .postdiv1 = 3, 484 .postdiv2 = 1, 485 .dsmpd = 1, 486 }, 487 { 488 .freq = 500000000, 489 .refdiv = 6, 490 .fbdiv = 250, 491 .postdiv1 = 2, 492 .postdiv2 = 1, 493 .dsmpd = 1, 494 }, 495 { 496 .freq = 408000000, 497 .refdiv = 1, 498 .fbdiv = 68, 499 .postdiv1 = 2, 500 .postdiv2 = 2, 501 .dsmpd = 1, 502 }, 503 { 504 .freq = 312000000, 505 .refdiv = 1, 506 .fbdiv = 52, 507 .postdiv1 = 2, 508 .postdiv2 = 2, 509 .dsmpd = 1, 510 }, 511 { 512 .freq = 216000000, 513 .refdiv = 1, 514 .fbdiv = 72, 515 .postdiv1 = 4, 516 .postdiv2 = 2, 517 .dsmpd = 1, 518 }, 519 { 520 .freq = 96000000, 521 .refdiv = 1, 522 .fbdiv = 64, 523 .postdiv1 = 4, 524 .postdiv2 = 4, 525 .dsmpd = 1, 526 }, 527 {}, 528}; 529 530static struct rk_clk_pll_rate rk3328_pll_frac_rates[] = { 531 { 532 .freq = 1016064000, 533 .refdiv = 3, 534 .fbdiv = 127, 535 .postdiv1 = 1, 536 .postdiv2 = 1, 537 .dsmpd = 0, 538 .frac = 134217, 539 }, 540 { 541 .freq = 983040000, 542 .refdiv = 24, 543 .fbdiv = 983, 544 .postdiv1 = 1, 545 .postdiv2 = 1, 546 .dsmpd = 0, 547 .frac = 671088, 548 }, 549 { 550 .freq = 491520000, 551 .refdiv = 24, 552 .fbdiv = 983, 553 .postdiv1 = 2, 554 .postdiv2 = 1, 555 .dsmpd = 0, 556 .frac = 671088, 557 }, 558 { 559 .freq = 61440000, 560 .refdiv = 6, 561 .fbdiv = 215, 562 .postdiv1 = 7, 563 .postdiv2 = 2, 564 .dsmpd = 0, 565 .frac = 671088, 566 }, 567 { 568 .freq = 56448000, 569 .refdiv = 12, 570 .fbdiv = 451, 571 .postdiv1 = 4, 572 .postdiv2 = 4, 573 .dsmpd = 0, 574 .frac = 9797894, 575 }, 576 { 577 .freq = 40960000, 578 .refdiv = 12, 579 .fbdiv = 409, 580 .postdiv1 = 4, 581 .postdiv2 = 5, 582 .dsmpd = 0, 583 .frac = 10066329, 584 }, 585 {}, 586}; 587 588static const char *pll_parents[] = {"xin24m"}; 589static struct rk_clk_pll_def apll = { 590 .clkdef = { 591 .id = PLL_APLL, 592 .name = "apll", 593 .parent_names = pll_parents, 594 .parent_cnt = nitems(pll_parents), 595 }, 596 .base_offset = 0x00, 597 .gate_offset = 0x200, 598 .gate_shift = 0, 599 .mode_reg = 0x80, 600 .mode_shift = 1, 601 .flags = RK_CLK_PLL_HAVE_GATE, 602 .frac_rates = rk3328_pll_frac_rates, 603}; 604 605static struct rk_clk_pll_def dpll = { 606 .clkdef = { 607 .id = PLL_DPLL, 608 .name = "dpll", 609 .parent_names = pll_parents, 610 .parent_cnt = nitems(pll_parents), 611 }, 612 .base_offset = 0x20, 613 .gate_offset = 0x200, 614 .gate_shift = 1, 615 .mode_reg = 0x80, 616 .mode_shift = 4, 617 .flags = RK_CLK_PLL_HAVE_GATE, 618}; 619 620static struct rk_clk_pll_def cpll = { 621 .clkdef = { 622 .id = PLL_CPLL, 623 .name = "cpll", 624 .parent_names = pll_parents, 625 .parent_cnt = nitems(pll_parents), 626 }, 627 .base_offset = 0x40, 628 .mode_reg = 0x80, 629 .mode_shift = 8, 630 .rates = rk3328_pll_rates, 631}; 632 633static struct rk_clk_pll_def gpll = { 634 .clkdef = { 635 .id = PLL_GPLL, 636 .name = "gpll", 637 .parent_names = pll_parents, 638 .parent_cnt = nitems(pll_parents), 639 }, 640 .base_offset = 0x60, 641 .gate_offset = 0x200, 642 .gate_shift = 2, 643 .mode_reg = 0x80, 644 .mode_shift = 12, 645 .flags = RK_CLK_PLL_HAVE_GATE, 646 .frac_rates = rk3328_pll_frac_rates, 647}; 648 649static struct rk_clk_pll_def npll = { 650 .clkdef = { 651 .id = PLL_NPLL, 652 .name = "npll", 653 .parent_names = pll_parents, 654 .parent_cnt = nitems(pll_parents), 655 }, 656 .base_offset = 0xa0, 657 .gate_offset = 0x200, 658 .gate_shift = 12, 659 .mode_reg = 0x80, 660 .mode_shift = 1, 661 .flags = RK_CLK_PLL_HAVE_GATE, 662 .rates = rk3328_pll_rates, 663}; 664 665/* CRU_CLKSEL_CON0 */ 666#define ACLK_BUS_PRE 136 667 668/* Needs hdmiphy as parent too*/ 669static const char *aclk_bus_pre_parents[] = {"cpll", "gpll"}; 670static struct rk_clk_composite_def aclk_bus_pre = { 671 .clkdef = { 672 .id = ACLK_BUS_PRE, 673 .name = "aclk_bus_pre", 674 .parent_names = aclk_bus_pre_parents, 675 .parent_cnt = nitems(aclk_bus_pre_parents), 676 }, 677 .muxdiv_offset = 0x100, 678 .mux_shift = 13, 679 .mux_width = 2, 680 681 .div_shift = 8, 682 .div_width = 5, 683 684 .gate_offset = 0x220, 685 .gate_shift = 0, 686 687 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 688}; 689 690static struct rk_clk_armclk_rates rk3328_armclk_rates[] = { 691 { 692 .freq = 1296000000, 693 .div = 1, 694 }, 695 { 696 .freq = 1200000000, 697 .div = 1, 698 }, 699 { 700 .freq = 1104000000, 701 .div = 1, 702 }, 703 { 704 .freq = 1008000000, 705 .div = 1, 706 }, 707 { 708 .freq = 912000000, 709 .div = 1, 710 }, 711 { 712 .freq = 816000000, 713 .div = 1, 714 }, 715 { 716 .freq = 696000000, 717 .div = 1, 718 }, 719 { 720 .freq = 600000000, 721 .div = 1, 722 }, 723 { 724 .freq = 408000000, 725 .div = 1, 726 }, 727 { 728 .freq = 312000000, 729 .div = 1, 730 }, 731 { 732 .freq = 216000000, 733 .div = 1, 734 }, 735 { 736 .freq = 96000000, 737 .div = 1, 738 }, 739}; 740 741#define ARMCLK 6 742static const char *armclk_parents[] = {"apll", "gpll", "dpll", "npll" }; 743static struct rk_clk_armclk_def armclk = { 744 .clkdef = { 745 .id = ARMCLK, 746 .name = "armclk", 747 .parent_names = armclk_parents, 748 .parent_cnt = nitems(armclk_parents), 749 }, 750 .muxdiv_offset = 0x100, 751 .mux_shift = 6, 752 .mux_width = 2, 753 754 .div_shift = 0, 755 .div_width = 5, 756 757 .flags = RK_CLK_COMPOSITE_HAVE_MUX, 758 .main_parent = 3, /* npll */ 759 .alt_parent = 0, /* apll */ 760 761 .rates = rk3328_armclk_rates, 762 .nrates = nitems(rk3328_armclk_rates), 763}; 764 765/* CRU_CLKSEL_CON1 */ 766 767#define PCLK_BUS_PRE 216 768#define HCLK_BUS_PRE 328 769 770static const char *hclk_bus_pre_parents[] = {"aclk_bus_pre"}; 771static struct rk_clk_composite_def hclk_bus_pre = { 772 .clkdef = { 773 .id = HCLK_BUS_PRE, 774 .name = "hclk_bus_pre", 775 .parent_names = hclk_bus_pre_parents, 776 .parent_cnt = nitems(hclk_bus_pre_parents), 777 }, 778 .muxdiv_offset = 0x104, 779 780 .div_shift = 8, 781 .div_width = 2, 782 783 .gate_offset = 0x220, 784 .gate_shift = 1, 785 786 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 787}; 788 789static const char *pclk_bus_pre_parents[] = {"aclk_bus_pre"}; 790static struct rk_clk_composite_def pclk_bus_pre = { 791 .clkdef = { 792 .id = PCLK_BUS_PRE, 793 .name = "pclk_bus_pre", 794 .parent_names = pclk_bus_pre_parents, 795 .parent_cnt = nitems(pclk_bus_pre_parents), 796 }, 797 .muxdiv_offset = 0x104, 798 799 .div_shift = 12, 800 .div_width = 3, 801 802 .gate_offset = 0x220, 803 .gate_shift = 2, 804 805 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 806}; 807 808/* CRU_CLKSEL_CON22 */ 809 810#define SCLK_TSADC 36 811 812static const char *clk_tsadc_parents[] = {"xin24m"}; 813static struct rk_clk_composite_def clk_tsadc = { 814 .clkdef = { 815 .id = SCLK_TSADC, 816 .name = "clk_tsadc", 817 .parent_names = clk_tsadc_parents, 818 .parent_cnt = nitems(clk_tsadc_parents), 819 }, 820 .div_shift = 0, 821 .div_width = 9, 822}; 823 824/* CRU_CLKSEL_CON28 */ 825 826#define ACLK_PERI_PRE 137 827 828static const char *aclk_peri_pre_parents[] = {"cpll", "gpll"/* , "hdmiphy" */}; 829static struct rk_clk_composite_def aclk_peri_pre = { 830 .clkdef = { 831 .id = ACLK_PERI_PRE, 832 .name = "aclk_peri_pre", 833 .parent_names = aclk_peri_pre_parents, 834 .parent_cnt = nitems(aclk_peri_pre_parents), 835 }, 836 .muxdiv_offset = 0x170, 837 838 .mux_shift = 6, 839 .mux_width = 2, 840 841 .div_shift = 0, 842 .div_width = 5, 843 844 .flags = RK_CLK_COMPOSITE_HAVE_MUX, 845}; 846 847/* CRU_CLKSEL_CON29 */ 848 849#define PCLK_PERI 230 850#define HCLK_PERI 308 851 852static const char *phclk_peri_parents[] = {"aclk_peri_pre"}; 853static struct rk_clk_composite_def pclk_peri = { 854 .clkdef = { 855 .id = PCLK_PERI, 856 .name = "pclk_peri", 857 .parent_names = phclk_peri_parents, 858 .parent_cnt = nitems(phclk_peri_parents), 859 }, 860 861 .div_shift = 0, 862 .div_width = 2, 863 864 /* CRU_CLKGATE_CON10 */ 865 .gate_offset = 0x228, 866 .gate_shift = 2, 867 868 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 869}; 870 871static struct rk_clk_composite_def hclk_peri = { 872 .clkdef = { 873 .id = HCLK_PERI, 874 .name = "hclk_peri", 875 .parent_names = phclk_peri_parents, 876 .parent_cnt = nitems(phclk_peri_parents), 877 }, 878 879 .div_shift = 4, 880 .div_width = 3, 881 882 /* CRU_CLKGATE_CON10 */ 883 .gate_offset = 0x228, 884 .gate_shift = 1, 885 886 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 887}; 888 889/* CRU_CLKSEL_CON30 */ 890 891#define SCLK_SDMMC 33 892 893static const char *mmc_parents[] = {"cpll", "gpll", "xin24m"/* , "usb480m" */}; 894static struct rk_clk_composite_def sdmmc = { 895 .clkdef = { 896 .id = SCLK_SDMMC, 897 .name = "clk_sdmmc", 898 .parent_names = mmc_parents, 899 .parent_cnt = nitems(mmc_parents), 900 }, 901 .muxdiv_offset = 0x178, 902 903 .mux_shift = 8, 904 .mux_width = 2, 905 906 .div_shift = 0, 907 .div_width = 8, 908 909 /* CRU_CLKGATE_CON4 */ 910 .gate_offset = 0x210, 911 .gate_shift = 3, 912 913 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 914}; 915 916/* CRU_CLKSEL_CON31 */ 917#define SCLK_SDIO 34 918 919static struct rk_clk_composite_def sdio = { 920 .clkdef = { 921 .id = SCLK_SDIO, 922 .name = "clk_sdio", 923 .parent_names = mmc_parents, 924 .parent_cnt = nitems(mmc_parents), 925 }, 926 .muxdiv_offset = 0x17C, 927 928 .mux_shift = 8, 929 .mux_width = 2, 930 931 .div_shift = 0, 932 .div_width = 8, 933 934 /* CRU_CLKGATE_CON4 */ 935 .gate_offset = 0x210, 936 .gate_shift = 4, 937 938 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 939}; 940 941/* CRU_CLKSEL_CON32 */ 942#define SCLK_EMMC 35 943 944static struct rk_clk_composite_def emmc = { 945 .clkdef = { 946 .id = SCLK_EMMC, 947 .name = "clk_emmc", 948 .parent_names = mmc_parents, 949 .parent_cnt = nitems(mmc_parents), 950 }, 951 .muxdiv_offset = 0x180, 952 953 .mux_shift = 8, 954 .mux_width = 2, 955 956 .div_shift = 0, 957 .div_width = 8, 958 959 /* CRU_CLKGATE_CON4 */ 960 .gate_offset = 0x210, 961 .gate_shift = 5, 962 963 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 964}; 965 966/* CRU_CLKSEL_CON34 */ 967#define SCLK_I2C0 55 968#define SCLK_I2C1 56 969 970static const char *i2c_parents[] = {"cpll", "gpll"}; 971 972static struct rk_clk_composite_def i2c0 = { 973 .clkdef = { 974 .id = SCLK_I2C0, 975 .name = "clk_i2c0", 976 .parent_names = i2c_parents, 977 .parent_cnt = nitems(i2c_parents), 978 }, 979 .muxdiv_offset = 0x188, 980 981 .mux_shift = 7, 982 .mux_width = 1, 983 984 .div_shift = 0, 985 .div_width = 6, 986 987 /* CRU_CLKGATE_CON2 */ 988 .gate_offset = 0x208, 989 .gate_shift = 9, 990 991 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 992}; 993 994static struct rk_clk_composite_def i2c1 = { 995 .clkdef = { 996 .id = SCLK_I2C1, 997 .name = "clk_i2c1", 998 .parent_names = i2c_parents, 999 .parent_cnt = nitems(i2c_parents), 1000 }, 1001 .muxdiv_offset = 0x188, 1002 1003 .mux_shift = 15, 1004 .mux_width = 1, 1005 1006 .div_shift = 8, 1007 .div_width = 6, 1008 1009 /* CRU_CLKGATE_CON2 */ 1010 .gate_offset = 0x208, 1011 .gate_shift = 10, 1012 1013 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 1014}; 1015 1016/* CRU_CLKSEL_CON35 */ 1017#define SCLK_I2C2 57 1018#define SCLK_I2C3 58 1019 1020static struct rk_clk_composite_def i2c2 = { 1021 .clkdef = { 1022 .id = SCLK_I2C2, 1023 .name = "clk_i2c2", 1024 .parent_names = i2c_parents, 1025 .parent_cnt = nitems(i2c_parents), 1026 }, 1027 .muxdiv_offset = 0x18C, 1028 1029 .mux_shift = 7, 1030 .mux_width = 1, 1031 1032 .div_shift = 0, 1033 .div_width = 6, 1034 1035 /* CRU_CLKGATE_CON2 */ 1036 .gate_offset = 0x208, 1037 .gate_shift = 11, 1038 1039 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 1040}; 1041 1042static struct rk_clk_composite_def i2c3 = { 1043 .clkdef = { 1044 .id = SCLK_I2C3, 1045 .name = "clk_i2c3", 1046 .parent_names = i2c_parents, 1047 .parent_cnt = nitems(i2c_parents), 1048 }, 1049 .muxdiv_offset = 0x18C, 1050 1051 .mux_shift = 15, 1052 .mux_width = 1, 1053 1054 .div_shift = 8, 1055 .div_width = 6, 1056 1057 /* CRU_CLKGATE_CON2 */ 1058 .gate_offset = 0x208, 1059 .gate_shift = 12, 1060 1061 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, 1062}; 1063 1064#define SCLK_USB3_REF 72 1065#define SCLK_USB3_SUSPEND 73 1066#define SCLK_USB3PHY_REF 94 1067#define SCLK_REF_USB3OTG 95 1068#define SCLK_USB3OTG_SUSPEND 97 1069#define SCLK_REF_USB3OTG_SRC 98 1070 1071static const char *ref_usb3otg_parents[] = { "xin24m", "clk_usb3otg_ref" }; 1072 1073static struct rk_clk_composite_def ref_usb3otg = { 1074 .clkdef = { 1075 .id = SCLK_REF_USB3OTG, 1076 .name = "clk_ref_usb3otg", 1077 .parent_names = ref_usb3otg_parents, 1078 .parent_cnt = nitems(ref_usb3otg_parents), 1079 }, 1080 .muxdiv_offset = 0x1B4, 1081 1082 .mux_shift = 8, 1083 .mux_width = 1, 1084 1085 .flags = RK_CLK_COMPOSITE_HAVE_MUX, 1086}; 1087 1088static const char *usb3otg_suspend_parents[] = { "xin24m"/*, "clk_rtc32k" */}; 1089 1090static struct rk_clk_composite_def usb3otg_suspend = { 1091 .clkdef = { 1092 .id = SCLK_USB3OTG_SUSPEND, 1093 .name = "clk_usb3otg_suspend", 1094 .parent_names = usb3otg_suspend_parents, 1095 .parent_cnt = nitems(usb3otg_suspend_parents), 1096 }, 1097 .muxdiv_offset = 0x184, 1098 1099 .mux_shift = 15, 1100 .mux_width = 1, 1101 1102 .div_shift = 0, 1103 .div_width = 10, 1104 1105 /* CRU_CLKGATE_CON4 */ 1106 .gate_offset = 0x210, 1107 .gate_shift = 8, 1108 1109 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 1110}; 1111 1112static const char *ref_usb3otg_src_parents[] = { "cpll", "gpll" }; 1113 1114static struct rk_clk_composite_def ref_usb3otg_src = { 1115 .clkdef = { 1116 .id = SCLK_REF_USB3OTG_SRC, 1117 .name = "clk_ref_usb3otg_src", 1118 .parent_names = ref_usb3otg_src_parents, 1119 .parent_cnt = nitems(ref_usb3otg_src_parents), 1120 }, 1121 .muxdiv_offset = 0x1B4, 1122 1123 .mux_shift = 7, 1124 .mux_width = 1, 1125 1126 .div_shift = 0, 1127 .div_width = 7, 1128 1129 /* CRU_CLKGATE_CON4 */ 1130 .gate_offset = 0x210, 1131 .gate_shift = 9, 1132 1133 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 1134}; 1135 1136/* I2S0 */ 1137static const char *i2s0_div_parents[] = { "cpll", "gpll" }; 1138static struct rk_clk_composite_def i2s0_div = { 1139 .clkdef = { 1140 .id = 0, 1141 .name = "clk_i2s0_div", 1142 .parent_names = i2s0_div_parents, 1143 .parent_cnt = nitems(i2s0_div_parents), 1144 }, 1145 /* CRU_CLKSEL_CON6 */ 1146 .muxdiv_offset = 0x118, 1147 1148 .mux_shift = 15, 1149 .mux_width = 1, 1150 1151 .div_shift = 0, 1152 .div_width = 7, 1153 1154 /* CRU_CLKGATE_CON1 */ 1155 .gate_offset = 0x204, 1156 .gate_shift = 1, 1157 1158 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 1159}; 1160 1161static const char *i2s0_frac_parents[] = { "clk_i2s0_div" }; 1162static struct rk_clk_fract_def i2s0_frac = { 1163 .clkdef = { 1164 .id = 0, 1165 .name = "clk_i2s0_frac", 1166 .parent_names = i2s0_frac_parents, 1167 .parent_cnt = nitems(i2s0_frac_parents), 1168 }, 1169 /* CRU_CLKSEL_CON7 */ 1170 .offset = 0x11c, 1171 1172 /* CRU_CLKGATE_CON1 */ 1173 .gate_offset = 0x204, 1174 .gate_shift = 2, 1175 1176 .flags = RK_CLK_FRACT_HAVE_GATE, 1177}; 1178 1179static const char *i2s0_mux_parents[] = { "clk_i2s0_div", "clk_i2s0_frac", "xin12m", "xin12m" }; 1180static struct rk_clk_mux_def i2s0_mux = { 1181 .clkdef = { 1182 .id = 0, 1183 .name = "clk_i2s0_mux", 1184 .parent_names = i2s0_mux_parents, 1185 .parent_cnt = nitems(i2s0_mux_parents), 1186 }, 1187 .offset = 0x118, 1188 1189 .shift = 8, 1190 .width = 2, 1191 1192 .mux_flags = RK_CLK_MUX_REPARENT, 1193}; 1194 1195/* I2S1 */ 1196static const char *i2s1_div_parents[] = { "cpll", "gpll" }; 1197static struct rk_clk_composite_def i2s1_div = { 1198 .clkdef = { 1199 .id = 0, 1200 .name = "clk_i2s1_div", 1201 .parent_names = i2s1_div_parents, 1202 .parent_cnt = nitems(i2s1_div_parents), 1203 }, 1204 /* CRU_CLKSEL_CON8 */ 1205 .muxdiv_offset = 0x120, 1206 1207 .mux_shift = 15, 1208 .mux_width = 1, 1209 1210 .div_shift = 0, 1211 .div_width = 7, 1212 1213 /* CRU_CLKGATE_CON1 */ 1214 .gate_offset = 0x204, 1215 .gate_shift = 4, 1216 1217 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 1218}; 1219 1220static const char *i2s1_frac_parents[] = { "clk_i2s1_div" }; 1221static struct rk_clk_fract_def i2s1_frac = { 1222 .clkdef = { 1223 .id = 0, 1224 .name = "clk_i2s1_frac", 1225 .parent_names = i2s1_frac_parents, 1226 .parent_cnt = nitems(i2s1_frac_parents), 1227 }, 1228 /* CRU_CLKSEL_CON9 */ 1229 .offset = 0x124, 1230 1231 /* CRU_CLKGATE_CON1 */ 1232 .gate_offset = 0x204, 1233 .gate_shift = 5, 1234 1235 .flags = RK_CLK_FRACT_HAVE_GATE, 1236}; 1237 1238static const char *i2s1_mux_parents[] = { "clk_i2s1_div", "clk_i2s1_frac", "clkin_i2s1", "xin12m" }; 1239static struct rk_clk_mux_def i2s1_mux = { 1240 .clkdef = { 1241 .id = 0, 1242 .name = "clk_i2s1_mux", 1243 .parent_names = i2s1_mux_parents, 1244 .parent_cnt = nitems(i2s1_mux_parents), 1245 }, 1246 .offset = 0x120, 1247 1248 .shift = 8, 1249 .width = 2, 1250 .mux_flags = RK_CLK_MUX_REPARENT, 1251}; 1252 1253static struct clk_fixed_def clkin_i2s1 = { 1254 .clkdef = { 1255 .id = 0, 1256 .name = "clkin_i2s1", 1257 .parent_names = NULL, 1258 .parent_cnt = 0 1259 }, 1260 1261 .freq = 0, 1262}; 1263 1264/* I2S2 */ 1265static const char *i2s2_div_parents[] = { "cpll", "gpll" }; 1266static struct rk_clk_composite_def i2s2_div = { 1267 .clkdef = { 1268 .id = 0, 1269 .name = "clk_i2s2_div", 1270 .parent_names = i2s2_div_parents, 1271 .parent_cnt = nitems(i2s2_div_parents), 1272 }, 1273 /* CRU_CLKSEL_CON10 */ 1274 .muxdiv_offset = 0x128, 1275 1276 .mux_shift = 15, 1277 .mux_width = 1, 1278 1279 .div_shift = 0, 1280 .div_width = 7, 1281 1282 /* CRU_CLKGATE_CON1 */ 1283 .gate_offset = 0x204, 1284 .gate_shift = 8, 1285 1286 .flags = RK_CLK_COMPOSITE_HAVE_GATE, 1287}; 1288 1289static const char *i2s2_frac_parents[] = { "clk_i2s2_div" }; 1290static struct rk_clk_fract_def i2s2_frac = { 1291 .clkdef = { 1292 .id = 0, 1293 .name = "clk_i2s2_frac", 1294 .parent_names = i2s2_frac_parents, 1295 .parent_cnt = nitems(i2s2_frac_parents), 1296 }, 1297 /* CRU_CLKSEL_CON11 */ 1298 .offset = 0x12c, 1299 1300 /* CRU_CLKGATE_CON1 */ 1301 .gate_offset = 0x204, 1302 .gate_shift = 9, 1303 1304 .flags = RK_CLK_FRACT_HAVE_GATE, 1305}; 1306 1307static const char *i2s2_mux_parents[] = { "clk_i2s2_div", "clk_i2s2_frac", "clkin_i2s2", "xin12m" }; 1308static struct rk_clk_mux_def i2s2_mux = { 1309 .clkdef = { 1310 .id = 0, 1311 .name = "clk_i2s2_mux", 1312 .parent_names = i2s2_mux_parents, 1313 .parent_cnt = nitems(i2s2_mux_parents), 1314 }, 1315 .offset = 0x128, 1316 1317 .shift = 8, 1318 .width = 2, 1319 1320 .mux_flags = RK_CLK_MUX_REPARENT, 1321}; 1322 1323static struct clk_fixed_def clkin_i2s2 = { 1324 .clkdef = { 1325 .id = 0, 1326 .name = "clkin_i2s2", 1327 .parent_names = NULL, 1328 .parent_cnt = 0 1329 }, 1330 1331 .freq = 0, 1332}; 1333 1334static struct clk_fixed_def xin12m = { 1335 .clkdef = { 1336 .id = 0, 1337 .name = "xin12m", 1338 .parent_names = NULL, 1339 .parent_cnt = 0 1340 }, 1341 1342 .freq = 12000000, 1343}; 1344 1345static const char *mac2io_src_parents[] = { "cpll", "gpll" }; 1346 1347static struct rk_clk_composite_def mac2io_src = { 1348 .clkdef = { 1349 .id = SCLK_MAC2IO_SRC, 1350 .name = "clk_mac2io_src", 1351 .parent_names = mac2io_src_parents, 1352 .parent_cnt = nitems(mac2io_src_parents), 1353 }, 1354 /* CRU_CLKSEL_CON27 */ 1355 .muxdiv_offset = 0x16c, 1356 1357 .mux_shift = 7, 1358 .mux_width = 1, 1359 1360 .div_shift = 0, 1361 .div_width = 5, 1362 1363 /* CRU_CLKGATE_CON3 */ 1364 .gate_offset = 0x20c, 1365 .gate_shift = 1, 1366 1367 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX, 1368}; 1369 1370static const char *mac2io_out_parents[] = { "cpll", "gpll" }; 1371 1372static struct rk_clk_composite_def mac2io_out = { 1373 .clkdef = { 1374 .id = SCLK_MAC2IO_OUT, 1375 .name = "clk_mac2io_out", 1376 .parent_names = mac2io_out_parents, 1377 .parent_cnt = nitems(mac2io_out_parents), 1378 }, 1379 /* CRU_CLKSEL_CON27 */ 1380 .muxdiv_offset = 0x16c, 1381 1382 .mux_shift = 15, 1383 .mux_width = 1, 1384 1385 .div_shift = 8, 1386 .div_width = 5, 1387 1388 /* CRU_CLKGATE_CON3 */ 1389 .gate_offset = 0x20c, 1390 .gate_shift = 5, 1391 1392 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX, 1393}; 1394 1395static const char *mac2io_parents[] = { "clk_mac2io_src", "gmac_clkin" }; 1396 1397static struct rk_clk_composite_def mac2io = { 1398 .clkdef = { 1399 .id = SCLK_MAC2IO, 1400 .name = "clk_mac2io", 1401 .parent_names = mac2io_parents, 1402 .parent_cnt = nitems(mac2io_parents), 1403 }, 1404 .muxdiv_offset = RK3328_GRF_MAC_CON1, 1405 1406 .mux_shift = 10, 1407 .mux_width = 1, 1408 1409 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF 1410}; 1411 1412static const char *mac2io_ext_parents[] = { "clk_mac2io", "gmac_clkin" }; 1413 1414static struct rk_clk_composite_def mac2io_ext = { 1415 .clkdef = { 1416 .id = SCLK_MAC2IO_EXT, 1417 .name = "clk_mac2io_ext", 1418 .parent_names = mac2io_ext_parents, 1419 .parent_cnt = nitems(mac2io_ext_parents), 1420 }, 1421 .muxdiv_offset = RK3328_GRF_SOC_CON4, 1422 1423 .mux_shift = 14, 1424 .mux_width = 1, 1425 1426 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF 1427}; 1428 1429static const char *mac2phy_src_parents[] = { "cpll", "gpll" }; 1430 1431static struct rk_clk_composite_def mac2phy_src = { 1432 .clkdef = { 1433 .id = SCLK_MAC2PHY_SRC, 1434 .name = "clk_mac2phy_src", 1435 .parent_names = mac2phy_src_parents, 1436 .parent_cnt = nitems(mac2phy_src_parents), 1437 }, 1438 /* CRU_CLKSEL_CON26 */ 1439 .muxdiv_offset = 0x168, 1440 1441 .mux_shift = 7, 1442 .mux_width = 1, 1443 1444 .div_shift = 0, 1445 .div_width = 5, 1446 1447 /* CRU_CLKGATE_CON3 */ 1448 .gate_offset = 0x20c, 1449 .gate_shift = 0, 1450 1451 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX, 1452}; 1453 1454static const char *mac2phy_parents[] = { "clk_mac2phy_src", "phy_50m_out" }; 1455 1456static struct rk_clk_composite_def mac2phy = { 1457 .clkdef = { 1458 .id = SCLK_MAC2PHY, 1459 .name = "clk_mac2phy", 1460 .parent_names = mac2phy_parents, 1461 .parent_cnt = nitems(mac2phy_parents), 1462 }, 1463 .muxdiv_offset = RK3328_GRF_MAC_CON2, 1464 1465 .mux_shift = 10, 1466 .mux_width = 1, 1467 1468 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_GRF 1469}; 1470 1471static const char *mac2phy_out_parents[] = { "clk_mac2phy" }; 1472 1473static struct rk_clk_composite_def mac2phy_out = { 1474 .clkdef = { 1475 .id = SCLK_MAC2PHY_OUT, 1476 .name = "clk_mac2phy_out", 1477 .parent_names = mac2phy_out_parents, 1478 .parent_cnt = nitems(mac2phy_out_parents), 1479 }, 1480 /* CRU_CLKSEL_CON26 */ 1481 .muxdiv_offset = 0x168, 1482 1483 .div_shift = 8, 1484 .div_width = 2, 1485 1486 /* CRU_CLKGATE_CON9 */ 1487 .gate_offset = 0x224, 1488 .gate_shift = 2, 1489 1490 .flags = RK_CLK_COMPOSITE_HAVE_GATE 1491}; 1492 1493static struct clk_fixed_def phy_50m_out = { 1494 .clkdef.name = "phy_50m_out", 1495 .freq = 50000000, 1496}; 1497 1498static struct clk_link_def gmac_clkin = { 1499 .clkdef.name = "gmac_clkin", 1500}; 1501 1502static const char *aclk_gmac_parents[] = { "cpll", "gpll" }; 1503 1504static struct rk_clk_composite_def aclk_gmac = { 1505 .clkdef = { 1506 .id = ACLK_GMAC, 1507 .name = "aclk_gmac", 1508 .parent_names = aclk_gmac_parents, 1509 .parent_cnt = nitems(aclk_gmac_parents), 1510 }, 1511 /* CRU_CLKSEL_CON35 */ 1512 .muxdiv_offset = 0x18c, 1513 1514 .mux_shift = 6, 1515 .mux_width = 2, 1516 1517 .div_shift = 0, 1518 .div_width = 5, 1519 1520 /* CRU_CLKGATE_CON3 */ 1521 .gate_offset = 0x20c, 1522 .gate_shift = 2, 1523 1524 .flags = RK_CLK_COMPOSITE_HAVE_GATE | RK_CLK_COMPOSITE_HAVE_MUX, 1525}; 1526 1527static const char *pclk_gmac_parents[] = { "aclk_gmac" }; 1528 1529static struct rk_clk_composite_def pclk_gmac = { 1530 .clkdef = { 1531 .id = PCLK_GMAC, 1532 .name = "pclk_gmac", 1533 .parent_names = pclk_gmac_parents, 1534 .parent_cnt = nitems(pclk_gmac_parents), 1535 }, 1536 /* CRU_CLKSEL_CON25 */ 1537 .muxdiv_offset = 0x164, 1538 1539 .div_shift = 8, 1540 .div_width = 3, 1541 1542 /* CRU_CLKGATE_CON9 */ 1543 .gate_offset = 0x224, 1544 .gate_shift = 0, 1545 1546 .flags = RK_CLK_COMPOSITE_HAVE_GATE 1547}; 1548 1549static struct rk_clk rk3328_clks[] = { 1550 { 1551 .type = RK3328_CLK_PLL, 1552 .clk.pll = &apll 1553 }, 1554 { 1555 .type = RK3328_CLK_PLL, 1556 .clk.pll = &dpll 1557 }, 1558 { 1559 .type = RK3328_CLK_PLL, 1560 .clk.pll = &cpll 1561 }, 1562 { 1563 .type = RK3328_CLK_PLL, 1564 .clk.pll = &gpll 1565 }, 1566 { 1567 .type = RK3328_CLK_PLL, 1568 .clk.pll = &npll 1569 }, 1570 1571 { 1572 .type = RK_CLK_COMPOSITE, 1573 .clk.composite = &aclk_bus_pre 1574 }, 1575 { 1576 .type = RK_CLK_COMPOSITE, 1577 .clk.composite = &hclk_bus_pre 1578 }, 1579 { 1580 .type = RK_CLK_COMPOSITE, 1581 .clk.composite = &pclk_bus_pre 1582 }, 1583 1584 { 1585 .type = RK_CLK_ARMCLK, 1586 .clk.armclk = &armclk, 1587 }, 1588 1589 { 1590 .type = RK_CLK_COMPOSITE, 1591 .clk.composite = &clk_tsadc, 1592 }, 1593 { 1594 .type = RK_CLK_COMPOSITE, 1595 .clk.composite = &aclk_peri_pre, 1596 }, 1597 { 1598 .type = RK_CLK_COMPOSITE, 1599 .clk.composite = &pclk_peri, 1600 }, 1601 { 1602 .type = RK_CLK_COMPOSITE, 1603 .clk.composite = &hclk_peri, 1604 }, 1605 { 1606 .type = RK_CLK_COMPOSITE, 1607 .clk.composite = &sdmmc 1608 }, 1609 { 1610 .type = RK_CLK_COMPOSITE, 1611 .clk.composite = &sdio 1612 }, 1613 { 1614 .type = RK_CLK_COMPOSITE, 1615 .clk.composite = &emmc 1616 }, 1617 1618 { 1619 .type = RK_CLK_COMPOSITE, 1620 .clk.composite = &i2c0 1621 }, 1622 { 1623 .type = RK_CLK_COMPOSITE, 1624 .clk.composite = &i2c1 1625 }, 1626 { 1627 .type = RK_CLK_COMPOSITE, 1628 .clk.composite = &i2c2 1629 }, 1630 { 1631 .type = RK_CLK_COMPOSITE, 1632 .clk.composite = &i2c3 1633 }, 1634 1635 { 1636 .type = RK_CLK_COMPOSITE, 1637 .clk.composite = &ref_usb3otg 1638 }, 1639 { 1640 .type = RK_CLK_COMPOSITE, 1641 .clk.composite = &ref_usb3otg_src 1642 }, 1643 { 1644 .type = RK_CLK_COMPOSITE, 1645 .clk.composite = &usb3otg_suspend 1646 }, 1647 { 1648 .type = RK_CLK_COMPOSITE, 1649 .clk.composite = &i2s0_div 1650 }, 1651 { 1652 .type = RK_CLK_FRACT, 1653 .clk.fract = &i2s0_frac 1654 }, 1655 { 1656 .type = RK_CLK_MUX, 1657 .clk.mux = &i2s0_mux 1658 }, 1659 { 1660 .type = RK_CLK_COMPOSITE, 1661 .clk.composite = &i2s1_div 1662 }, 1663 { 1664 .type = RK_CLK_FRACT, 1665 .clk.fract = &i2s1_frac 1666 }, 1667 { 1668 .type = RK_CLK_MUX, 1669 .clk.mux = &i2s1_mux 1670 }, 1671 { 1672 .type = RK_CLK_FIXED, 1673 .clk.fixed = &clkin_i2s1 1674 }, 1675 { 1676 .type = RK_CLK_COMPOSITE, 1677 .clk.composite = &i2s2_div 1678 }, 1679 { 1680 .type = RK_CLK_FRACT, 1681 .clk.fract = &i2s2_frac 1682 }, 1683 { 1684 .type = RK_CLK_MUX, 1685 .clk.mux = &i2s2_mux 1686 }, 1687 { 1688 .type = RK_CLK_FIXED, 1689 .clk.fixed = &clkin_i2s2 1690 }, 1691 { 1692 .type = RK_CLK_FIXED, 1693 .clk.fixed = &xin12m 1694 }, 1695 { 1696 .type = RK_CLK_COMPOSITE, 1697 .clk.composite = &mac2io_src 1698 }, 1699 { 1700 .type = RK_CLK_COMPOSITE, 1701 .clk.composite = &mac2io 1702 }, 1703 { 1704 .type = RK_CLK_COMPOSITE, 1705 .clk.composite = &mac2io_out 1706 }, 1707 { 1708 .type = RK_CLK_COMPOSITE, 1709 .clk.composite = &mac2io_ext 1710 }, 1711 { 1712 .type = RK_CLK_COMPOSITE, 1713 .clk.composite = &mac2phy_src 1714 }, 1715 { 1716 .type = RK_CLK_COMPOSITE, 1717 .clk.composite = &mac2phy 1718 }, 1719 { 1720 .type = RK_CLK_COMPOSITE, 1721 .clk.composite = &mac2phy_out 1722 }, 1723 { 1724 .type = RK_CLK_FIXED, 1725 .clk.fixed = &phy_50m_out 1726 }, 1727 { 1728 .type = RK_CLK_LINK, 1729 .clk.link = &gmac_clkin 1730 }, 1731 { 1732 .type = RK_CLK_COMPOSITE, 1733 .clk.composite = &aclk_gmac 1734 }, 1735 { 1736 .type = RK_CLK_COMPOSITE, 1737 .clk.composite = &pclk_gmac 1738 }, 1739}; 1740 1741static int 1742rk3328_cru_probe(device_t dev) 1743{ 1744 1745 if (!ofw_bus_status_okay(dev)) 1746 return (ENXIO); 1747 1748 if (ofw_bus_is_compatible(dev, "rockchip,rk3328-cru")) { 1749 device_set_desc(dev, "Rockchip RK3328 Clock and Reset Unit"); 1750 return (BUS_PROBE_DEFAULT); 1751 } 1752 1753 return (ENXIO); 1754} 1755 1756static int 1757rk3328_cru_attach(device_t dev) 1758{ 1759 struct rk_cru_softc *sc; 1760 1761 sc = device_get_softc(dev); 1762 sc->dev = dev; 1763 1764 sc->gates = rk3328_gates; 1765 sc->ngates = nitems(rk3328_gates); 1766 1767 sc->clks = rk3328_clks; 1768 sc->nclks = nitems(rk3328_clks); 1769 1770 sc->reset_offset = 0x300; 1771 sc->reset_num = 184; 1772 1773 return (rk_cru_attach(dev)); 1774} 1775 1776static device_method_t rk3328_cru_methods[] = { 1777 /* Device interface */ 1778 DEVMETHOD(device_probe, rk3328_cru_probe), 1779 DEVMETHOD(device_attach, rk3328_cru_attach), 1780 1781 DEVMETHOD_END 1782}; 1783 1784static devclass_t rk3328_cru_devclass; 1785 1786DEFINE_CLASS_1(rk3328_cru, rk3328_cru_driver, rk3328_cru_methods, 1787 sizeof(struct rk_cru_softc), rk_cru_driver); 1788 1789EARLY_DRIVER_MODULE(rk3328_cru, simplebus, rk3328_cru_driver, 1790 rk3328_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); 1791