1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * AmLogic Meson-AXG Clock Controller Driver 4 * 5 * Copyright (c) 2016 Baylibre SAS. 6 * Author: Michael Turquette <mturquette@baylibre.com> 7 * 8 * Copyright (c) 2017 Amlogic, inc. 9 * Author: Qiufang Dai <qiufang.dai@amlogic.com> 10 */ 11 12 #include <linux/clk.h> 13 #include <linux/clk-provider.h> 14 #include <linux/init.h> 15 #include <linux/of_device.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/platform_device.h> 18 #include <linux/regmap.h> 19 20 #include "clkc.h" 21 #include "axg.h" 22 23 static DEFINE_SPINLOCK(meson_clk_lock); 24 25 static struct clk_regmap axg_fixed_pll_dco = { 26 .data = &(struct meson_clk_pll_data){ 27 .en = { 28 .reg_off = HHI_MPLL_CNTL, 29 .shift = 30, 30 .width = 1, 31 }, 32 .m = { 33 .reg_off = HHI_MPLL_CNTL, 34 .shift = 0, 35 .width = 9, 36 }, 37 .n = { 38 .reg_off = HHI_MPLL_CNTL, 39 .shift = 9, 40 .width = 5, 41 }, 42 .frac = { 43 .reg_off = HHI_MPLL_CNTL2, 44 .shift = 0, 45 .width = 12, 46 }, 47 .l = { 48 .reg_off = HHI_MPLL_CNTL, 49 .shift = 31, 50 .width = 1, 51 }, 52 .rst = { 53 .reg_off = HHI_MPLL_CNTL, 54 .shift = 29, 55 .width = 1, 56 }, 57 }, 58 .hw.init = &(struct clk_init_data){ 59 .name = "fixed_pll_dco", 60 .ops = &meson_clk_pll_ro_ops, 61 .parent_names = (const char *[]){ "xtal" }, 62 .num_parents = 1, 63 }, 64 }; 65 66 static struct clk_regmap axg_fixed_pll = { 67 .data = &(struct clk_regmap_div_data){ 68 .offset = HHI_MPLL_CNTL, 69 .shift = 16, 70 .width = 2, 71 .flags = CLK_DIVIDER_POWER_OF_TWO, 72 }, 73 .hw.init = &(struct clk_init_data){ 74 .name = "fixed_pll", 75 .ops = &clk_regmap_divider_ro_ops, 76 .parent_names = (const char *[]){ "fixed_pll_dco" }, 77 .num_parents = 1, 78 /* 79 * This clock won't ever change at runtime so 80 * CLK_SET_RATE_PARENT is not required 81 */ 82 }, 83 }; 84 85 static struct clk_regmap axg_sys_pll_dco = { 86 .data = &(struct meson_clk_pll_data){ 87 .en = { 88 .reg_off = HHI_SYS_PLL_CNTL, 89 .shift = 30, 90 .width = 1, 91 }, 92 .m = { 93 .reg_off = HHI_SYS_PLL_CNTL, 94 .shift = 0, 95 .width = 9, 96 }, 97 .n = { 98 .reg_off = HHI_SYS_PLL_CNTL, 99 .shift = 9, 100 .width = 5, 101 }, 102 .l = { 103 .reg_off = HHI_SYS_PLL_CNTL, 104 .shift = 31, 105 .width = 1, 106 }, 107 .rst = { 108 .reg_off = HHI_SYS_PLL_CNTL, 109 .shift = 29, 110 .width = 1, 111 }, 112 }, 113 .hw.init = &(struct clk_init_data){ 114 .name = "sys_pll_dco", 115 .ops = &meson_clk_pll_ro_ops, 116 .parent_names = (const char *[]){ "xtal" }, 117 .num_parents = 1, 118 }, 119 }; 120 121 static struct clk_regmap axg_sys_pll = { 122 .data = &(struct clk_regmap_div_data){ 123 .offset = HHI_SYS_PLL_CNTL, 124 .shift = 16, 125 .width = 2, 126 .flags = CLK_DIVIDER_POWER_OF_TWO, 127 }, 128 .hw.init = &(struct clk_init_data){ 129 .name = "sys_pll", 130 .ops = &clk_regmap_divider_ro_ops, 131 .parent_names = (const char *[]){ "sys_pll_dco" }, 132 .num_parents = 1, 133 .flags = CLK_SET_RATE_PARENT, 134 }, 135 }; 136 137 static const struct pll_params_table axg_gp0_pll_params_table[] = { 138 PLL_PARAMS(40, 1), 139 PLL_PARAMS(41, 1), 140 PLL_PARAMS(42, 1), 141 PLL_PARAMS(43, 1), 142 PLL_PARAMS(44, 1), 143 PLL_PARAMS(45, 1), 144 PLL_PARAMS(46, 1), 145 PLL_PARAMS(47, 1), 146 PLL_PARAMS(48, 1), 147 PLL_PARAMS(49, 1), 148 PLL_PARAMS(50, 1), 149 PLL_PARAMS(51, 1), 150 PLL_PARAMS(52, 1), 151 PLL_PARAMS(53, 1), 152 PLL_PARAMS(54, 1), 153 PLL_PARAMS(55, 1), 154 PLL_PARAMS(56, 1), 155 PLL_PARAMS(57, 1), 156 PLL_PARAMS(58, 1), 157 PLL_PARAMS(59, 1), 158 PLL_PARAMS(60, 1), 159 PLL_PARAMS(61, 1), 160 PLL_PARAMS(62, 1), 161 PLL_PARAMS(63, 1), 162 PLL_PARAMS(64, 1), 163 PLL_PARAMS(65, 1), 164 PLL_PARAMS(66, 1), 165 PLL_PARAMS(67, 1), 166 PLL_PARAMS(68, 1), 167 { /* sentinel */ }, 168 }; 169 170 static const struct reg_sequence axg_gp0_init_regs[] = { 171 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 }, 172 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be }, 173 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, 174 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, 175 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, 176 }; 177 178 static struct clk_regmap axg_gp0_pll_dco = { 179 .data = &(struct meson_clk_pll_data){ 180 .en = { 181 .reg_off = HHI_GP0_PLL_CNTL, 182 .shift = 30, 183 .width = 1, 184 }, 185 .m = { 186 .reg_off = HHI_GP0_PLL_CNTL, 187 .shift = 0, 188 .width = 9, 189 }, 190 .n = { 191 .reg_off = HHI_GP0_PLL_CNTL, 192 .shift = 9, 193 .width = 5, 194 }, 195 .frac = { 196 .reg_off = HHI_GP0_PLL_CNTL1, 197 .shift = 0, 198 .width = 10, 199 }, 200 .l = { 201 .reg_off = HHI_GP0_PLL_CNTL, 202 .shift = 31, 203 .width = 1, 204 }, 205 .rst = { 206 .reg_off = HHI_GP0_PLL_CNTL, 207 .shift = 29, 208 .width = 1, 209 }, 210 .table = axg_gp0_pll_params_table, 211 .init_regs = axg_gp0_init_regs, 212 .init_count = ARRAY_SIZE(axg_gp0_init_regs), 213 }, 214 .hw.init = &(struct clk_init_data){ 215 .name = "gp0_pll_dco", 216 .ops = &meson_clk_pll_ops, 217 .parent_names = (const char *[]){ "xtal" }, 218 .num_parents = 1, 219 }, 220 }; 221 222 static struct clk_regmap axg_gp0_pll = { 223 .data = &(struct clk_regmap_div_data){ 224 .offset = HHI_GP0_PLL_CNTL, 225 .shift = 16, 226 .width = 2, 227 .flags = CLK_DIVIDER_POWER_OF_TWO, 228 }, 229 .hw.init = &(struct clk_init_data){ 230 .name = "gp0_pll", 231 .ops = &clk_regmap_divider_ops, 232 .parent_names = (const char *[]){ "gp0_pll_dco" }, 233 .num_parents = 1, 234 .flags = CLK_SET_RATE_PARENT, 235 }, 236 }; 237 238 static const struct reg_sequence axg_hifi_init_regs[] = { 239 { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, 240 { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, 241 { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 }, 242 { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d }, 243 { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, 244 }; 245 246 static struct clk_regmap axg_hifi_pll_dco = { 247 .data = &(struct meson_clk_pll_data){ 248 .en = { 249 .reg_off = HHI_HIFI_PLL_CNTL, 250 .shift = 30, 251 .width = 1, 252 }, 253 .m = { 254 .reg_off = HHI_HIFI_PLL_CNTL, 255 .shift = 0, 256 .width = 9, 257 }, 258 .n = { 259 .reg_off = HHI_HIFI_PLL_CNTL, 260 .shift = 9, 261 .width = 5, 262 }, 263 .frac = { 264 .reg_off = HHI_HIFI_PLL_CNTL5, 265 .shift = 0, 266 .width = 13, 267 }, 268 .l = { 269 .reg_off = HHI_HIFI_PLL_CNTL, 270 .shift = 31, 271 .width = 1, 272 }, 273 .rst = { 274 .reg_off = HHI_HIFI_PLL_CNTL, 275 .shift = 29, 276 .width = 1, 277 }, 278 .table = axg_gp0_pll_params_table, 279 .init_regs = axg_hifi_init_regs, 280 .init_count = ARRAY_SIZE(axg_hifi_init_regs), 281 .flags = CLK_MESON_PLL_ROUND_CLOSEST, 282 }, 283 .hw.init = &(struct clk_init_data){ 284 .name = "hifi_pll_dco", 285 .ops = &meson_clk_pll_ops, 286 .parent_names = (const char *[]){ "xtal" }, 287 .num_parents = 1, 288 }, 289 }; 290 291 static struct clk_regmap axg_hifi_pll = { 292 .data = &(struct clk_regmap_div_data){ 293 .offset = HHI_HIFI_PLL_CNTL, 294 .shift = 16, 295 .width = 2, 296 .flags = CLK_DIVIDER_POWER_OF_TWO, 297 }, 298 .hw.init = &(struct clk_init_data){ 299 .name = "hifi_pll", 300 .ops = &clk_regmap_divider_ops, 301 .parent_names = (const char *[]){ "hifi_pll_dco" }, 302 .num_parents = 1, 303 .flags = CLK_SET_RATE_PARENT, 304 }, 305 }; 306 307 static struct clk_fixed_factor axg_fclk_div2_div = { 308 .mult = 1, 309 .div = 2, 310 .hw.init = &(struct clk_init_data){ 311 .name = "fclk_div2_div", 312 .ops = &clk_fixed_factor_ops, 313 .parent_names = (const char *[]){ "fixed_pll" }, 314 .num_parents = 1, 315 }, 316 }; 317 318 static struct clk_regmap axg_fclk_div2 = { 319 .data = &(struct clk_regmap_gate_data){ 320 .offset = HHI_MPLL_CNTL6, 321 .bit_idx = 27, 322 }, 323 .hw.init = &(struct clk_init_data){ 324 .name = "fclk_div2", 325 .ops = &clk_regmap_gate_ops, 326 .parent_names = (const char *[]){ "fclk_div2_div" }, 327 .num_parents = 1, 328 .flags = CLK_IS_CRITICAL, 329 }, 330 }; 331 332 static struct clk_fixed_factor axg_fclk_div3_div = { 333 .mult = 1, 334 .div = 3, 335 .hw.init = &(struct clk_init_data){ 336 .name = "fclk_div3_div", 337 .ops = &clk_fixed_factor_ops, 338 .parent_names = (const char *[]){ "fixed_pll" }, 339 .num_parents = 1, 340 }, 341 }; 342 343 static struct clk_regmap axg_fclk_div3 = { 344 .data = &(struct clk_regmap_gate_data){ 345 .offset = HHI_MPLL_CNTL6, 346 .bit_idx = 28, 347 }, 348 .hw.init = &(struct clk_init_data){ 349 .name = "fclk_div3", 350 .ops = &clk_regmap_gate_ops, 351 .parent_names = (const char *[]){ "fclk_div3_div" }, 352 .num_parents = 1, 353 /* 354 * FIXME: 355 * This clock, as fdiv2, is used by the SCPI FW and is required 356 * by the platform to operate correctly. 357 * Until the following condition are met, we need this clock to 358 * be marked as critical: 359 * a) The SCPI generic driver claims and enable all the clocks 360 * it needs 361 * b) CCF has a clock hand-off mechanism to make the sure the 362 * clock stays on until the proper driver comes along 363 */ 364 .flags = CLK_IS_CRITICAL, 365 }, 366 }; 367 368 static struct clk_fixed_factor axg_fclk_div4_div = { 369 .mult = 1, 370 .div = 4, 371 .hw.init = &(struct clk_init_data){ 372 .name = "fclk_div4_div", 373 .ops = &clk_fixed_factor_ops, 374 .parent_names = (const char *[]){ "fixed_pll" }, 375 .num_parents = 1, 376 }, 377 }; 378 379 static struct clk_regmap axg_fclk_div4 = { 380 .data = &(struct clk_regmap_gate_data){ 381 .offset = HHI_MPLL_CNTL6, 382 .bit_idx = 29, 383 }, 384 .hw.init = &(struct clk_init_data){ 385 .name = "fclk_div4", 386 .ops = &clk_regmap_gate_ops, 387 .parent_names = (const char *[]){ "fclk_div4_div" }, 388 .num_parents = 1, 389 }, 390 }; 391 392 static struct clk_fixed_factor axg_fclk_div5_div = { 393 .mult = 1, 394 .div = 5, 395 .hw.init = &(struct clk_init_data){ 396 .name = "fclk_div5_div", 397 .ops = &clk_fixed_factor_ops, 398 .parent_names = (const char *[]){ "fixed_pll" }, 399 .num_parents = 1, 400 }, 401 }; 402 403 static struct clk_regmap axg_fclk_div5 = { 404 .data = &(struct clk_regmap_gate_data){ 405 .offset = HHI_MPLL_CNTL6, 406 .bit_idx = 30, 407 }, 408 .hw.init = &(struct clk_init_data){ 409 .name = "fclk_div5", 410 .ops = &clk_regmap_gate_ops, 411 .parent_names = (const char *[]){ "fclk_div5_div" }, 412 .num_parents = 1, 413 }, 414 }; 415 416 static struct clk_fixed_factor axg_fclk_div7_div = { 417 .mult = 1, 418 .div = 7, 419 .hw.init = &(struct clk_init_data){ 420 .name = "fclk_div7_div", 421 .ops = &clk_fixed_factor_ops, 422 .parent_names = (const char *[]){ "fixed_pll" }, 423 .num_parents = 1, 424 }, 425 }; 426 427 static struct clk_regmap axg_fclk_div7 = { 428 .data = &(struct clk_regmap_gate_data){ 429 .offset = HHI_MPLL_CNTL6, 430 .bit_idx = 31, 431 }, 432 .hw.init = &(struct clk_init_data){ 433 .name = "fclk_div7", 434 .ops = &clk_regmap_gate_ops, 435 .parent_names = (const char *[]){ "fclk_div7_div" }, 436 .num_parents = 1, 437 }, 438 }; 439 440 static struct clk_regmap axg_mpll_prediv = { 441 .data = &(struct clk_regmap_div_data){ 442 .offset = HHI_MPLL_CNTL5, 443 .shift = 12, 444 .width = 1, 445 }, 446 .hw.init = &(struct clk_init_data){ 447 .name = "mpll_prediv", 448 .ops = &clk_regmap_divider_ro_ops, 449 .parent_names = (const char *[]){ "fixed_pll" }, 450 .num_parents = 1, 451 }, 452 }; 453 454 static struct clk_regmap axg_mpll0_div = { 455 .data = &(struct meson_clk_mpll_data){ 456 .sdm = { 457 .reg_off = HHI_MPLL_CNTL7, 458 .shift = 0, 459 .width = 14, 460 }, 461 .sdm_en = { 462 .reg_off = HHI_MPLL_CNTL7, 463 .shift = 15, 464 .width = 1, 465 }, 466 .n2 = { 467 .reg_off = HHI_MPLL_CNTL7, 468 .shift = 16, 469 .width = 9, 470 }, 471 .ssen = { 472 .reg_off = HHI_MPLL_CNTL, 473 .shift = 25, 474 .width = 1, 475 }, 476 .misc = { 477 .reg_off = HHI_PLL_TOP_MISC, 478 .shift = 0, 479 .width = 1, 480 }, 481 .lock = &meson_clk_lock, 482 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 483 }, 484 .hw.init = &(struct clk_init_data){ 485 .name = "mpll0_div", 486 .ops = &meson_clk_mpll_ops, 487 .parent_names = (const char *[]){ "mpll_prediv" }, 488 .num_parents = 1, 489 }, 490 }; 491 492 static struct clk_regmap axg_mpll0 = { 493 .data = &(struct clk_regmap_gate_data){ 494 .offset = HHI_MPLL_CNTL7, 495 .bit_idx = 14, 496 }, 497 .hw.init = &(struct clk_init_data){ 498 .name = "mpll0", 499 .ops = &clk_regmap_gate_ops, 500 .parent_names = (const char *[]){ "mpll0_div" }, 501 .num_parents = 1, 502 .flags = CLK_SET_RATE_PARENT, 503 }, 504 }; 505 506 static struct clk_regmap axg_mpll1_div = { 507 .data = &(struct meson_clk_mpll_data){ 508 .sdm = { 509 .reg_off = HHI_MPLL_CNTL8, 510 .shift = 0, 511 .width = 14, 512 }, 513 .sdm_en = { 514 .reg_off = HHI_MPLL_CNTL8, 515 .shift = 15, 516 .width = 1, 517 }, 518 .n2 = { 519 .reg_off = HHI_MPLL_CNTL8, 520 .shift = 16, 521 .width = 9, 522 }, 523 .misc = { 524 .reg_off = HHI_PLL_TOP_MISC, 525 .shift = 1, 526 .width = 1, 527 }, 528 .lock = &meson_clk_lock, 529 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 530 }, 531 .hw.init = &(struct clk_init_data){ 532 .name = "mpll1_div", 533 .ops = &meson_clk_mpll_ops, 534 .parent_names = (const char *[]){ "mpll_prediv" }, 535 .num_parents = 1, 536 }, 537 }; 538 539 static struct clk_regmap axg_mpll1 = { 540 .data = &(struct clk_regmap_gate_data){ 541 .offset = HHI_MPLL_CNTL8, 542 .bit_idx = 14, 543 }, 544 .hw.init = &(struct clk_init_data){ 545 .name = "mpll1", 546 .ops = &clk_regmap_gate_ops, 547 .parent_names = (const char *[]){ "mpll1_div" }, 548 .num_parents = 1, 549 .flags = CLK_SET_RATE_PARENT, 550 }, 551 }; 552 553 static struct clk_regmap axg_mpll2_div = { 554 .data = &(struct meson_clk_mpll_data){ 555 .sdm = { 556 .reg_off = HHI_MPLL_CNTL9, 557 .shift = 0, 558 .width = 14, 559 }, 560 .sdm_en = { 561 .reg_off = HHI_MPLL_CNTL9, 562 .shift = 15, 563 .width = 1, 564 }, 565 .n2 = { 566 .reg_off = HHI_MPLL_CNTL9, 567 .shift = 16, 568 .width = 9, 569 }, 570 .misc = { 571 .reg_off = HHI_PLL_TOP_MISC, 572 .shift = 2, 573 .width = 1, 574 }, 575 .lock = &meson_clk_lock, 576 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 577 }, 578 .hw.init = &(struct clk_init_data){ 579 .name = "mpll2_div", 580 .ops = &meson_clk_mpll_ops, 581 .parent_names = (const char *[]){ "mpll_prediv" }, 582 .num_parents = 1, 583 }, 584 }; 585 586 static struct clk_regmap axg_mpll2 = { 587 .data = &(struct clk_regmap_gate_data){ 588 .offset = HHI_MPLL_CNTL9, 589 .bit_idx = 14, 590 }, 591 .hw.init = &(struct clk_init_data){ 592 .name = "mpll2", 593 .ops = &clk_regmap_gate_ops, 594 .parent_names = (const char *[]){ "mpll2_div" }, 595 .num_parents = 1, 596 .flags = CLK_SET_RATE_PARENT, 597 }, 598 }; 599 600 static struct clk_regmap axg_mpll3_div = { 601 .data = &(struct meson_clk_mpll_data){ 602 .sdm = { 603 .reg_off = HHI_MPLL3_CNTL0, 604 .shift = 12, 605 .width = 14, 606 }, 607 .sdm_en = { 608 .reg_off = HHI_MPLL3_CNTL0, 609 .shift = 11, 610 .width = 1, 611 }, 612 .n2 = { 613 .reg_off = HHI_MPLL3_CNTL0, 614 .shift = 2, 615 .width = 9, 616 }, 617 .misc = { 618 .reg_off = HHI_PLL_TOP_MISC, 619 .shift = 3, 620 .width = 1, 621 }, 622 .lock = &meson_clk_lock, 623 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 624 }, 625 .hw.init = &(struct clk_init_data){ 626 .name = "mpll3_div", 627 .ops = &meson_clk_mpll_ops, 628 .parent_names = (const char *[]){ "mpll_prediv" }, 629 .num_parents = 1, 630 }, 631 }; 632 633 static struct clk_regmap axg_mpll3 = { 634 .data = &(struct clk_regmap_gate_data){ 635 .offset = HHI_MPLL3_CNTL0, 636 .bit_idx = 0, 637 }, 638 .hw.init = &(struct clk_init_data){ 639 .name = "mpll3", 640 .ops = &clk_regmap_gate_ops, 641 .parent_names = (const char *[]){ "mpll3_div" }, 642 .num_parents = 1, 643 .flags = CLK_SET_RATE_PARENT, 644 }, 645 }; 646 647 static const struct pll_params_table axg_pcie_pll_params_table[] = { 648 { 649 .m = 200, 650 .n = 3, 651 }, 652 { /* sentinel */ }, 653 }; 654 655 static const struct reg_sequence axg_pcie_init_regs[] = { 656 { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, 657 { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, 658 { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, 659 { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, 660 { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, 661 { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, 662 { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, 663 }; 664 665 static struct clk_regmap axg_pcie_pll_dco = { 666 .data = &(struct meson_clk_pll_data){ 667 .en = { 668 .reg_off = HHI_PCIE_PLL_CNTL, 669 .shift = 30, 670 .width = 1, 671 }, 672 .m = { 673 .reg_off = HHI_PCIE_PLL_CNTL, 674 .shift = 0, 675 .width = 9, 676 }, 677 .n = { 678 .reg_off = HHI_PCIE_PLL_CNTL, 679 .shift = 9, 680 .width = 5, 681 }, 682 .frac = { 683 .reg_off = HHI_PCIE_PLL_CNTL1, 684 .shift = 0, 685 .width = 12, 686 }, 687 .l = { 688 .reg_off = HHI_PCIE_PLL_CNTL, 689 .shift = 31, 690 .width = 1, 691 }, 692 .rst = { 693 .reg_off = HHI_PCIE_PLL_CNTL, 694 .shift = 29, 695 .width = 1, 696 }, 697 .table = axg_pcie_pll_params_table, 698 .init_regs = axg_pcie_init_regs, 699 .init_count = ARRAY_SIZE(axg_pcie_init_regs), 700 }, 701 .hw.init = &(struct clk_init_data){ 702 .name = "pcie_pll_dco", 703 .ops = &meson_clk_pll_ops, 704 .parent_names = (const char *[]){ "xtal" }, 705 .num_parents = 1, 706 }, 707 }; 708 709 static struct clk_regmap axg_pcie_pll_od = { 710 .data = &(struct clk_regmap_div_data){ 711 .offset = HHI_PCIE_PLL_CNTL, 712 .shift = 16, 713 .width = 2, 714 .flags = CLK_DIVIDER_POWER_OF_TWO, 715 }, 716 .hw.init = &(struct clk_init_data){ 717 .name = "pcie_pll_od", 718 .ops = &clk_regmap_divider_ops, 719 .parent_names = (const char *[]){ "pcie_pll_dco" }, 720 .num_parents = 1, 721 .flags = CLK_SET_RATE_PARENT, 722 }, 723 }; 724 725 static struct clk_regmap axg_pcie_pll = { 726 .data = &(struct clk_regmap_div_data){ 727 .offset = HHI_PCIE_PLL_CNTL6, 728 .shift = 6, 729 .width = 2, 730 .flags = CLK_DIVIDER_POWER_OF_TWO, 731 }, 732 .hw.init = &(struct clk_init_data){ 733 .name = "pcie_pll", 734 .ops = &clk_regmap_divider_ops, 735 .parent_names = (const char *[]){ "pcie_pll_od" }, 736 .num_parents = 1, 737 .flags = CLK_SET_RATE_PARENT, 738 }, 739 }; 740 741 static struct clk_regmap axg_pcie_mux = { 742 .data = &(struct clk_regmap_mux_data){ 743 .offset = HHI_PCIE_PLL_CNTL6, 744 .mask = 0x1, 745 .shift = 2, 746 /* skip the parent mpll3, reserved for debug */ 747 .table = (u32[]){ 1 }, 748 }, 749 .hw.init = &(struct clk_init_data){ 750 .name = "pcie_mux", 751 .ops = &clk_regmap_mux_ops, 752 .parent_names = (const char *[]){ "pcie_pll" }, 753 .num_parents = 1, 754 .flags = CLK_SET_RATE_PARENT, 755 }, 756 }; 757 758 static struct clk_regmap axg_pcie_ref = { 759 .data = &(struct clk_regmap_mux_data){ 760 .offset = HHI_PCIE_PLL_CNTL6, 761 .mask = 0x1, 762 .shift = 1, 763 /* skip the parent 0, reserved for debug */ 764 .table = (u32[]){ 1 }, 765 }, 766 .hw.init = &(struct clk_init_data){ 767 .name = "pcie_ref", 768 .ops = &clk_regmap_mux_ops, 769 .parent_names = (const char *[]){ "pcie_mux" }, 770 .num_parents = 1, 771 .flags = CLK_SET_RATE_PARENT, 772 }, 773 }; 774 775 static struct clk_regmap axg_pcie_cml_en0 = { 776 .data = &(struct clk_regmap_gate_data){ 777 .offset = HHI_PCIE_PLL_CNTL6, 778 .bit_idx = 4, 779 }, 780 .hw.init = &(struct clk_init_data) { 781 .name = "pcie_cml_en0", 782 .ops = &clk_regmap_gate_ops, 783 .parent_names = (const char *[]){ "pcie_ref" }, 784 .num_parents = 1, 785 .flags = CLK_SET_RATE_PARENT, 786 787 }, 788 }; 789 790 static struct clk_regmap axg_pcie_cml_en1 = { 791 .data = &(struct clk_regmap_gate_data){ 792 .offset = HHI_PCIE_PLL_CNTL6, 793 .bit_idx = 3, 794 }, 795 .hw.init = &(struct clk_init_data) { 796 .name = "pcie_cml_en1", 797 .ops = &clk_regmap_gate_ops, 798 .parent_names = (const char *[]){ "pcie_ref" }, 799 .num_parents = 1, 800 .flags = CLK_SET_RATE_PARENT, 801 }, 802 }; 803 804 static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 805 static const char * const clk81_parent_names[] = { 806 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 807 "fclk_div3", "fclk_div5" 808 }; 809 810 static struct clk_regmap axg_mpeg_clk_sel = { 811 .data = &(struct clk_regmap_mux_data){ 812 .offset = HHI_MPEG_CLK_CNTL, 813 .mask = 0x7, 814 .shift = 12, 815 .table = mux_table_clk81, 816 }, 817 .hw.init = &(struct clk_init_data){ 818 .name = "mpeg_clk_sel", 819 .ops = &clk_regmap_mux_ro_ops, 820 .parent_names = clk81_parent_names, 821 .num_parents = ARRAY_SIZE(clk81_parent_names), 822 }, 823 }; 824 825 static struct clk_regmap axg_mpeg_clk_div = { 826 .data = &(struct clk_regmap_div_data){ 827 .offset = HHI_MPEG_CLK_CNTL, 828 .shift = 0, 829 .width = 7, 830 }, 831 .hw.init = &(struct clk_init_data){ 832 .name = "mpeg_clk_div", 833 .ops = &clk_regmap_divider_ops, 834 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 835 .num_parents = 1, 836 .flags = CLK_SET_RATE_PARENT, 837 }, 838 }; 839 840 static struct clk_regmap axg_clk81 = { 841 .data = &(struct clk_regmap_gate_data){ 842 .offset = HHI_MPEG_CLK_CNTL, 843 .bit_idx = 7, 844 }, 845 .hw.init = &(struct clk_init_data){ 846 .name = "clk81", 847 .ops = &clk_regmap_gate_ops, 848 .parent_names = (const char *[]){ "mpeg_clk_div" }, 849 .num_parents = 1, 850 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 851 }, 852 }; 853 854 static const char * const axg_sd_emmc_clk0_parent_names[] = { 855 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", 856 857 /* 858 * Following these parent clocks, we should also have had mpll2, mpll3 859 * and gp0_pll but these clocks are too precious to be used here. All 860 * the necessary rates for MMC and NAND operation can be acheived using 861 * xtal or fclk_div clocks 862 */ 863 }; 864 865 /* SDcard clock */ 866 static struct clk_regmap axg_sd_emmc_b_clk0_sel = { 867 .data = &(struct clk_regmap_mux_data){ 868 .offset = HHI_SD_EMMC_CLK_CNTL, 869 .mask = 0x7, 870 .shift = 25, 871 }, 872 .hw.init = &(struct clk_init_data) { 873 .name = "sd_emmc_b_clk0_sel", 874 .ops = &clk_regmap_mux_ops, 875 .parent_names = axg_sd_emmc_clk0_parent_names, 876 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 877 .flags = CLK_SET_RATE_PARENT, 878 }, 879 }; 880 881 static struct clk_regmap axg_sd_emmc_b_clk0_div = { 882 .data = &(struct clk_regmap_div_data){ 883 .offset = HHI_SD_EMMC_CLK_CNTL, 884 .shift = 16, 885 .width = 7, 886 .flags = CLK_DIVIDER_ROUND_CLOSEST, 887 }, 888 .hw.init = &(struct clk_init_data) { 889 .name = "sd_emmc_b_clk0_div", 890 .ops = &clk_regmap_divider_ops, 891 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 892 .num_parents = 1, 893 .flags = CLK_SET_RATE_PARENT, 894 }, 895 }; 896 897 static struct clk_regmap axg_sd_emmc_b_clk0 = { 898 .data = &(struct clk_regmap_gate_data){ 899 .offset = HHI_SD_EMMC_CLK_CNTL, 900 .bit_idx = 23, 901 }, 902 .hw.init = &(struct clk_init_data){ 903 .name = "sd_emmc_b_clk0", 904 .ops = &clk_regmap_gate_ops, 905 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 906 .num_parents = 1, 907 .flags = CLK_SET_RATE_PARENT, 908 }, 909 }; 910 911 /* EMMC/NAND clock */ 912 static struct clk_regmap axg_sd_emmc_c_clk0_sel = { 913 .data = &(struct clk_regmap_mux_data){ 914 .offset = HHI_NAND_CLK_CNTL, 915 .mask = 0x7, 916 .shift = 9, 917 }, 918 .hw.init = &(struct clk_init_data) { 919 .name = "sd_emmc_c_clk0_sel", 920 .ops = &clk_regmap_mux_ops, 921 .parent_names = axg_sd_emmc_clk0_parent_names, 922 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 923 .flags = CLK_SET_RATE_PARENT, 924 }, 925 }; 926 927 static struct clk_regmap axg_sd_emmc_c_clk0_div = { 928 .data = &(struct clk_regmap_div_data){ 929 .offset = HHI_NAND_CLK_CNTL, 930 .shift = 0, 931 .width = 7, 932 .flags = CLK_DIVIDER_ROUND_CLOSEST, 933 }, 934 .hw.init = &(struct clk_init_data) { 935 .name = "sd_emmc_c_clk0_div", 936 .ops = &clk_regmap_divider_ops, 937 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 938 .num_parents = 1, 939 .flags = CLK_SET_RATE_PARENT, 940 }, 941 }; 942 943 static struct clk_regmap axg_sd_emmc_c_clk0 = { 944 .data = &(struct clk_regmap_gate_data){ 945 .offset = HHI_NAND_CLK_CNTL, 946 .bit_idx = 7, 947 }, 948 .hw.init = &(struct clk_init_data){ 949 .name = "sd_emmc_c_clk0", 950 .ops = &clk_regmap_gate_ops, 951 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 952 .num_parents = 1, 953 .flags = CLK_SET_RATE_PARENT, 954 }, 955 }; 956 957 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 958 9, 10, 11, 13, 14, }; 959 static const char * const gen_clk_parent_names[] = { 960 "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", 961 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", 962 }; 963 964 static struct clk_regmap axg_gen_clk_sel = { 965 .data = &(struct clk_regmap_mux_data){ 966 .offset = HHI_GEN_CLK_CNTL, 967 .mask = 0xf, 968 .shift = 12, 969 .table = mux_table_gen_clk, 970 }, 971 .hw.init = &(struct clk_init_data){ 972 .name = "gen_clk_sel", 973 .ops = &clk_regmap_mux_ops, 974 /* 975 * bits 15:12 selects from 14 possible parents: 976 * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt], 977 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, 978 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll 979 */ 980 .parent_names = gen_clk_parent_names, 981 .num_parents = ARRAY_SIZE(gen_clk_parent_names), 982 }, 983 }; 984 985 static struct clk_regmap axg_gen_clk_div = { 986 .data = &(struct clk_regmap_div_data){ 987 .offset = HHI_GEN_CLK_CNTL, 988 .shift = 0, 989 .width = 11, 990 }, 991 .hw.init = &(struct clk_init_data){ 992 .name = "gen_clk_div", 993 .ops = &clk_regmap_divider_ops, 994 .parent_names = (const char *[]){ "gen_clk_sel" }, 995 .num_parents = 1, 996 .flags = CLK_SET_RATE_PARENT, 997 }, 998 }; 999 1000 static struct clk_regmap axg_gen_clk = { 1001 .data = &(struct clk_regmap_gate_data){ 1002 .offset = HHI_GEN_CLK_CNTL, 1003 .bit_idx = 7, 1004 }, 1005 .hw.init = &(struct clk_init_data){ 1006 .name = "gen_clk", 1007 .ops = &clk_regmap_gate_ops, 1008 .parent_names = (const char *[]){ "gen_clk_div" }, 1009 .num_parents = 1, 1010 .flags = CLK_SET_RATE_PARENT, 1011 }, 1012 }; 1013 1014 /* Everything Else (EE) domain gates */ 1015 static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); 1016 static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); 1017 static MESON_GATE(axg_mipi_dsi_host, HHI_GCLK_MPEG0, 3); 1018 static MESON_GATE(axg_isa, HHI_GCLK_MPEG0, 5); 1019 static MESON_GATE(axg_pl301, HHI_GCLK_MPEG0, 6); 1020 static MESON_GATE(axg_periphs, HHI_GCLK_MPEG0, 7); 1021 static MESON_GATE(axg_spicc_0, HHI_GCLK_MPEG0, 8); 1022 static MESON_GATE(axg_i2c, HHI_GCLK_MPEG0, 9); 1023 static MESON_GATE(axg_rng0, HHI_GCLK_MPEG0, 12); 1024 static MESON_GATE(axg_uart0, HHI_GCLK_MPEG0, 13); 1025 static MESON_GATE(axg_mipi_dsi_phy, HHI_GCLK_MPEG0, 14); 1026 static MESON_GATE(axg_spicc_1, HHI_GCLK_MPEG0, 15); 1027 static MESON_GATE(axg_pcie_a, HHI_GCLK_MPEG0, 16); 1028 static MESON_GATE(axg_pcie_b, HHI_GCLK_MPEG0, 17); 1029 static MESON_GATE(axg_hiu_reg, HHI_GCLK_MPEG0, 19); 1030 static MESON_GATE(axg_assist_misc, HHI_GCLK_MPEG0, 23); 1031 static MESON_GATE(axg_emmc_b, HHI_GCLK_MPEG0, 25); 1032 static MESON_GATE(axg_emmc_c, HHI_GCLK_MPEG0, 26); 1033 static MESON_GATE(axg_dma, HHI_GCLK_MPEG0, 27); 1034 static MESON_GATE(axg_spi, HHI_GCLK_MPEG0, 30); 1035 1036 static MESON_GATE(axg_audio, HHI_GCLK_MPEG1, 0); 1037 static MESON_GATE(axg_eth_core, HHI_GCLK_MPEG1, 3); 1038 static MESON_GATE(axg_uart1, HHI_GCLK_MPEG1, 16); 1039 static MESON_GATE(axg_g2d, HHI_GCLK_MPEG1, 20); 1040 static MESON_GATE(axg_usb0, HHI_GCLK_MPEG1, 21); 1041 static MESON_GATE(axg_usb1, HHI_GCLK_MPEG1, 22); 1042 static MESON_GATE(axg_reset, HHI_GCLK_MPEG1, 23); 1043 static MESON_GATE(axg_usb_general, HHI_GCLK_MPEG1, 26); 1044 static MESON_GATE(axg_ahb_arb0, HHI_GCLK_MPEG1, 29); 1045 static MESON_GATE(axg_efuse, HHI_GCLK_MPEG1, 30); 1046 static MESON_GATE(axg_boot_rom, HHI_GCLK_MPEG1, 31); 1047 1048 static MESON_GATE(axg_ahb_data_bus, HHI_GCLK_MPEG2, 1); 1049 static MESON_GATE(axg_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); 1050 static MESON_GATE(axg_usb1_to_ddr, HHI_GCLK_MPEG2, 8); 1051 static MESON_GATE(axg_usb0_to_ddr, HHI_GCLK_MPEG2, 9); 1052 static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11); 1053 static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); 1054 static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); 1055 static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); 1056 static MESON_GATE(axg_mipi_enable, HHI_MIPI_CNTL0, 29); 1057 1058 /* Always On (AO) domain gates */ 1059 1060 static MESON_GATE(axg_ao_media_cpu, HHI_GCLK_AO, 0); 1061 static MESON_GATE(axg_ao_ahb_sram, HHI_GCLK_AO, 1); 1062 static MESON_GATE(axg_ao_ahb_bus, HHI_GCLK_AO, 2); 1063 static MESON_GATE(axg_ao_iface, HHI_GCLK_AO, 3); 1064 static MESON_GATE(axg_ao_i2c, HHI_GCLK_AO, 4); 1065 1066 /* Array of all clocks provided by this provider */ 1067 1068 static struct clk_hw_onecell_data axg_hw_onecell_data = { 1069 .hws = { 1070 [CLKID_SYS_PLL] = &axg_sys_pll.hw, 1071 [CLKID_FIXED_PLL] = &axg_fixed_pll.hw, 1072 [CLKID_FCLK_DIV2] = &axg_fclk_div2.hw, 1073 [CLKID_FCLK_DIV3] = &axg_fclk_div3.hw, 1074 [CLKID_FCLK_DIV4] = &axg_fclk_div4.hw, 1075 [CLKID_FCLK_DIV5] = &axg_fclk_div5.hw, 1076 [CLKID_FCLK_DIV7] = &axg_fclk_div7.hw, 1077 [CLKID_GP0_PLL] = &axg_gp0_pll.hw, 1078 [CLKID_MPEG_SEL] = &axg_mpeg_clk_sel.hw, 1079 [CLKID_MPEG_DIV] = &axg_mpeg_clk_div.hw, 1080 [CLKID_CLK81] = &axg_clk81.hw, 1081 [CLKID_MPLL0] = &axg_mpll0.hw, 1082 [CLKID_MPLL1] = &axg_mpll1.hw, 1083 [CLKID_MPLL2] = &axg_mpll2.hw, 1084 [CLKID_MPLL3] = &axg_mpll3.hw, 1085 [CLKID_DDR] = &axg_ddr.hw, 1086 [CLKID_AUDIO_LOCKER] = &axg_audio_locker.hw, 1087 [CLKID_MIPI_DSI_HOST] = &axg_mipi_dsi_host.hw, 1088 [CLKID_ISA] = &axg_isa.hw, 1089 [CLKID_PL301] = &axg_pl301.hw, 1090 [CLKID_PERIPHS] = &axg_periphs.hw, 1091 [CLKID_SPICC0] = &axg_spicc_0.hw, 1092 [CLKID_I2C] = &axg_i2c.hw, 1093 [CLKID_RNG0] = &axg_rng0.hw, 1094 [CLKID_UART0] = &axg_uart0.hw, 1095 [CLKID_MIPI_DSI_PHY] = &axg_mipi_dsi_phy.hw, 1096 [CLKID_SPICC1] = &axg_spicc_1.hw, 1097 [CLKID_PCIE_A] = &axg_pcie_a.hw, 1098 [CLKID_PCIE_B] = &axg_pcie_b.hw, 1099 [CLKID_HIU_IFACE] = &axg_hiu_reg.hw, 1100 [CLKID_ASSIST_MISC] = &axg_assist_misc.hw, 1101 [CLKID_SD_EMMC_B] = &axg_emmc_b.hw, 1102 [CLKID_SD_EMMC_C] = &axg_emmc_c.hw, 1103 [CLKID_DMA] = &axg_dma.hw, 1104 [CLKID_SPI] = &axg_spi.hw, 1105 [CLKID_AUDIO] = &axg_audio.hw, 1106 [CLKID_ETH] = &axg_eth_core.hw, 1107 [CLKID_UART1] = &axg_uart1.hw, 1108 [CLKID_G2D] = &axg_g2d.hw, 1109 [CLKID_USB0] = &axg_usb0.hw, 1110 [CLKID_USB1] = &axg_usb1.hw, 1111 [CLKID_RESET] = &axg_reset.hw, 1112 [CLKID_USB] = &axg_usb_general.hw, 1113 [CLKID_AHB_ARB0] = &axg_ahb_arb0.hw, 1114 [CLKID_EFUSE] = &axg_efuse.hw, 1115 [CLKID_BOOT_ROM] = &axg_boot_rom.hw, 1116 [CLKID_AHB_DATA_BUS] = &axg_ahb_data_bus.hw, 1117 [CLKID_AHB_CTRL_BUS] = &axg_ahb_ctrl_bus.hw, 1118 [CLKID_USB1_DDR_BRIDGE] = &axg_usb1_to_ddr.hw, 1119 [CLKID_USB0_DDR_BRIDGE] = &axg_usb0_to_ddr.hw, 1120 [CLKID_MMC_PCLK] = &axg_mmc_pclk.hw, 1121 [CLKID_VPU_INTR] = &axg_vpu_intr.hw, 1122 [CLKID_SEC_AHB_AHB3_BRIDGE] = &axg_sec_ahb_ahb3_bridge.hw, 1123 [CLKID_GIC] = &axg_gic.hw, 1124 [CLKID_AO_MEDIA_CPU] = &axg_ao_media_cpu.hw, 1125 [CLKID_AO_AHB_SRAM] = &axg_ao_ahb_sram.hw, 1126 [CLKID_AO_AHB_BUS] = &axg_ao_ahb_bus.hw, 1127 [CLKID_AO_IFACE] = &axg_ao_iface.hw, 1128 [CLKID_AO_I2C] = &axg_ao_i2c.hw, 1129 [CLKID_SD_EMMC_B_CLK0_SEL] = &axg_sd_emmc_b_clk0_sel.hw, 1130 [CLKID_SD_EMMC_B_CLK0_DIV] = &axg_sd_emmc_b_clk0_div.hw, 1131 [CLKID_SD_EMMC_B_CLK0] = &axg_sd_emmc_b_clk0.hw, 1132 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw, 1133 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw, 1134 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw, 1135 [CLKID_MPLL0_DIV] = &axg_mpll0_div.hw, 1136 [CLKID_MPLL1_DIV] = &axg_mpll1_div.hw, 1137 [CLKID_MPLL2_DIV] = &axg_mpll2_div.hw, 1138 [CLKID_MPLL3_DIV] = &axg_mpll3_div.hw, 1139 [CLKID_HIFI_PLL] = &axg_hifi_pll.hw, 1140 [CLKID_MPLL_PREDIV] = &axg_mpll_prediv.hw, 1141 [CLKID_FCLK_DIV2_DIV] = &axg_fclk_div2_div.hw, 1142 [CLKID_FCLK_DIV3_DIV] = &axg_fclk_div3_div.hw, 1143 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw, 1144 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw, 1145 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw, 1146 [CLKID_PCIE_PLL] = &axg_pcie_pll.hw, 1147 [CLKID_PCIE_MUX] = &axg_pcie_mux.hw, 1148 [CLKID_PCIE_REF] = &axg_pcie_ref.hw, 1149 [CLKID_PCIE_CML_EN0] = &axg_pcie_cml_en0.hw, 1150 [CLKID_PCIE_CML_EN1] = &axg_pcie_cml_en1.hw, 1151 [CLKID_MIPI_ENABLE] = &axg_mipi_enable.hw, 1152 [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, 1153 [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, 1154 [CLKID_GEN_CLK] = &axg_gen_clk.hw, 1155 [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, 1156 [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, 1157 [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, 1158 [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, 1159 [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, 1160 [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, 1161 [NR_CLKS] = NULL, 1162 }, 1163 .num = NR_CLKS, 1164 }; 1165 1166 /* Convenience table to populate regmap in .probe */ 1167 static struct clk_regmap *const axg_clk_regmaps[] = { 1168 &axg_clk81, 1169 &axg_ddr, 1170 &axg_audio_locker, 1171 &axg_mipi_dsi_host, 1172 &axg_isa, 1173 &axg_pl301, 1174 &axg_periphs, 1175 &axg_spicc_0, 1176 &axg_i2c, 1177 &axg_rng0, 1178 &axg_uart0, 1179 &axg_mipi_dsi_phy, 1180 &axg_spicc_1, 1181 &axg_pcie_a, 1182 &axg_pcie_b, 1183 &axg_hiu_reg, 1184 &axg_assist_misc, 1185 &axg_emmc_b, 1186 &axg_emmc_c, 1187 &axg_dma, 1188 &axg_spi, 1189 &axg_audio, 1190 &axg_eth_core, 1191 &axg_uart1, 1192 &axg_g2d, 1193 &axg_usb0, 1194 &axg_usb1, 1195 &axg_reset, 1196 &axg_usb_general, 1197 &axg_ahb_arb0, 1198 &axg_efuse, 1199 &axg_boot_rom, 1200 &axg_ahb_data_bus, 1201 &axg_ahb_ctrl_bus, 1202 &axg_usb1_to_ddr, 1203 &axg_usb0_to_ddr, 1204 &axg_mmc_pclk, 1205 &axg_vpu_intr, 1206 &axg_sec_ahb_ahb3_bridge, 1207 &axg_gic, 1208 &axg_ao_media_cpu, 1209 &axg_ao_ahb_sram, 1210 &axg_ao_ahb_bus, 1211 &axg_ao_iface, 1212 &axg_ao_i2c, 1213 &axg_sd_emmc_b_clk0, 1214 &axg_sd_emmc_c_clk0, 1215 &axg_mpeg_clk_div, 1216 &axg_sd_emmc_b_clk0_div, 1217 &axg_sd_emmc_c_clk0_div, 1218 &axg_mpeg_clk_sel, 1219 &axg_sd_emmc_b_clk0_sel, 1220 &axg_sd_emmc_c_clk0_sel, 1221 &axg_mpll0, 1222 &axg_mpll1, 1223 &axg_mpll2, 1224 &axg_mpll3, 1225 &axg_mpll0_div, 1226 &axg_mpll1_div, 1227 &axg_mpll2_div, 1228 &axg_mpll3_div, 1229 &axg_fixed_pll, 1230 &axg_sys_pll, 1231 &axg_gp0_pll, 1232 &axg_hifi_pll, 1233 &axg_mpll_prediv, 1234 &axg_fclk_div2, 1235 &axg_fclk_div3, 1236 &axg_fclk_div4, 1237 &axg_fclk_div5, 1238 &axg_fclk_div7, 1239 &axg_pcie_pll_dco, 1240 &axg_pcie_pll_od, 1241 &axg_pcie_pll, 1242 &axg_pcie_mux, 1243 &axg_pcie_ref, 1244 &axg_pcie_cml_en0, 1245 &axg_pcie_cml_en1, 1246 &axg_mipi_enable, 1247 &axg_gen_clk_sel, 1248 &axg_gen_clk_div, 1249 &axg_gen_clk, 1250 &axg_fixed_pll_dco, 1251 &axg_sys_pll_dco, 1252 &axg_gp0_pll_dco, 1253 &axg_hifi_pll_dco, 1254 &axg_pcie_pll_dco, 1255 &axg_pcie_pll_od, 1256 }; 1257 1258 static const struct of_device_id clkc_match_table[] = { 1259 { .compatible = "amlogic,axg-clkc" }, 1260 {} 1261 }; 1262 1263 static int axg_clkc_probe(struct platform_device *pdev) 1264 { 1265 struct device *dev = &pdev->dev; 1266 struct regmap *map; 1267 int ret, i; 1268 1269 /* Get the hhi system controller node if available */ 1270 map = syscon_node_to_regmap(of_get_parent(dev->of_node)); 1271 if (IS_ERR(map)) { 1272 dev_err(dev, "failed to get HHI regmap\n"); 1273 return PTR_ERR(map); 1274 } 1275 1276 /* Populate regmap for the regmap backed clocks */ 1277 for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++) 1278 axg_clk_regmaps[i]->map = map; 1279 1280 for (i = 0; i < axg_hw_onecell_data.num; i++) { 1281 /* array might be sparse */ 1282 if (!axg_hw_onecell_data.hws[i]) 1283 continue; 1284 1285 ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]); 1286 if (ret) { 1287 dev_err(dev, "Clock registration failed\n"); 1288 return ret; 1289 } 1290 } 1291 1292 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 1293 &axg_hw_onecell_data); 1294 } 1295 1296 static struct platform_driver axg_driver = { 1297 .probe = axg_clkc_probe, 1298 .driver = { 1299 .name = "axg-clkc", 1300 .of_match_table = clkc_match_table, 1301 }, 1302 }; 1303 1304 builtin_platform_driver(axg_driver); 1305