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 }, 329 }; 330 331 static struct clk_fixed_factor axg_fclk_div3_div = { 332 .mult = 1, 333 .div = 3, 334 .hw.init = &(struct clk_init_data){ 335 .name = "fclk_div3_div", 336 .ops = &clk_fixed_factor_ops, 337 .parent_names = (const char *[]){ "fixed_pll" }, 338 .num_parents = 1, 339 }, 340 }; 341 342 static struct clk_regmap axg_fclk_div3 = { 343 .data = &(struct clk_regmap_gate_data){ 344 .offset = HHI_MPLL_CNTL6, 345 .bit_idx = 28, 346 }, 347 .hw.init = &(struct clk_init_data){ 348 .name = "fclk_div3", 349 .ops = &clk_regmap_gate_ops, 350 .parent_names = (const char *[]){ "fclk_div3_div" }, 351 .num_parents = 1, 352 }, 353 }; 354 355 static struct clk_fixed_factor axg_fclk_div4_div = { 356 .mult = 1, 357 .div = 4, 358 .hw.init = &(struct clk_init_data){ 359 .name = "fclk_div4_div", 360 .ops = &clk_fixed_factor_ops, 361 .parent_names = (const char *[]){ "fixed_pll" }, 362 .num_parents = 1, 363 }, 364 }; 365 366 static struct clk_regmap axg_fclk_div4 = { 367 .data = &(struct clk_regmap_gate_data){ 368 .offset = HHI_MPLL_CNTL6, 369 .bit_idx = 29, 370 }, 371 .hw.init = &(struct clk_init_data){ 372 .name = "fclk_div4", 373 .ops = &clk_regmap_gate_ops, 374 .parent_names = (const char *[]){ "fclk_div4_div" }, 375 .num_parents = 1, 376 }, 377 }; 378 379 static struct clk_fixed_factor axg_fclk_div5_div = { 380 .mult = 1, 381 .div = 5, 382 .hw.init = &(struct clk_init_data){ 383 .name = "fclk_div5_div", 384 .ops = &clk_fixed_factor_ops, 385 .parent_names = (const char *[]){ "fixed_pll" }, 386 .num_parents = 1, 387 }, 388 }; 389 390 static struct clk_regmap axg_fclk_div5 = { 391 .data = &(struct clk_regmap_gate_data){ 392 .offset = HHI_MPLL_CNTL6, 393 .bit_idx = 30, 394 }, 395 .hw.init = &(struct clk_init_data){ 396 .name = "fclk_div5", 397 .ops = &clk_regmap_gate_ops, 398 .parent_names = (const char *[]){ "fclk_div5_div" }, 399 .num_parents = 1, 400 }, 401 }; 402 403 static struct clk_fixed_factor axg_fclk_div7_div = { 404 .mult = 1, 405 .div = 7, 406 .hw.init = &(struct clk_init_data){ 407 .name = "fclk_div7_div", 408 .ops = &clk_fixed_factor_ops, 409 .parent_names = (const char *[]){ "fixed_pll" }, 410 .num_parents = 1, 411 }, 412 }; 413 414 static struct clk_regmap axg_fclk_div7 = { 415 .data = &(struct clk_regmap_gate_data){ 416 .offset = HHI_MPLL_CNTL6, 417 .bit_idx = 31, 418 }, 419 .hw.init = &(struct clk_init_data){ 420 .name = "fclk_div7", 421 .ops = &clk_regmap_gate_ops, 422 .parent_names = (const char *[]){ "fclk_div7_div" }, 423 .num_parents = 1, 424 }, 425 }; 426 427 static struct clk_regmap axg_mpll_prediv = { 428 .data = &(struct clk_regmap_div_data){ 429 .offset = HHI_MPLL_CNTL5, 430 .shift = 12, 431 .width = 1, 432 }, 433 .hw.init = &(struct clk_init_data){ 434 .name = "mpll_prediv", 435 .ops = &clk_regmap_divider_ro_ops, 436 .parent_names = (const char *[]){ "fixed_pll" }, 437 .num_parents = 1, 438 }, 439 }; 440 441 static struct clk_regmap axg_mpll0_div = { 442 .data = &(struct meson_clk_mpll_data){ 443 .sdm = { 444 .reg_off = HHI_MPLL_CNTL7, 445 .shift = 0, 446 .width = 14, 447 }, 448 .sdm_en = { 449 .reg_off = HHI_MPLL_CNTL7, 450 .shift = 15, 451 .width = 1, 452 }, 453 .n2 = { 454 .reg_off = HHI_MPLL_CNTL7, 455 .shift = 16, 456 .width = 9, 457 }, 458 .ssen = { 459 .reg_off = HHI_MPLL_CNTL, 460 .shift = 25, 461 .width = 1, 462 }, 463 .misc = { 464 .reg_off = HHI_PLL_TOP_MISC, 465 .shift = 0, 466 .width = 1, 467 }, 468 .lock = &meson_clk_lock, 469 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 470 }, 471 .hw.init = &(struct clk_init_data){ 472 .name = "mpll0_div", 473 .ops = &meson_clk_mpll_ops, 474 .parent_names = (const char *[]){ "mpll_prediv" }, 475 .num_parents = 1, 476 }, 477 }; 478 479 static struct clk_regmap axg_mpll0 = { 480 .data = &(struct clk_regmap_gate_data){ 481 .offset = HHI_MPLL_CNTL7, 482 .bit_idx = 14, 483 }, 484 .hw.init = &(struct clk_init_data){ 485 .name = "mpll0", 486 .ops = &clk_regmap_gate_ops, 487 .parent_names = (const char *[]){ "mpll0_div" }, 488 .num_parents = 1, 489 .flags = CLK_SET_RATE_PARENT, 490 }, 491 }; 492 493 static struct clk_regmap axg_mpll1_div = { 494 .data = &(struct meson_clk_mpll_data){ 495 .sdm = { 496 .reg_off = HHI_MPLL_CNTL8, 497 .shift = 0, 498 .width = 14, 499 }, 500 .sdm_en = { 501 .reg_off = HHI_MPLL_CNTL8, 502 .shift = 15, 503 .width = 1, 504 }, 505 .n2 = { 506 .reg_off = HHI_MPLL_CNTL8, 507 .shift = 16, 508 .width = 9, 509 }, 510 .misc = { 511 .reg_off = HHI_PLL_TOP_MISC, 512 .shift = 1, 513 .width = 1, 514 }, 515 .lock = &meson_clk_lock, 516 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 517 }, 518 .hw.init = &(struct clk_init_data){ 519 .name = "mpll1_div", 520 .ops = &meson_clk_mpll_ops, 521 .parent_names = (const char *[]){ "mpll_prediv" }, 522 .num_parents = 1, 523 }, 524 }; 525 526 static struct clk_regmap axg_mpll1 = { 527 .data = &(struct clk_regmap_gate_data){ 528 .offset = HHI_MPLL_CNTL8, 529 .bit_idx = 14, 530 }, 531 .hw.init = &(struct clk_init_data){ 532 .name = "mpll1", 533 .ops = &clk_regmap_gate_ops, 534 .parent_names = (const char *[]){ "mpll1_div" }, 535 .num_parents = 1, 536 .flags = CLK_SET_RATE_PARENT, 537 }, 538 }; 539 540 static struct clk_regmap axg_mpll2_div = { 541 .data = &(struct meson_clk_mpll_data){ 542 .sdm = { 543 .reg_off = HHI_MPLL_CNTL9, 544 .shift = 0, 545 .width = 14, 546 }, 547 .sdm_en = { 548 .reg_off = HHI_MPLL_CNTL9, 549 .shift = 15, 550 .width = 1, 551 }, 552 .n2 = { 553 .reg_off = HHI_MPLL_CNTL9, 554 .shift = 16, 555 .width = 9, 556 }, 557 .misc = { 558 .reg_off = HHI_PLL_TOP_MISC, 559 .shift = 2, 560 .width = 1, 561 }, 562 .lock = &meson_clk_lock, 563 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 564 }, 565 .hw.init = &(struct clk_init_data){ 566 .name = "mpll2_div", 567 .ops = &meson_clk_mpll_ops, 568 .parent_names = (const char *[]){ "mpll_prediv" }, 569 .num_parents = 1, 570 }, 571 }; 572 573 static struct clk_regmap axg_mpll2 = { 574 .data = &(struct clk_regmap_gate_data){ 575 .offset = HHI_MPLL_CNTL9, 576 .bit_idx = 14, 577 }, 578 .hw.init = &(struct clk_init_data){ 579 .name = "mpll2", 580 .ops = &clk_regmap_gate_ops, 581 .parent_names = (const char *[]){ "mpll2_div" }, 582 .num_parents = 1, 583 .flags = CLK_SET_RATE_PARENT, 584 }, 585 }; 586 587 static struct clk_regmap axg_mpll3_div = { 588 .data = &(struct meson_clk_mpll_data){ 589 .sdm = { 590 .reg_off = HHI_MPLL3_CNTL0, 591 .shift = 12, 592 .width = 14, 593 }, 594 .sdm_en = { 595 .reg_off = HHI_MPLL3_CNTL0, 596 .shift = 11, 597 .width = 1, 598 }, 599 .n2 = { 600 .reg_off = HHI_MPLL3_CNTL0, 601 .shift = 2, 602 .width = 9, 603 }, 604 .misc = { 605 .reg_off = HHI_PLL_TOP_MISC, 606 .shift = 3, 607 .width = 1, 608 }, 609 .lock = &meson_clk_lock, 610 .flags = CLK_MESON_MPLL_ROUND_CLOSEST, 611 }, 612 .hw.init = &(struct clk_init_data){ 613 .name = "mpll3_div", 614 .ops = &meson_clk_mpll_ops, 615 .parent_names = (const char *[]){ "mpll_prediv" }, 616 .num_parents = 1, 617 }, 618 }; 619 620 static struct clk_regmap axg_mpll3 = { 621 .data = &(struct clk_regmap_gate_data){ 622 .offset = HHI_MPLL3_CNTL0, 623 .bit_idx = 0, 624 }, 625 .hw.init = &(struct clk_init_data){ 626 .name = "mpll3", 627 .ops = &clk_regmap_gate_ops, 628 .parent_names = (const char *[]){ "mpll3_div" }, 629 .num_parents = 1, 630 .flags = CLK_SET_RATE_PARENT, 631 }, 632 }; 633 634 static const struct pll_params_table axg_pcie_pll_params_table[] = { 635 { 636 .m = 200, 637 .n = 3, 638 }, 639 { /* sentinel */ }, 640 }; 641 642 static const struct reg_sequence axg_pcie_init_regs[] = { 643 { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, 644 { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, 645 { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, 646 { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, 647 { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, 648 { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, 649 { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, 650 }; 651 652 static struct clk_regmap axg_pcie_pll_dco = { 653 .data = &(struct meson_clk_pll_data){ 654 .en = { 655 .reg_off = HHI_PCIE_PLL_CNTL, 656 .shift = 30, 657 .width = 1, 658 }, 659 .m = { 660 .reg_off = HHI_PCIE_PLL_CNTL, 661 .shift = 0, 662 .width = 9, 663 }, 664 .n = { 665 .reg_off = HHI_PCIE_PLL_CNTL, 666 .shift = 9, 667 .width = 5, 668 }, 669 .frac = { 670 .reg_off = HHI_PCIE_PLL_CNTL1, 671 .shift = 0, 672 .width = 12, 673 }, 674 .l = { 675 .reg_off = HHI_PCIE_PLL_CNTL, 676 .shift = 31, 677 .width = 1, 678 }, 679 .rst = { 680 .reg_off = HHI_PCIE_PLL_CNTL, 681 .shift = 29, 682 .width = 1, 683 }, 684 .table = axg_pcie_pll_params_table, 685 .init_regs = axg_pcie_init_regs, 686 .init_count = ARRAY_SIZE(axg_pcie_init_regs), 687 }, 688 .hw.init = &(struct clk_init_data){ 689 .name = "pcie_pll_dco", 690 .ops = &meson_clk_pll_ops, 691 .parent_names = (const char *[]){ "xtal" }, 692 .num_parents = 1, 693 }, 694 }; 695 696 static struct clk_regmap axg_pcie_pll_od = { 697 .data = &(struct clk_regmap_div_data){ 698 .offset = HHI_PCIE_PLL_CNTL, 699 .shift = 16, 700 .width = 2, 701 .flags = CLK_DIVIDER_POWER_OF_TWO, 702 }, 703 .hw.init = &(struct clk_init_data){ 704 .name = "pcie_pll_od", 705 .ops = &clk_regmap_divider_ops, 706 .parent_names = (const char *[]){ "pcie_pll_dco" }, 707 .num_parents = 1, 708 .flags = CLK_SET_RATE_PARENT, 709 }, 710 }; 711 712 static struct clk_regmap axg_pcie_pll = { 713 .data = &(struct clk_regmap_div_data){ 714 .offset = HHI_PCIE_PLL_CNTL6, 715 .shift = 6, 716 .width = 2, 717 .flags = CLK_DIVIDER_POWER_OF_TWO, 718 }, 719 .hw.init = &(struct clk_init_data){ 720 .name = "pcie_pll", 721 .ops = &clk_regmap_divider_ops, 722 .parent_names = (const char *[]){ "pcie_pll_od" }, 723 .num_parents = 1, 724 .flags = CLK_SET_RATE_PARENT, 725 }, 726 }; 727 728 static struct clk_regmap axg_pcie_mux = { 729 .data = &(struct clk_regmap_mux_data){ 730 .offset = HHI_PCIE_PLL_CNTL6, 731 .mask = 0x1, 732 .shift = 2, 733 /* skip the parent mpll3, reserved for debug */ 734 .table = (u32[]){ 1 }, 735 }, 736 .hw.init = &(struct clk_init_data){ 737 .name = "pcie_mux", 738 .ops = &clk_regmap_mux_ops, 739 .parent_names = (const char *[]){ "pcie_pll" }, 740 .num_parents = 1, 741 .flags = CLK_SET_RATE_PARENT, 742 }, 743 }; 744 745 static struct clk_regmap axg_pcie_ref = { 746 .data = &(struct clk_regmap_mux_data){ 747 .offset = HHI_PCIE_PLL_CNTL6, 748 .mask = 0x1, 749 .shift = 1, 750 /* skip the parent 0, reserved for debug */ 751 .table = (u32[]){ 1 }, 752 }, 753 .hw.init = &(struct clk_init_data){ 754 .name = "pcie_ref", 755 .ops = &clk_regmap_mux_ops, 756 .parent_names = (const char *[]){ "pcie_mux" }, 757 .num_parents = 1, 758 .flags = CLK_SET_RATE_PARENT, 759 }, 760 }; 761 762 static struct clk_regmap axg_pcie_cml_en0 = { 763 .data = &(struct clk_regmap_gate_data){ 764 .offset = HHI_PCIE_PLL_CNTL6, 765 .bit_idx = 4, 766 }, 767 .hw.init = &(struct clk_init_data) { 768 .name = "pcie_cml_en0", 769 .ops = &clk_regmap_gate_ops, 770 .parent_names = (const char *[]){ "pcie_ref" }, 771 .num_parents = 1, 772 .flags = CLK_SET_RATE_PARENT, 773 774 }, 775 }; 776 777 static struct clk_regmap axg_pcie_cml_en1 = { 778 .data = &(struct clk_regmap_gate_data){ 779 .offset = HHI_PCIE_PLL_CNTL6, 780 .bit_idx = 3, 781 }, 782 .hw.init = &(struct clk_init_data) { 783 .name = "pcie_cml_en1", 784 .ops = &clk_regmap_gate_ops, 785 .parent_names = (const char *[]){ "pcie_ref" }, 786 .num_parents = 1, 787 .flags = CLK_SET_RATE_PARENT, 788 }, 789 }; 790 791 static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 792 static const char * const clk81_parent_names[] = { 793 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 794 "fclk_div3", "fclk_div5" 795 }; 796 797 static struct clk_regmap axg_mpeg_clk_sel = { 798 .data = &(struct clk_regmap_mux_data){ 799 .offset = HHI_MPEG_CLK_CNTL, 800 .mask = 0x7, 801 .shift = 12, 802 .table = mux_table_clk81, 803 }, 804 .hw.init = &(struct clk_init_data){ 805 .name = "mpeg_clk_sel", 806 .ops = &clk_regmap_mux_ro_ops, 807 .parent_names = clk81_parent_names, 808 .num_parents = ARRAY_SIZE(clk81_parent_names), 809 }, 810 }; 811 812 static struct clk_regmap axg_mpeg_clk_div = { 813 .data = &(struct clk_regmap_div_data){ 814 .offset = HHI_MPEG_CLK_CNTL, 815 .shift = 0, 816 .width = 7, 817 }, 818 .hw.init = &(struct clk_init_data){ 819 .name = "mpeg_clk_div", 820 .ops = &clk_regmap_divider_ops, 821 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 822 .num_parents = 1, 823 .flags = CLK_SET_RATE_PARENT, 824 }, 825 }; 826 827 static struct clk_regmap axg_clk81 = { 828 .data = &(struct clk_regmap_gate_data){ 829 .offset = HHI_MPEG_CLK_CNTL, 830 .bit_idx = 7, 831 }, 832 .hw.init = &(struct clk_init_data){ 833 .name = "clk81", 834 .ops = &clk_regmap_gate_ops, 835 .parent_names = (const char *[]){ "mpeg_clk_div" }, 836 .num_parents = 1, 837 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 838 }, 839 }; 840 841 static const char * const axg_sd_emmc_clk0_parent_names[] = { 842 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", 843 844 /* 845 * Following these parent clocks, we should also have had mpll2, mpll3 846 * and gp0_pll but these clocks are too precious to be used here. All 847 * the necessary rates for MMC and NAND operation can be acheived using 848 * xtal or fclk_div clocks 849 */ 850 }; 851 852 /* SDcard clock */ 853 static struct clk_regmap axg_sd_emmc_b_clk0_sel = { 854 .data = &(struct clk_regmap_mux_data){ 855 .offset = HHI_SD_EMMC_CLK_CNTL, 856 .mask = 0x7, 857 .shift = 25, 858 }, 859 .hw.init = &(struct clk_init_data) { 860 .name = "sd_emmc_b_clk0_sel", 861 .ops = &clk_regmap_mux_ops, 862 .parent_names = axg_sd_emmc_clk0_parent_names, 863 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 864 .flags = CLK_SET_RATE_PARENT, 865 }, 866 }; 867 868 static struct clk_regmap axg_sd_emmc_b_clk0_div = { 869 .data = &(struct clk_regmap_div_data){ 870 .offset = HHI_SD_EMMC_CLK_CNTL, 871 .shift = 16, 872 .width = 7, 873 .flags = CLK_DIVIDER_ROUND_CLOSEST, 874 }, 875 .hw.init = &(struct clk_init_data) { 876 .name = "sd_emmc_b_clk0_div", 877 .ops = &clk_regmap_divider_ops, 878 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 879 .num_parents = 1, 880 .flags = CLK_SET_RATE_PARENT, 881 }, 882 }; 883 884 static struct clk_regmap axg_sd_emmc_b_clk0 = { 885 .data = &(struct clk_regmap_gate_data){ 886 .offset = HHI_SD_EMMC_CLK_CNTL, 887 .bit_idx = 23, 888 }, 889 .hw.init = &(struct clk_init_data){ 890 .name = "sd_emmc_b_clk0", 891 .ops = &clk_regmap_gate_ops, 892 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 893 .num_parents = 1, 894 .flags = CLK_SET_RATE_PARENT, 895 }, 896 }; 897 898 /* EMMC/NAND clock */ 899 static struct clk_regmap axg_sd_emmc_c_clk0_sel = { 900 .data = &(struct clk_regmap_mux_data){ 901 .offset = HHI_NAND_CLK_CNTL, 902 .mask = 0x7, 903 .shift = 9, 904 }, 905 .hw.init = &(struct clk_init_data) { 906 .name = "sd_emmc_c_clk0_sel", 907 .ops = &clk_regmap_mux_ops, 908 .parent_names = axg_sd_emmc_clk0_parent_names, 909 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 910 .flags = CLK_SET_RATE_PARENT, 911 }, 912 }; 913 914 static struct clk_regmap axg_sd_emmc_c_clk0_div = { 915 .data = &(struct clk_regmap_div_data){ 916 .offset = HHI_NAND_CLK_CNTL, 917 .shift = 0, 918 .width = 7, 919 .flags = CLK_DIVIDER_ROUND_CLOSEST, 920 }, 921 .hw.init = &(struct clk_init_data) { 922 .name = "sd_emmc_c_clk0_div", 923 .ops = &clk_regmap_divider_ops, 924 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 925 .num_parents = 1, 926 .flags = CLK_SET_RATE_PARENT, 927 }, 928 }; 929 930 static struct clk_regmap axg_sd_emmc_c_clk0 = { 931 .data = &(struct clk_regmap_gate_data){ 932 .offset = HHI_NAND_CLK_CNTL, 933 .bit_idx = 7, 934 }, 935 .hw.init = &(struct clk_init_data){ 936 .name = "sd_emmc_c_clk0", 937 .ops = &clk_regmap_gate_ops, 938 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 939 .num_parents = 1, 940 .flags = CLK_SET_RATE_PARENT, 941 }, 942 }; 943 944 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 945 9, 10, 11, 13, 14, }; 946 static const char * const gen_clk_parent_names[] = { 947 "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", 948 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", 949 }; 950 951 static struct clk_regmap axg_gen_clk_sel = { 952 .data = &(struct clk_regmap_mux_data){ 953 .offset = HHI_GEN_CLK_CNTL, 954 .mask = 0xf, 955 .shift = 12, 956 .table = mux_table_gen_clk, 957 }, 958 .hw.init = &(struct clk_init_data){ 959 .name = "gen_clk_sel", 960 .ops = &clk_regmap_mux_ops, 961 /* 962 * bits 15:12 selects from 14 possible parents: 963 * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt], 964 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, 965 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll 966 */ 967 .parent_names = gen_clk_parent_names, 968 .num_parents = ARRAY_SIZE(gen_clk_parent_names), 969 }, 970 }; 971 972 static struct clk_regmap axg_gen_clk_div = { 973 .data = &(struct clk_regmap_div_data){ 974 .offset = HHI_GEN_CLK_CNTL, 975 .shift = 0, 976 .width = 11, 977 }, 978 .hw.init = &(struct clk_init_data){ 979 .name = "gen_clk_div", 980 .ops = &clk_regmap_divider_ops, 981 .parent_names = (const char *[]){ "gen_clk_sel" }, 982 .num_parents = 1, 983 .flags = CLK_SET_RATE_PARENT, 984 }, 985 }; 986 987 static struct clk_regmap axg_gen_clk = { 988 .data = &(struct clk_regmap_gate_data){ 989 .offset = HHI_GEN_CLK_CNTL, 990 .bit_idx = 7, 991 }, 992 .hw.init = &(struct clk_init_data){ 993 .name = "gen_clk", 994 .ops = &clk_regmap_gate_ops, 995 .parent_names = (const char *[]){ "gen_clk_div" }, 996 .num_parents = 1, 997 .flags = CLK_SET_RATE_PARENT, 998 }, 999 }; 1000 1001 /* Everything Else (EE) domain gates */ 1002 static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); 1003 static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); 1004 static MESON_GATE(axg_mipi_dsi_host, HHI_GCLK_MPEG0, 3); 1005 static MESON_GATE(axg_isa, HHI_GCLK_MPEG0, 5); 1006 static MESON_GATE(axg_pl301, HHI_GCLK_MPEG0, 6); 1007 static MESON_GATE(axg_periphs, HHI_GCLK_MPEG0, 7); 1008 static MESON_GATE(axg_spicc_0, HHI_GCLK_MPEG0, 8); 1009 static MESON_GATE(axg_i2c, HHI_GCLK_MPEG0, 9); 1010 static MESON_GATE(axg_rng0, HHI_GCLK_MPEG0, 12); 1011 static MESON_GATE(axg_uart0, HHI_GCLK_MPEG0, 13); 1012 static MESON_GATE(axg_mipi_dsi_phy, HHI_GCLK_MPEG0, 14); 1013 static MESON_GATE(axg_spicc_1, HHI_GCLK_MPEG0, 15); 1014 static MESON_GATE(axg_pcie_a, HHI_GCLK_MPEG0, 16); 1015 static MESON_GATE(axg_pcie_b, HHI_GCLK_MPEG0, 17); 1016 static MESON_GATE(axg_hiu_reg, HHI_GCLK_MPEG0, 19); 1017 static MESON_GATE(axg_assist_misc, HHI_GCLK_MPEG0, 23); 1018 static MESON_GATE(axg_emmc_b, HHI_GCLK_MPEG0, 25); 1019 static MESON_GATE(axg_emmc_c, HHI_GCLK_MPEG0, 26); 1020 static MESON_GATE(axg_dma, HHI_GCLK_MPEG0, 27); 1021 static MESON_GATE(axg_spi, HHI_GCLK_MPEG0, 30); 1022 1023 static MESON_GATE(axg_audio, HHI_GCLK_MPEG1, 0); 1024 static MESON_GATE(axg_eth_core, HHI_GCLK_MPEG1, 3); 1025 static MESON_GATE(axg_uart1, HHI_GCLK_MPEG1, 16); 1026 static MESON_GATE(axg_g2d, HHI_GCLK_MPEG1, 20); 1027 static MESON_GATE(axg_usb0, HHI_GCLK_MPEG1, 21); 1028 static MESON_GATE(axg_usb1, HHI_GCLK_MPEG1, 22); 1029 static MESON_GATE(axg_reset, HHI_GCLK_MPEG1, 23); 1030 static MESON_GATE(axg_usb_general, HHI_GCLK_MPEG1, 26); 1031 static MESON_GATE(axg_ahb_arb0, HHI_GCLK_MPEG1, 29); 1032 static MESON_GATE(axg_efuse, HHI_GCLK_MPEG1, 30); 1033 static MESON_GATE(axg_boot_rom, HHI_GCLK_MPEG1, 31); 1034 1035 static MESON_GATE(axg_ahb_data_bus, HHI_GCLK_MPEG2, 1); 1036 static MESON_GATE(axg_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); 1037 static MESON_GATE(axg_usb1_to_ddr, HHI_GCLK_MPEG2, 8); 1038 static MESON_GATE(axg_usb0_to_ddr, HHI_GCLK_MPEG2, 9); 1039 static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11); 1040 static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); 1041 static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); 1042 static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); 1043 static MESON_GATE(axg_mipi_enable, HHI_MIPI_CNTL0, 29); 1044 1045 /* Always On (AO) domain gates */ 1046 1047 static MESON_GATE(axg_ao_media_cpu, HHI_GCLK_AO, 0); 1048 static MESON_GATE(axg_ao_ahb_sram, HHI_GCLK_AO, 1); 1049 static MESON_GATE(axg_ao_ahb_bus, HHI_GCLK_AO, 2); 1050 static MESON_GATE(axg_ao_iface, HHI_GCLK_AO, 3); 1051 static MESON_GATE(axg_ao_i2c, HHI_GCLK_AO, 4); 1052 1053 /* Array of all clocks provided by this provider */ 1054 1055 static struct clk_hw_onecell_data axg_hw_onecell_data = { 1056 .hws = { 1057 [CLKID_SYS_PLL] = &axg_sys_pll.hw, 1058 [CLKID_FIXED_PLL] = &axg_fixed_pll.hw, 1059 [CLKID_FCLK_DIV2] = &axg_fclk_div2.hw, 1060 [CLKID_FCLK_DIV3] = &axg_fclk_div3.hw, 1061 [CLKID_FCLK_DIV4] = &axg_fclk_div4.hw, 1062 [CLKID_FCLK_DIV5] = &axg_fclk_div5.hw, 1063 [CLKID_FCLK_DIV7] = &axg_fclk_div7.hw, 1064 [CLKID_GP0_PLL] = &axg_gp0_pll.hw, 1065 [CLKID_MPEG_SEL] = &axg_mpeg_clk_sel.hw, 1066 [CLKID_MPEG_DIV] = &axg_mpeg_clk_div.hw, 1067 [CLKID_CLK81] = &axg_clk81.hw, 1068 [CLKID_MPLL0] = &axg_mpll0.hw, 1069 [CLKID_MPLL1] = &axg_mpll1.hw, 1070 [CLKID_MPLL2] = &axg_mpll2.hw, 1071 [CLKID_MPLL3] = &axg_mpll3.hw, 1072 [CLKID_DDR] = &axg_ddr.hw, 1073 [CLKID_AUDIO_LOCKER] = &axg_audio_locker.hw, 1074 [CLKID_MIPI_DSI_HOST] = &axg_mipi_dsi_host.hw, 1075 [CLKID_ISA] = &axg_isa.hw, 1076 [CLKID_PL301] = &axg_pl301.hw, 1077 [CLKID_PERIPHS] = &axg_periphs.hw, 1078 [CLKID_SPICC0] = &axg_spicc_0.hw, 1079 [CLKID_I2C] = &axg_i2c.hw, 1080 [CLKID_RNG0] = &axg_rng0.hw, 1081 [CLKID_UART0] = &axg_uart0.hw, 1082 [CLKID_MIPI_DSI_PHY] = &axg_mipi_dsi_phy.hw, 1083 [CLKID_SPICC1] = &axg_spicc_1.hw, 1084 [CLKID_PCIE_A] = &axg_pcie_a.hw, 1085 [CLKID_PCIE_B] = &axg_pcie_b.hw, 1086 [CLKID_HIU_IFACE] = &axg_hiu_reg.hw, 1087 [CLKID_ASSIST_MISC] = &axg_assist_misc.hw, 1088 [CLKID_SD_EMMC_B] = &axg_emmc_b.hw, 1089 [CLKID_SD_EMMC_C] = &axg_emmc_c.hw, 1090 [CLKID_DMA] = &axg_dma.hw, 1091 [CLKID_SPI] = &axg_spi.hw, 1092 [CLKID_AUDIO] = &axg_audio.hw, 1093 [CLKID_ETH] = &axg_eth_core.hw, 1094 [CLKID_UART1] = &axg_uart1.hw, 1095 [CLKID_G2D] = &axg_g2d.hw, 1096 [CLKID_USB0] = &axg_usb0.hw, 1097 [CLKID_USB1] = &axg_usb1.hw, 1098 [CLKID_RESET] = &axg_reset.hw, 1099 [CLKID_USB] = &axg_usb_general.hw, 1100 [CLKID_AHB_ARB0] = &axg_ahb_arb0.hw, 1101 [CLKID_EFUSE] = &axg_efuse.hw, 1102 [CLKID_BOOT_ROM] = &axg_boot_rom.hw, 1103 [CLKID_AHB_DATA_BUS] = &axg_ahb_data_bus.hw, 1104 [CLKID_AHB_CTRL_BUS] = &axg_ahb_ctrl_bus.hw, 1105 [CLKID_USB1_DDR_BRIDGE] = &axg_usb1_to_ddr.hw, 1106 [CLKID_USB0_DDR_BRIDGE] = &axg_usb0_to_ddr.hw, 1107 [CLKID_MMC_PCLK] = &axg_mmc_pclk.hw, 1108 [CLKID_VPU_INTR] = &axg_vpu_intr.hw, 1109 [CLKID_SEC_AHB_AHB3_BRIDGE] = &axg_sec_ahb_ahb3_bridge.hw, 1110 [CLKID_GIC] = &axg_gic.hw, 1111 [CLKID_AO_MEDIA_CPU] = &axg_ao_media_cpu.hw, 1112 [CLKID_AO_AHB_SRAM] = &axg_ao_ahb_sram.hw, 1113 [CLKID_AO_AHB_BUS] = &axg_ao_ahb_bus.hw, 1114 [CLKID_AO_IFACE] = &axg_ao_iface.hw, 1115 [CLKID_AO_I2C] = &axg_ao_i2c.hw, 1116 [CLKID_SD_EMMC_B_CLK0_SEL] = &axg_sd_emmc_b_clk0_sel.hw, 1117 [CLKID_SD_EMMC_B_CLK0_DIV] = &axg_sd_emmc_b_clk0_div.hw, 1118 [CLKID_SD_EMMC_B_CLK0] = &axg_sd_emmc_b_clk0.hw, 1119 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw, 1120 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw, 1121 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw, 1122 [CLKID_MPLL0_DIV] = &axg_mpll0_div.hw, 1123 [CLKID_MPLL1_DIV] = &axg_mpll1_div.hw, 1124 [CLKID_MPLL2_DIV] = &axg_mpll2_div.hw, 1125 [CLKID_MPLL3_DIV] = &axg_mpll3_div.hw, 1126 [CLKID_HIFI_PLL] = &axg_hifi_pll.hw, 1127 [CLKID_MPLL_PREDIV] = &axg_mpll_prediv.hw, 1128 [CLKID_FCLK_DIV2_DIV] = &axg_fclk_div2_div.hw, 1129 [CLKID_FCLK_DIV3_DIV] = &axg_fclk_div3_div.hw, 1130 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw, 1131 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw, 1132 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw, 1133 [CLKID_PCIE_PLL] = &axg_pcie_pll.hw, 1134 [CLKID_PCIE_MUX] = &axg_pcie_mux.hw, 1135 [CLKID_PCIE_REF] = &axg_pcie_ref.hw, 1136 [CLKID_PCIE_CML_EN0] = &axg_pcie_cml_en0.hw, 1137 [CLKID_PCIE_CML_EN1] = &axg_pcie_cml_en1.hw, 1138 [CLKID_MIPI_ENABLE] = &axg_mipi_enable.hw, 1139 [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, 1140 [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, 1141 [CLKID_GEN_CLK] = &axg_gen_clk.hw, 1142 [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, 1143 [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, 1144 [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, 1145 [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, 1146 [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, 1147 [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, 1148 [NR_CLKS] = NULL, 1149 }, 1150 .num = NR_CLKS, 1151 }; 1152 1153 /* Convenience table to populate regmap in .probe */ 1154 static struct clk_regmap *const axg_clk_regmaps[] = { 1155 &axg_clk81, 1156 &axg_ddr, 1157 &axg_audio_locker, 1158 &axg_mipi_dsi_host, 1159 &axg_isa, 1160 &axg_pl301, 1161 &axg_periphs, 1162 &axg_spicc_0, 1163 &axg_i2c, 1164 &axg_rng0, 1165 &axg_uart0, 1166 &axg_mipi_dsi_phy, 1167 &axg_spicc_1, 1168 &axg_pcie_a, 1169 &axg_pcie_b, 1170 &axg_hiu_reg, 1171 &axg_assist_misc, 1172 &axg_emmc_b, 1173 &axg_emmc_c, 1174 &axg_dma, 1175 &axg_spi, 1176 &axg_audio, 1177 &axg_eth_core, 1178 &axg_uart1, 1179 &axg_g2d, 1180 &axg_usb0, 1181 &axg_usb1, 1182 &axg_reset, 1183 &axg_usb_general, 1184 &axg_ahb_arb0, 1185 &axg_efuse, 1186 &axg_boot_rom, 1187 &axg_ahb_data_bus, 1188 &axg_ahb_ctrl_bus, 1189 &axg_usb1_to_ddr, 1190 &axg_usb0_to_ddr, 1191 &axg_mmc_pclk, 1192 &axg_vpu_intr, 1193 &axg_sec_ahb_ahb3_bridge, 1194 &axg_gic, 1195 &axg_ao_media_cpu, 1196 &axg_ao_ahb_sram, 1197 &axg_ao_ahb_bus, 1198 &axg_ao_iface, 1199 &axg_ao_i2c, 1200 &axg_sd_emmc_b_clk0, 1201 &axg_sd_emmc_c_clk0, 1202 &axg_mpeg_clk_div, 1203 &axg_sd_emmc_b_clk0_div, 1204 &axg_sd_emmc_c_clk0_div, 1205 &axg_mpeg_clk_sel, 1206 &axg_sd_emmc_b_clk0_sel, 1207 &axg_sd_emmc_c_clk0_sel, 1208 &axg_mpll0, 1209 &axg_mpll1, 1210 &axg_mpll2, 1211 &axg_mpll3, 1212 &axg_mpll0_div, 1213 &axg_mpll1_div, 1214 &axg_mpll2_div, 1215 &axg_mpll3_div, 1216 &axg_fixed_pll, 1217 &axg_sys_pll, 1218 &axg_gp0_pll, 1219 &axg_hifi_pll, 1220 &axg_mpll_prediv, 1221 &axg_fclk_div2, 1222 &axg_fclk_div3, 1223 &axg_fclk_div4, 1224 &axg_fclk_div5, 1225 &axg_fclk_div7, 1226 &axg_pcie_pll_dco, 1227 &axg_pcie_pll_od, 1228 &axg_pcie_pll, 1229 &axg_pcie_mux, 1230 &axg_pcie_ref, 1231 &axg_pcie_cml_en0, 1232 &axg_pcie_cml_en1, 1233 &axg_mipi_enable, 1234 &axg_gen_clk_sel, 1235 &axg_gen_clk_div, 1236 &axg_gen_clk, 1237 &axg_fixed_pll_dco, 1238 &axg_sys_pll_dco, 1239 &axg_gp0_pll_dco, 1240 &axg_hifi_pll_dco, 1241 &axg_pcie_pll_dco, 1242 &axg_pcie_pll_od, 1243 }; 1244 1245 static const struct of_device_id clkc_match_table[] = { 1246 { .compatible = "amlogic,axg-clkc" }, 1247 {} 1248 }; 1249 1250 static int axg_clkc_probe(struct platform_device *pdev) 1251 { 1252 struct device *dev = &pdev->dev; 1253 struct regmap *map; 1254 int ret, i; 1255 1256 /* Get the hhi system controller node if available */ 1257 map = syscon_node_to_regmap(of_get_parent(dev->of_node)); 1258 if (IS_ERR(map)) { 1259 dev_err(dev, "failed to get HHI regmap\n"); 1260 return PTR_ERR(map); 1261 } 1262 1263 /* Populate regmap for the regmap backed clocks */ 1264 for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++) 1265 axg_clk_regmaps[i]->map = map; 1266 1267 for (i = 0; i < axg_hw_onecell_data.num; i++) { 1268 /* array might be sparse */ 1269 if (!axg_hw_onecell_data.hws[i]) 1270 continue; 1271 1272 ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]); 1273 if (ret) { 1274 dev_err(dev, "Clock registration failed\n"); 1275 return ret; 1276 } 1277 } 1278 1279 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 1280 &axg_hw_onecell_data); 1281 } 1282 1283 static struct platform_driver axg_driver = { 1284 .probe = axg_clkc_probe, 1285 .driver = { 1286 .name = "axg-clkc", 1287 .of_match_table = clkc_match_table, 1288 }, 1289 }; 1290 1291 builtin_platform_driver(axg_driver); 1292