1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2015 Endless Mobile, Inc. 4 * Author: Carlo Caione <carlo@endlessm.com> 5 * 6 * Copyright (c) 2016 BayLibre, Inc. 7 * Michael Turquette <mturquette@baylibre.com> 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/clk-provider.h> 12 #include <linux/init.h> 13 #include <linux/mfd/syscon.h> 14 #include <linux/of_address.h> 15 #include <linux/reset-controller.h> 16 #include <linux/slab.h> 17 #include <linux/regmap.h> 18 19 #include "clkc.h" 20 #include "meson8b.h" 21 #include "clk-regmap.h" 22 23 static DEFINE_SPINLOCK(meson_clk_lock); 24 25 struct meson8b_clk_reset { 26 struct reset_controller_dev reset; 27 struct regmap *regmap; 28 }; 29 30 static const struct pll_params_table sys_pll_params_table[] = { 31 PLL_PARAMS(50, 1), 32 PLL_PARAMS(51, 1), 33 PLL_PARAMS(52, 1), 34 PLL_PARAMS(53, 1), 35 PLL_PARAMS(54, 1), 36 PLL_PARAMS(55, 1), 37 PLL_PARAMS(56, 1), 38 PLL_PARAMS(57, 1), 39 PLL_PARAMS(58, 1), 40 PLL_PARAMS(59, 1), 41 PLL_PARAMS(60, 1), 42 PLL_PARAMS(61, 1), 43 PLL_PARAMS(62, 1), 44 PLL_PARAMS(63, 1), 45 PLL_PARAMS(64, 1), 46 PLL_PARAMS(65, 1), 47 PLL_PARAMS(66, 1), 48 PLL_PARAMS(67, 1), 49 PLL_PARAMS(68, 1), 50 PLL_PARAMS(84, 1), 51 { /* sentinel */ }, 52 }; 53 54 static struct clk_fixed_rate meson8b_xtal = { 55 .fixed_rate = 24000000, 56 .hw.init = &(struct clk_init_data){ 57 .name = "xtal", 58 .num_parents = 0, 59 .ops = &clk_fixed_rate_ops, 60 }, 61 }; 62 63 static struct clk_regmap meson8b_fixed_pll_dco = { 64 .data = &(struct meson_clk_pll_data){ 65 .en = { 66 .reg_off = HHI_MPLL_CNTL, 67 .shift = 30, 68 .width = 1, 69 }, 70 .m = { 71 .reg_off = HHI_MPLL_CNTL, 72 .shift = 0, 73 .width = 9, 74 }, 75 .n = { 76 .reg_off = HHI_MPLL_CNTL, 77 .shift = 9, 78 .width = 5, 79 }, 80 .frac = { 81 .reg_off = HHI_MPLL_CNTL2, 82 .shift = 0, 83 .width = 12, 84 }, 85 .l = { 86 .reg_off = HHI_MPLL_CNTL, 87 .shift = 31, 88 .width = 1, 89 }, 90 .rst = { 91 .reg_off = HHI_MPLL_CNTL, 92 .shift = 29, 93 .width = 1, 94 }, 95 }, 96 .hw.init = &(struct clk_init_data){ 97 .name = "fixed_pll_dco", 98 .ops = &meson_clk_pll_ro_ops, 99 .parent_names = (const char *[]){ "xtal" }, 100 .num_parents = 1, 101 }, 102 }; 103 104 static struct clk_regmap meson8b_fixed_pll = { 105 .data = &(struct clk_regmap_div_data){ 106 .offset = HHI_MPLL_CNTL, 107 .shift = 16, 108 .width = 2, 109 .flags = CLK_DIVIDER_POWER_OF_TWO, 110 }, 111 .hw.init = &(struct clk_init_data){ 112 .name = "fixed_pll", 113 .ops = &clk_regmap_divider_ro_ops, 114 .parent_names = (const char *[]){ "fixed_pll_dco" }, 115 .num_parents = 1, 116 /* 117 * This clock won't ever change at runtime so 118 * CLK_SET_RATE_PARENT is not required 119 */ 120 }, 121 }; 122 123 static struct clk_regmap meson8b_hdmi_pll_dco = { 124 .data = &(struct meson_clk_pll_data){ 125 .en = { 126 .reg_off = HHI_VID_PLL_CNTL, 127 .shift = 30, 128 .width = 1, 129 }, 130 .m = { 131 .reg_off = HHI_VID_PLL_CNTL, 132 .shift = 0, 133 .width = 9, 134 }, 135 .n = { 136 .reg_off = HHI_VID_PLL_CNTL, 137 .shift = 10, 138 .width = 5, 139 }, 140 .frac = { 141 .reg_off = HHI_VID_PLL_CNTL2, 142 .shift = 0, 143 .width = 12, 144 }, 145 .l = { 146 .reg_off = HHI_VID_PLL_CNTL, 147 .shift = 31, 148 .width = 1, 149 }, 150 .rst = { 151 .reg_off = HHI_VID_PLL_CNTL, 152 .shift = 29, 153 .width = 1, 154 }, 155 }, 156 .hw.init = &(struct clk_init_data){ 157 /* sometimes also called "HPLL" or "HPLL PLL" */ 158 .name = "hdmi_pll_dco", 159 .ops = &meson_clk_pll_ro_ops, 160 .parent_names = (const char *[]){ "xtal" }, 161 .num_parents = 1, 162 }, 163 }; 164 165 static struct clk_regmap meson8b_hdmi_pll_lvds_out = { 166 .data = &(struct clk_regmap_div_data){ 167 .offset = HHI_VID_PLL_CNTL, 168 .shift = 16, 169 .width = 2, 170 .flags = CLK_DIVIDER_POWER_OF_TWO, 171 }, 172 .hw.init = &(struct clk_init_data){ 173 .name = "hdmi_pll_lvds_out", 174 .ops = &clk_regmap_divider_ro_ops, 175 .parent_names = (const char *[]){ "hdmi_pll_dco" }, 176 .num_parents = 1, 177 .flags = CLK_SET_RATE_PARENT, 178 }, 179 }; 180 181 static struct clk_regmap meson8b_hdmi_pll_hdmi_out = { 182 .data = &(struct clk_regmap_div_data){ 183 .offset = HHI_VID_PLL_CNTL, 184 .shift = 18, 185 .width = 2, 186 .flags = CLK_DIVIDER_POWER_OF_TWO, 187 }, 188 .hw.init = &(struct clk_init_data){ 189 .name = "hdmi_pll_hdmi_out", 190 .ops = &clk_regmap_divider_ro_ops, 191 .parent_names = (const char *[]){ "hdmi_pll_dco" }, 192 .num_parents = 1, 193 .flags = CLK_SET_RATE_PARENT, 194 }, 195 }; 196 197 static struct clk_regmap meson8b_sys_pll_dco = { 198 .data = &(struct meson_clk_pll_data){ 199 .en = { 200 .reg_off = HHI_SYS_PLL_CNTL, 201 .shift = 30, 202 .width = 1, 203 }, 204 .m = { 205 .reg_off = HHI_SYS_PLL_CNTL, 206 .shift = 0, 207 .width = 9, 208 }, 209 .n = { 210 .reg_off = HHI_SYS_PLL_CNTL, 211 .shift = 9, 212 .width = 5, 213 }, 214 .l = { 215 .reg_off = HHI_SYS_PLL_CNTL, 216 .shift = 31, 217 .width = 1, 218 }, 219 .rst = { 220 .reg_off = HHI_SYS_PLL_CNTL, 221 .shift = 29, 222 .width = 1, 223 }, 224 .table = sys_pll_params_table, 225 }, 226 .hw.init = &(struct clk_init_data){ 227 .name = "sys_pll_dco", 228 .ops = &meson_clk_pll_ops, 229 .parent_names = (const char *[]){ "xtal" }, 230 .num_parents = 1, 231 }, 232 }; 233 234 static struct clk_regmap meson8b_sys_pll = { 235 .data = &(struct clk_regmap_div_data){ 236 .offset = HHI_SYS_PLL_CNTL, 237 .shift = 16, 238 .width = 2, 239 .flags = CLK_DIVIDER_POWER_OF_TWO, 240 }, 241 .hw.init = &(struct clk_init_data){ 242 .name = "sys_pll", 243 .ops = &clk_regmap_divider_ops, 244 .parent_names = (const char *[]){ "sys_pll_dco" }, 245 .num_parents = 1, 246 .flags = CLK_SET_RATE_PARENT, 247 }, 248 }; 249 250 static struct clk_fixed_factor meson8b_fclk_div2_div = { 251 .mult = 1, 252 .div = 2, 253 .hw.init = &(struct clk_init_data){ 254 .name = "fclk_div2_div", 255 .ops = &clk_fixed_factor_ops, 256 .parent_names = (const char *[]){ "fixed_pll" }, 257 .num_parents = 1, 258 }, 259 }; 260 261 static struct clk_regmap meson8b_fclk_div2 = { 262 .data = &(struct clk_regmap_gate_data){ 263 .offset = HHI_MPLL_CNTL6, 264 .bit_idx = 27, 265 }, 266 .hw.init = &(struct clk_init_data){ 267 .name = "fclk_div2", 268 .ops = &clk_regmap_gate_ops, 269 .parent_names = (const char *[]){ "fclk_div2_div" }, 270 .num_parents = 1, 271 /* 272 * FIXME: Ethernet with a RGMII PHYs is not working if 273 * fclk_div2 is disabled. it is currently unclear why this 274 * is. keep it enabled until the Ethernet driver knows how 275 * to manage this clock. 276 */ 277 .flags = CLK_IS_CRITICAL, 278 }, 279 }; 280 281 static struct clk_fixed_factor meson8b_fclk_div3_div = { 282 .mult = 1, 283 .div = 3, 284 .hw.init = &(struct clk_init_data){ 285 .name = "fclk_div3_div", 286 .ops = &clk_fixed_factor_ops, 287 .parent_names = (const char *[]){ "fixed_pll" }, 288 .num_parents = 1, 289 }, 290 }; 291 292 static struct clk_regmap meson8b_fclk_div3 = { 293 .data = &(struct clk_regmap_gate_data){ 294 .offset = HHI_MPLL_CNTL6, 295 .bit_idx = 28, 296 }, 297 .hw.init = &(struct clk_init_data){ 298 .name = "fclk_div3", 299 .ops = &clk_regmap_gate_ops, 300 .parent_names = (const char *[]){ "fclk_div3_div" }, 301 .num_parents = 1, 302 }, 303 }; 304 305 static struct clk_fixed_factor meson8b_fclk_div4_div = { 306 .mult = 1, 307 .div = 4, 308 .hw.init = &(struct clk_init_data){ 309 .name = "fclk_div4_div", 310 .ops = &clk_fixed_factor_ops, 311 .parent_names = (const char *[]){ "fixed_pll" }, 312 .num_parents = 1, 313 }, 314 }; 315 316 static struct clk_regmap meson8b_fclk_div4 = { 317 .data = &(struct clk_regmap_gate_data){ 318 .offset = HHI_MPLL_CNTL6, 319 .bit_idx = 29, 320 }, 321 .hw.init = &(struct clk_init_data){ 322 .name = "fclk_div4", 323 .ops = &clk_regmap_gate_ops, 324 .parent_names = (const char *[]){ "fclk_div4_div" }, 325 .num_parents = 1, 326 }, 327 }; 328 329 static struct clk_fixed_factor meson8b_fclk_div5_div = { 330 .mult = 1, 331 .div = 5, 332 .hw.init = &(struct clk_init_data){ 333 .name = "fclk_div5_div", 334 .ops = &clk_fixed_factor_ops, 335 .parent_names = (const char *[]){ "fixed_pll" }, 336 .num_parents = 1, 337 }, 338 }; 339 340 static struct clk_regmap meson8b_fclk_div5 = { 341 .data = &(struct clk_regmap_gate_data){ 342 .offset = HHI_MPLL_CNTL6, 343 .bit_idx = 30, 344 }, 345 .hw.init = &(struct clk_init_data){ 346 .name = "fclk_div5", 347 .ops = &clk_regmap_gate_ops, 348 .parent_names = (const char *[]){ "fclk_div5_div" }, 349 .num_parents = 1, 350 }, 351 }; 352 353 static struct clk_fixed_factor meson8b_fclk_div7_div = { 354 .mult = 1, 355 .div = 7, 356 .hw.init = &(struct clk_init_data){ 357 .name = "fclk_div7_div", 358 .ops = &clk_fixed_factor_ops, 359 .parent_names = (const char *[]){ "fixed_pll" }, 360 .num_parents = 1, 361 }, 362 }; 363 364 static struct clk_regmap meson8b_fclk_div7 = { 365 .data = &(struct clk_regmap_gate_data){ 366 .offset = HHI_MPLL_CNTL6, 367 .bit_idx = 31, 368 }, 369 .hw.init = &(struct clk_init_data){ 370 .name = "fclk_div7", 371 .ops = &clk_regmap_gate_ops, 372 .parent_names = (const char *[]){ "fclk_div7_div" }, 373 .num_parents = 1, 374 }, 375 }; 376 377 static struct clk_regmap meson8b_mpll_prediv = { 378 .data = &(struct clk_regmap_div_data){ 379 .offset = HHI_MPLL_CNTL5, 380 .shift = 12, 381 .width = 1, 382 }, 383 .hw.init = &(struct clk_init_data){ 384 .name = "mpll_prediv", 385 .ops = &clk_regmap_divider_ro_ops, 386 .parent_names = (const char *[]){ "fixed_pll" }, 387 .num_parents = 1, 388 }, 389 }; 390 391 static struct clk_regmap meson8b_mpll0_div = { 392 .data = &(struct meson_clk_mpll_data){ 393 .sdm = { 394 .reg_off = HHI_MPLL_CNTL7, 395 .shift = 0, 396 .width = 14, 397 }, 398 .sdm_en = { 399 .reg_off = HHI_MPLL_CNTL7, 400 .shift = 15, 401 .width = 1, 402 }, 403 .n2 = { 404 .reg_off = HHI_MPLL_CNTL7, 405 .shift = 16, 406 .width = 9, 407 }, 408 .ssen = { 409 .reg_off = HHI_MPLL_CNTL, 410 .shift = 25, 411 .width = 1, 412 }, 413 .lock = &meson_clk_lock, 414 }, 415 .hw.init = &(struct clk_init_data){ 416 .name = "mpll0_div", 417 .ops = &meson_clk_mpll_ops, 418 .parent_names = (const char *[]){ "mpll_prediv" }, 419 .num_parents = 1, 420 }, 421 }; 422 423 static struct clk_regmap meson8b_mpll0 = { 424 .data = &(struct clk_regmap_gate_data){ 425 .offset = HHI_MPLL_CNTL7, 426 .bit_idx = 14, 427 }, 428 .hw.init = &(struct clk_init_data){ 429 .name = "mpll0", 430 .ops = &clk_regmap_gate_ops, 431 .parent_names = (const char *[]){ "mpll0_div" }, 432 .num_parents = 1, 433 .flags = CLK_SET_RATE_PARENT, 434 }, 435 }; 436 437 static struct clk_regmap meson8b_mpll1_div = { 438 .data = &(struct meson_clk_mpll_data){ 439 .sdm = { 440 .reg_off = HHI_MPLL_CNTL8, 441 .shift = 0, 442 .width = 14, 443 }, 444 .sdm_en = { 445 .reg_off = HHI_MPLL_CNTL8, 446 .shift = 15, 447 .width = 1, 448 }, 449 .n2 = { 450 .reg_off = HHI_MPLL_CNTL8, 451 .shift = 16, 452 .width = 9, 453 }, 454 .lock = &meson_clk_lock, 455 }, 456 .hw.init = &(struct clk_init_data){ 457 .name = "mpll1_div", 458 .ops = &meson_clk_mpll_ops, 459 .parent_names = (const char *[]){ "mpll_prediv" }, 460 .num_parents = 1, 461 }, 462 }; 463 464 static struct clk_regmap meson8b_mpll1 = { 465 .data = &(struct clk_regmap_gate_data){ 466 .offset = HHI_MPLL_CNTL8, 467 .bit_idx = 14, 468 }, 469 .hw.init = &(struct clk_init_data){ 470 .name = "mpll1", 471 .ops = &clk_regmap_gate_ops, 472 .parent_names = (const char *[]){ "mpll1_div" }, 473 .num_parents = 1, 474 .flags = CLK_SET_RATE_PARENT, 475 }, 476 }; 477 478 static struct clk_regmap meson8b_mpll2_div = { 479 .data = &(struct meson_clk_mpll_data){ 480 .sdm = { 481 .reg_off = HHI_MPLL_CNTL9, 482 .shift = 0, 483 .width = 14, 484 }, 485 .sdm_en = { 486 .reg_off = HHI_MPLL_CNTL9, 487 .shift = 15, 488 .width = 1, 489 }, 490 .n2 = { 491 .reg_off = HHI_MPLL_CNTL9, 492 .shift = 16, 493 .width = 9, 494 }, 495 .lock = &meson_clk_lock, 496 }, 497 .hw.init = &(struct clk_init_data){ 498 .name = "mpll2_div", 499 .ops = &meson_clk_mpll_ops, 500 .parent_names = (const char *[]){ "mpll_prediv" }, 501 .num_parents = 1, 502 }, 503 }; 504 505 static struct clk_regmap meson8b_mpll2 = { 506 .data = &(struct clk_regmap_gate_data){ 507 .offset = HHI_MPLL_CNTL9, 508 .bit_idx = 14, 509 }, 510 .hw.init = &(struct clk_init_data){ 511 .name = "mpll2", 512 .ops = &clk_regmap_gate_ops, 513 .parent_names = (const char *[]){ "mpll2_div" }, 514 .num_parents = 1, 515 .flags = CLK_SET_RATE_PARENT, 516 }, 517 }; 518 519 static u32 mux_table_clk81[] = { 6, 5, 7 }; 520 static struct clk_regmap meson8b_mpeg_clk_sel = { 521 .data = &(struct clk_regmap_mux_data){ 522 .offset = HHI_MPEG_CLK_CNTL, 523 .mask = 0x7, 524 .shift = 12, 525 .table = mux_table_clk81, 526 }, 527 .hw.init = &(struct clk_init_data){ 528 .name = "mpeg_clk_sel", 529 .ops = &clk_regmap_mux_ro_ops, 530 /* 531 * FIXME bits 14:12 selects from 8 possible parents: 532 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, 533 * fclk_div4, fclk_div3, fclk_div5 534 */ 535 .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", 536 "fclk_div5" }, 537 .num_parents = 3, 538 }, 539 }; 540 541 static struct clk_regmap meson8b_mpeg_clk_div = { 542 .data = &(struct clk_regmap_div_data){ 543 .offset = HHI_MPEG_CLK_CNTL, 544 .shift = 0, 545 .width = 7, 546 }, 547 .hw.init = &(struct clk_init_data){ 548 .name = "mpeg_clk_div", 549 .ops = &clk_regmap_divider_ro_ops, 550 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 551 .num_parents = 1, 552 }, 553 }; 554 555 static struct clk_regmap meson8b_clk81 = { 556 .data = &(struct clk_regmap_gate_data){ 557 .offset = HHI_MPEG_CLK_CNTL, 558 .bit_idx = 7, 559 }, 560 .hw.init = &(struct clk_init_data){ 561 .name = "clk81", 562 .ops = &clk_regmap_gate_ops, 563 .parent_names = (const char *[]){ "mpeg_clk_div" }, 564 .num_parents = 1, 565 .flags = CLK_IS_CRITICAL, 566 }, 567 }; 568 569 static struct clk_regmap meson8b_cpu_in_sel = { 570 .data = &(struct clk_regmap_mux_data){ 571 .offset = HHI_SYS_CPU_CLK_CNTL0, 572 .mask = 0x1, 573 .shift = 0, 574 }, 575 .hw.init = &(struct clk_init_data){ 576 .name = "cpu_in_sel", 577 .ops = &clk_regmap_mux_ops, 578 .parent_names = (const char *[]){ "xtal", "sys_pll" }, 579 .num_parents = 2, 580 .flags = (CLK_SET_RATE_PARENT | 581 CLK_SET_RATE_NO_REPARENT), 582 }, 583 }; 584 585 static struct clk_fixed_factor meson8b_cpu_in_div2 = { 586 .mult = 1, 587 .div = 2, 588 .hw.init = &(struct clk_init_data){ 589 .name = "cpu_in_div2", 590 .ops = &clk_fixed_factor_ops, 591 .parent_names = (const char *[]){ "cpu_in_sel" }, 592 .num_parents = 1, 593 .flags = CLK_SET_RATE_PARENT, 594 }, 595 }; 596 597 static struct clk_fixed_factor meson8b_cpu_in_div3 = { 598 .mult = 1, 599 .div = 3, 600 .hw.init = &(struct clk_init_data){ 601 .name = "cpu_in_div3", 602 .ops = &clk_fixed_factor_ops, 603 .parent_names = (const char *[]){ "cpu_in_sel" }, 604 .num_parents = 1, 605 .flags = CLK_SET_RATE_PARENT, 606 }, 607 }; 608 609 static const struct clk_div_table cpu_scale_table[] = { 610 { .val = 1, .div = 4 }, 611 { .val = 2, .div = 6 }, 612 { .val = 3, .div = 8 }, 613 { .val = 4, .div = 10 }, 614 { .val = 5, .div = 12 }, 615 { .val = 6, .div = 14 }, 616 { .val = 7, .div = 16 }, 617 { .val = 8, .div = 18 }, 618 { /* sentinel */ }, 619 }; 620 621 static struct clk_regmap meson8b_cpu_scale_div = { 622 .data = &(struct clk_regmap_div_data){ 623 .offset = HHI_SYS_CPU_CLK_CNTL1, 624 .shift = 20, 625 .width = 10, 626 .table = cpu_scale_table, 627 .flags = CLK_DIVIDER_ALLOW_ZERO, 628 }, 629 .hw.init = &(struct clk_init_data){ 630 .name = "cpu_scale_div", 631 .ops = &clk_regmap_divider_ops, 632 .parent_names = (const char *[]){ "cpu_in_sel" }, 633 .num_parents = 1, 634 .flags = CLK_SET_RATE_PARENT, 635 }, 636 }; 637 638 static u32 mux_table_cpu_scale_out_sel[] = { 0, 1, 3 }; 639 static struct clk_regmap meson8b_cpu_scale_out_sel = { 640 .data = &(struct clk_regmap_mux_data){ 641 .offset = HHI_SYS_CPU_CLK_CNTL0, 642 .mask = 0x3, 643 .shift = 2, 644 .table = mux_table_cpu_scale_out_sel, 645 }, 646 .hw.init = &(struct clk_init_data){ 647 .name = "cpu_scale_out_sel", 648 .ops = &clk_regmap_mux_ops, 649 /* 650 * NOTE: We are skipping the parent with value 0x2 (which is 651 * "cpu_in_div3") because it results in a duty cycle of 33% 652 * which makes the system unstable and can result in a lockup 653 * of the whole system. 654 */ 655 .parent_names = (const char *[]) { "cpu_in_sel", 656 "cpu_in_div2", 657 "cpu_scale_div" }, 658 .num_parents = 3, 659 .flags = CLK_SET_RATE_PARENT, 660 }, 661 }; 662 663 static struct clk_regmap meson8b_cpu_clk = { 664 .data = &(struct clk_regmap_mux_data){ 665 .offset = HHI_SYS_CPU_CLK_CNTL0, 666 .mask = 0x1, 667 .shift = 7, 668 }, 669 .hw.init = &(struct clk_init_data){ 670 .name = "cpu_clk", 671 .ops = &clk_regmap_mux_ops, 672 .parent_names = (const char *[]){ "xtal", 673 "cpu_scale_out_sel" }, 674 .num_parents = 2, 675 .flags = (CLK_SET_RATE_PARENT | 676 CLK_SET_RATE_NO_REPARENT | 677 CLK_IS_CRITICAL), 678 }, 679 }; 680 681 static struct clk_regmap meson8b_nand_clk_sel = { 682 .data = &(struct clk_regmap_mux_data){ 683 .offset = HHI_NAND_CLK_CNTL, 684 .mask = 0x7, 685 .shift = 9, 686 .flags = CLK_MUX_ROUND_CLOSEST, 687 }, 688 .hw.init = &(struct clk_init_data){ 689 .name = "nand_clk_sel", 690 .ops = &clk_regmap_mux_ops, 691 /* FIXME all other parents are unknown: */ 692 .parent_names = (const char *[]){ "fclk_div4", "fclk_div3", 693 "fclk_div5", "fclk_div7", "xtal" }, 694 .num_parents = 5, 695 .flags = CLK_SET_RATE_PARENT, 696 }, 697 }; 698 699 static struct clk_regmap meson8b_nand_clk_div = { 700 .data = &(struct clk_regmap_div_data){ 701 .offset = HHI_NAND_CLK_CNTL, 702 .shift = 0, 703 .width = 7, 704 .flags = CLK_DIVIDER_ROUND_CLOSEST, 705 }, 706 .hw.init = &(struct clk_init_data){ 707 .name = "nand_clk_div", 708 .ops = &clk_regmap_divider_ops, 709 .parent_names = (const char *[]){ "nand_clk_sel" }, 710 .num_parents = 1, 711 .flags = CLK_SET_RATE_PARENT, 712 }, 713 }; 714 715 static struct clk_regmap meson8b_nand_clk_gate = { 716 .data = &(struct clk_regmap_gate_data){ 717 .offset = HHI_NAND_CLK_CNTL, 718 .bit_idx = 8, 719 }, 720 .hw.init = &(struct clk_init_data){ 721 .name = "nand_clk_gate", 722 .ops = &clk_regmap_gate_ops, 723 .parent_names = (const char *[]){ "nand_clk_div" }, 724 .num_parents = 1, 725 .flags = CLK_SET_RATE_PARENT, 726 }, 727 }; 728 729 static struct clk_fixed_factor meson8b_cpu_clk_div2 = { 730 .mult = 1, 731 .div = 2, 732 .hw.init = &(struct clk_init_data){ 733 .name = "cpu_clk_div2", 734 .ops = &clk_fixed_factor_ops, 735 .parent_names = (const char *[]){ "cpu_clk" }, 736 .num_parents = 1, 737 }, 738 }; 739 740 static struct clk_fixed_factor meson8b_cpu_clk_div3 = { 741 .mult = 1, 742 .div = 3, 743 .hw.init = &(struct clk_init_data){ 744 .name = "cpu_clk_div3", 745 .ops = &clk_fixed_factor_ops, 746 .parent_names = (const char *[]){ "cpu_clk" }, 747 .num_parents = 1, 748 }, 749 }; 750 751 static struct clk_fixed_factor meson8b_cpu_clk_div4 = { 752 .mult = 1, 753 .div = 4, 754 .hw.init = &(struct clk_init_data){ 755 .name = "cpu_clk_div4", 756 .ops = &clk_fixed_factor_ops, 757 .parent_names = (const char *[]){ "cpu_clk" }, 758 .num_parents = 1, 759 }, 760 }; 761 762 static struct clk_fixed_factor meson8b_cpu_clk_div5 = { 763 .mult = 1, 764 .div = 5, 765 .hw.init = &(struct clk_init_data){ 766 .name = "cpu_clk_div5", 767 .ops = &clk_fixed_factor_ops, 768 .parent_names = (const char *[]){ "cpu_clk" }, 769 .num_parents = 1, 770 }, 771 }; 772 773 static struct clk_fixed_factor meson8b_cpu_clk_div6 = { 774 .mult = 1, 775 .div = 6, 776 .hw.init = &(struct clk_init_data){ 777 .name = "cpu_clk_div6", 778 .ops = &clk_fixed_factor_ops, 779 .parent_names = (const char *[]){ "cpu_clk" }, 780 .num_parents = 1, 781 }, 782 }; 783 784 static struct clk_fixed_factor meson8b_cpu_clk_div7 = { 785 .mult = 1, 786 .div = 7, 787 .hw.init = &(struct clk_init_data){ 788 .name = "cpu_clk_div7", 789 .ops = &clk_fixed_factor_ops, 790 .parent_names = (const char *[]){ "cpu_clk" }, 791 .num_parents = 1, 792 }, 793 }; 794 795 static struct clk_fixed_factor meson8b_cpu_clk_div8 = { 796 .mult = 1, 797 .div = 8, 798 .hw.init = &(struct clk_init_data){ 799 .name = "cpu_clk_div8", 800 .ops = &clk_fixed_factor_ops, 801 .parent_names = (const char *[]){ "cpu_clk" }, 802 .num_parents = 1, 803 }, 804 }; 805 806 static u32 mux_table_abp[] = { 1, 2, 3, 4, 5, 6, 7 }; 807 static struct clk_regmap meson8b_abp_clk_sel = { 808 .data = &(struct clk_regmap_mux_data){ 809 .offset = HHI_SYS_CPU_CLK_CNTL1, 810 .mask = 0x7, 811 .shift = 3, 812 .table = mux_table_abp, 813 }, 814 .hw.init = &(struct clk_init_data){ 815 .name = "abp_clk_sel", 816 .ops = &clk_regmap_mux_ops, 817 .parent_names = (const char *[]){ "cpu_clk_div2", 818 "cpu_clk_div3", 819 "cpu_clk_div4", 820 "cpu_clk_div5", 821 "cpu_clk_div6", 822 "cpu_clk_div7", 823 "cpu_clk_div8", }, 824 .num_parents = 7, 825 }, 826 }; 827 828 static struct clk_regmap meson8b_abp_clk_gate = { 829 .data = &(struct clk_regmap_gate_data){ 830 .offset = HHI_SYS_CPU_CLK_CNTL1, 831 .bit_idx = 16, 832 .flags = CLK_GATE_SET_TO_DISABLE, 833 }, 834 .hw.init = &(struct clk_init_data){ 835 .name = "abp_clk_dis", 836 .ops = &clk_regmap_gate_ro_ops, 837 .parent_names = (const char *[]){ "abp_clk_sel" }, 838 .num_parents = 1, 839 .flags = CLK_SET_RATE_PARENT, 840 }, 841 }; 842 843 static struct clk_regmap meson8b_periph_clk_sel = { 844 .data = &(struct clk_regmap_mux_data){ 845 .offset = HHI_SYS_CPU_CLK_CNTL1, 846 .mask = 0x7, 847 .shift = 6, 848 }, 849 .hw.init = &(struct clk_init_data){ 850 .name = "periph_clk_sel", 851 .ops = &clk_regmap_mux_ops, 852 .parent_names = (const char *[]){ "cpu_clk_div2", 853 "cpu_clk_div3", 854 "cpu_clk_div4", 855 "cpu_clk_div5", 856 "cpu_clk_div6", 857 "cpu_clk_div7", 858 "cpu_clk_div8", }, 859 .num_parents = 7, 860 }, 861 }; 862 863 static struct clk_regmap meson8b_periph_clk_gate = { 864 .data = &(struct clk_regmap_gate_data){ 865 .offset = HHI_SYS_CPU_CLK_CNTL1, 866 .bit_idx = 17, 867 .flags = CLK_GATE_SET_TO_DISABLE, 868 }, 869 .hw.init = &(struct clk_init_data){ 870 .name = "periph_clk_dis", 871 .ops = &clk_regmap_gate_ro_ops, 872 .parent_names = (const char *[]){ "periph_clk_sel" }, 873 .num_parents = 1, 874 .flags = CLK_SET_RATE_PARENT, 875 }, 876 }; 877 878 static u32 mux_table_axi[] = { 1, 2, 3, 4, 5, 6, 7 }; 879 static struct clk_regmap meson8b_axi_clk_sel = { 880 .data = &(struct clk_regmap_mux_data){ 881 .offset = HHI_SYS_CPU_CLK_CNTL1, 882 .mask = 0x7, 883 .shift = 9, 884 .table = mux_table_axi, 885 }, 886 .hw.init = &(struct clk_init_data){ 887 .name = "axi_clk_sel", 888 .ops = &clk_regmap_mux_ops, 889 .parent_names = (const char *[]){ "cpu_clk_div2", 890 "cpu_clk_div3", 891 "cpu_clk_div4", 892 "cpu_clk_div5", 893 "cpu_clk_div6", 894 "cpu_clk_div7", 895 "cpu_clk_div8", }, 896 .num_parents = 7, 897 }, 898 }; 899 900 static struct clk_regmap meson8b_axi_clk_gate = { 901 .data = &(struct clk_regmap_gate_data){ 902 .offset = HHI_SYS_CPU_CLK_CNTL1, 903 .bit_idx = 18, 904 .flags = CLK_GATE_SET_TO_DISABLE, 905 }, 906 .hw.init = &(struct clk_init_data){ 907 .name = "axi_clk_dis", 908 .ops = &clk_regmap_gate_ro_ops, 909 .parent_names = (const char *[]){ "axi_clk_sel" }, 910 .num_parents = 1, 911 .flags = CLK_SET_RATE_PARENT, 912 }, 913 }; 914 915 static struct clk_regmap meson8b_l2_dram_clk_sel = { 916 .data = &(struct clk_regmap_mux_data){ 917 .offset = HHI_SYS_CPU_CLK_CNTL1, 918 .mask = 0x7, 919 .shift = 12, 920 }, 921 .hw.init = &(struct clk_init_data){ 922 .name = "l2_dram_clk_sel", 923 .ops = &clk_regmap_mux_ops, 924 .parent_names = (const char *[]){ "cpu_clk_div2", 925 "cpu_clk_div3", 926 "cpu_clk_div4", 927 "cpu_clk_div5", 928 "cpu_clk_div6", 929 "cpu_clk_div7", 930 "cpu_clk_div8", }, 931 .num_parents = 7, 932 }, 933 }; 934 935 static struct clk_regmap meson8b_l2_dram_clk_gate = { 936 .data = &(struct clk_regmap_gate_data){ 937 .offset = HHI_SYS_CPU_CLK_CNTL1, 938 .bit_idx = 19, 939 .flags = CLK_GATE_SET_TO_DISABLE, 940 }, 941 .hw.init = &(struct clk_init_data){ 942 .name = "l2_dram_clk_dis", 943 .ops = &clk_regmap_gate_ro_ops, 944 .parent_names = (const char *[]){ "l2_dram_clk_sel" }, 945 .num_parents = 1, 946 .flags = CLK_SET_RATE_PARENT, 947 }, 948 }; 949 950 static struct clk_regmap meson8b_vid_pll_in_sel = { 951 .data = &(struct clk_regmap_mux_data){ 952 .offset = HHI_VID_DIVIDER_CNTL, 953 .mask = 0x1, 954 .shift = 15, 955 }, 956 .hw.init = &(struct clk_init_data){ 957 .name = "vid_pll_in_sel", 958 .ops = &clk_regmap_mux_ro_ops, 959 /* 960 * TODO: depending on the SoC there is also a second parent: 961 * Meson8: unknown 962 * Meson8b: hdmi_pll_dco 963 * Meson8m2: vid2_pll 964 */ 965 .parent_names = (const char *[]){ "hdmi_pll_dco" }, 966 .num_parents = 1, 967 .flags = CLK_SET_RATE_PARENT, 968 }, 969 }; 970 971 static struct clk_regmap meson8b_vid_pll_in_en = { 972 .data = &(struct clk_regmap_gate_data){ 973 .offset = HHI_VID_DIVIDER_CNTL, 974 .bit_idx = 16, 975 }, 976 .hw.init = &(struct clk_init_data){ 977 .name = "vid_pll_in_en", 978 .ops = &clk_regmap_gate_ro_ops, 979 .parent_names = (const char *[]){ "vid_pll_in_sel" }, 980 .num_parents = 1, 981 .flags = CLK_SET_RATE_PARENT, 982 }, 983 }; 984 985 static struct clk_regmap meson8b_vid_pll_pre_div = { 986 .data = &(struct clk_regmap_div_data){ 987 .offset = HHI_VID_DIVIDER_CNTL, 988 .shift = 4, 989 .width = 3, 990 }, 991 .hw.init = &(struct clk_init_data){ 992 .name = "vid_pll_pre_div", 993 .ops = &clk_regmap_divider_ro_ops, 994 .parent_names = (const char *[]){ "vid_pll_in_en" }, 995 .num_parents = 1, 996 .flags = CLK_SET_RATE_PARENT, 997 }, 998 }; 999 1000 static struct clk_regmap meson8b_vid_pll_post_div = { 1001 .data = &(struct clk_regmap_div_data){ 1002 .offset = HHI_VID_DIVIDER_CNTL, 1003 .shift = 12, 1004 .width = 3, 1005 }, 1006 .hw.init = &(struct clk_init_data){ 1007 .name = "vid_pll_post_div", 1008 .ops = &clk_regmap_divider_ro_ops, 1009 .parent_names = (const char *[]){ "vid_pll_pre_div" }, 1010 .num_parents = 1, 1011 .flags = CLK_SET_RATE_PARENT, 1012 }, 1013 }; 1014 1015 static struct clk_regmap meson8b_vid_pll = { 1016 .data = &(struct clk_regmap_mux_data){ 1017 .offset = HHI_VID_DIVIDER_CNTL, 1018 .mask = 0x3, 1019 .shift = 8, 1020 }, 1021 .hw.init = &(struct clk_init_data){ 1022 .name = "vid_pll", 1023 .ops = &clk_regmap_mux_ro_ops, 1024 /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */ 1025 .parent_names = (const char *[]){ "vid_pll_pre_div", 1026 "vid_pll_post_div" }, 1027 .num_parents = 2, 1028 .flags = CLK_SET_RATE_PARENT, 1029 }, 1030 }; 1031 1032 static struct clk_regmap meson8b_vid_pll_final_div = { 1033 .data = &(struct clk_regmap_div_data){ 1034 .offset = HHI_VID_CLK_DIV, 1035 .shift = 0, 1036 .width = 8, 1037 }, 1038 .hw.init = &(struct clk_init_data){ 1039 .name = "vid_pll_final_div", 1040 .ops = &clk_regmap_divider_ro_ops, 1041 .parent_names = (const char *[]){ "vid_pll" }, 1042 .num_parents = 1, 1043 .flags = CLK_SET_RATE_PARENT, 1044 }, 1045 }; 1046 1047 static const char * const meson8b_vclk_mux_parents[] = { 1048 "vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5", 1049 "vid_pll_final_div", "fclk_div7", "mpll1" 1050 }; 1051 1052 static struct clk_regmap meson8b_vclk_in_sel = { 1053 .data = &(struct clk_regmap_mux_data){ 1054 .offset = HHI_VID_CLK_CNTL, 1055 .mask = 0x7, 1056 .shift = 16, 1057 }, 1058 .hw.init = &(struct clk_init_data){ 1059 .name = "vclk_in_sel", 1060 .ops = &clk_regmap_mux_ro_ops, 1061 .parent_names = meson8b_vclk_mux_parents, 1062 .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents), 1063 .flags = CLK_SET_RATE_PARENT, 1064 }, 1065 }; 1066 1067 static struct clk_regmap meson8b_vclk_in_en = { 1068 .data = &(struct clk_regmap_gate_data){ 1069 .offset = HHI_VID_CLK_DIV, 1070 .bit_idx = 16, 1071 }, 1072 .hw.init = &(struct clk_init_data){ 1073 .name = "vclk_in_en", 1074 .ops = &clk_regmap_gate_ro_ops, 1075 .parent_names = (const char *[]){ "vclk_in_sel" }, 1076 .num_parents = 1, 1077 .flags = CLK_SET_RATE_PARENT, 1078 }, 1079 }; 1080 1081 static struct clk_regmap meson8b_vclk_div1_gate = { 1082 .data = &(struct clk_regmap_gate_data){ 1083 .offset = HHI_VID_CLK_DIV, 1084 .bit_idx = 0, 1085 }, 1086 .hw.init = &(struct clk_init_data){ 1087 .name = "vclk_div1_en", 1088 .ops = &clk_regmap_gate_ro_ops, 1089 .parent_names = (const char *[]){ "vclk_in_en" }, 1090 .num_parents = 1, 1091 .flags = CLK_SET_RATE_PARENT, 1092 }, 1093 }; 1094 1095 static struct clk_fixed_factor meson8b_vclk_div2_div = { 1096 .mult = 1, 1097 .div = 2, 1098 .hw.init = &(struct clk_init_data){ 1099 .name = "vclk_div2", 1100 .ops = &clk_fixed_factor_ops, 1101 .parent_names = (const char *[]){ "vclk_in_en" }, 1102 .num_parents = 1, 1103 .flags = CLK_SET_RATE_PARENT, 1104 } 1105 }; 1106 1107 static struct clk_regmap meson8b_vclk_div2_div_gate = { 1108 .data = &(struct clk_regmap_gate_data){ 1109 .offset = HHI_VID_CLK_DIV, 1110 .bit_idx = 1, 1111 }, 1112 .hw.init = &(struct clk_init_data){ 1113 .name = "vclk_div2_en", 1114 .ops = &clk_regmap_gate_ro_ops, 1115 .parent_names = (const char *[]){ "vclk_div2" }, 1116 .num_parents = 1, 1117 .flags = CLK_SET_RATE_PARENT, 1118 }, 1119 }; 1120 1121 static struct clk_fixed_factor meson8b_vclk_div4_div = { 1122 .mult = 1, 1123 .div = 4, 1124 .hw.init = &(struct clk_init_data){ 1125 .name = "vclk_div4", 1126 .ops = &clk_fixed_factor_ops, 1127 .parent_names = (const char *[]){ "vclk_in_en" }, 1128 .num_parents = 1, 1129 .flags = CLK_SET_RATE_PARENT, 1130 } 1131 }; 1132 1133 static struct clk_regmap meson8b_vclk_div4_div_gate = { 1134 .data = &(struct clk_regmap_gate_data){ 1135 .offset = HHI_VID_CLK_DIV, 1136 .bit_idx = 2, 1137 }, 1138 .hw.init = &(struct clk_init_data){ 1139 .name = "vclk_div4_en", 1140 .ops = &clk_regmap_gate_ro_ops, 1141 .parent_names = (const char *[]){ "vclk_div4" }, 1142 .num_parents = 1, 1143 .flags = CLK_SET_RATE_PARENT, 1144 }, 1145 }; 1146 1147 static struct clk_fixed_factor meson8b_vclk_div6_div = { 1148 .mult = 1, 1149 .div = 6, 1150 .hw.init = &(struct clk_init_data){ 1151 .name = "vclk_div6", 1152 .ops = &clk_fixed_factor_ops, 1153 .parent_names = (const char *[]){ "vclk_in_en" }, 1154 .num_parents = 1, 1155 .flags = CLK_SET_RATE_PARENT, 1156 } 1157 }; 1158 1159 static struct clk_regmap meson8b_vclk_div6_div_gate = { 1160 .data = &(struct clk_regmap_gate_data){ 1161 .offset = HHI_VID_CLK_DIV, 1162 .bit_idx = 3, 1163 }, 1164 .hw.init = &(struct clk_init_data){ 1165 .name = "vclk_div6_en", 1166 .ops = &clk_regmap_gate_ro_ops, 1167 .parent_names = (const char *[]){ "vclk_div6" }, 1168 .num_parents = 1, 1169 .flags = CLK_SET_RATE_PARENT, 1170 }, 1171 }; 1172 1173 static struct clk_fixed_factor meson8b_vclk_div12_div = { 1174 .mult = 1, 1175 .div = 12, 1176 .hw.init = &(struct clk_init_data){ 1177 .name = "vclk_div12", 1178 .ops = &clk_fixed_factor_ops, 1179 .parent_names = (const char *[]){ "vclk_in_en" }, 1180 .num_parents = 1, 1181 .flags = CLK_SET_RATE_PARENT, 1182 } 1183 }; 1184 1185 static struct clk_regmap meson8b_vclk_div12_div_gate = { 1186 .data = &(struct clk_regmap_gate_data){ 1187 .offset = HHI_VID_CLK_DIV, 1188 .bit_idx = 4, 1189 }, 1190 .hw.init = &(struct clk_init_data){ 1191 .name = "vclk_div12_en", 1192 .ops = &clk_regmap_gate_ro_ops, 1193 .parent_names = (const char *[]){ "vclk_div12" }, 1194 .num_parents = 1, 1195 .flags = CLK_SET_RATE_PARENT, 1196 }, 1197 }; 1198 1199 static struct clk_regmap meson8b_vclk2_in_sel = { 1200 .data = &(struct clk_regmap_mux_data){ 1201 .offset = HHI_VIID_CLK_CNTL, 1202 .mask = 0x7, 1203 .shift = 16, 1204 }, 1205 .hw.init = &(struct clk_init_data){ 1206 .name = "vclk2_in_sel", 1207 .ops = &clk_regmap_mux_ro_ops, 1208 .parent_names = meson8b_vclk_mux_parents, 1209 .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents), 1210 .flags = CLK_SET_RATE_PARENT, 1211 }, 1212 }; 1213 1214 static struct clk_regmap meson8b_vclk2_clk_in_en = { 1215 .data = &(struct clk_regmap_gate_data){ 1216 .offset = HHI_VIID_CLK_DIV, 1217 .bit_idx = 16, 1218 }, 1219 .hw.init = &(struct clk_init_data){ 1220 .name = "vclk2_in_en", 1221 .ops = &clk_regmap_gate_ro_ops, 1222 .parent_names = (const char *[]){ "vclk2_in_sel" }, 1223 .num_parents = 1, 1224 .flags = CLK_SET_RATE_PARENT, 1225 }, 1226 }; 1227 1228 static struct clk_regmap meson8b_vclk2_div1_gate = { 1229 .data = &(struct clk_regmap_gate_data){ 1230 .offset = HHI_VIID_CLK_DIV, 1231 .bit_idx = 0, 1232 }, 1233 .hw.init = &(struct clk_init_data){ 1234 .name = "vclk2_div1_en", 1235 .ops = &clk_regmap_gate_ro_ops, 1236 .parent_names = (const char *[]){ "vclk2_in_en" }, 1237 .num_parents = 1, 1238 .flags = CLK_SET_RATE_PARENT, 1239 }, 1240 }; 1241 1242 static struct clk_fixed_factor meson8b_vclk2_div2_div = { 1243 .mult = 1, 1244 .div = 2, 1245 .hw.init = &(struct clk_init_data){ 1246 .name = "vclk2_div2", 1247 .ops = &clk_fixed_factor_ops, 1248 .parent_names = (const char *[]){ "vclk2_in_en" }, 1249 .num_parents = 1, 1250 .flags = CLK_SET_RATE_PARENT, 1251 } 1252 }; 1253 1254 static struct clk_regmap meson8b_vclk2_div2_div_gate = { 1255 .data = &(struct clk_regmap_gate_data){ 1256 .offset = HHI_VIID_CLK_DIV, 1257 .bit_idx = 1, 1258 }, 1259 .hw.init = &(struct clk_init_data){ 1260 .name = "vclk2_div2_en", 1261 .ops = &clk_regmap_gate_ro_ops, 1262 .parent_names = (const char *[]){ "vclk2_div2" }, 1263 .num_parents = 1, 1264 .flags = CLK_SET_RATE_PARENT, 1265 }, 1266 }; 1267 1268 static struct clk_fixed_factor meson8b_vclk2_div4_div = { 1269 .mult = 1, 1270 .div = 4, 1271 .hw.init = &(struct clk_init_data){ 1272 .name = "vclk2_div4", 1273 .ops = &clk_fixed_factor_ops, 1274 .parent_names = (const char *[]){ "vclk2_in_en" }, 1275 .num_parents = 1, 1276 .flags = CLK_SET_RATE_PARENT, 1277 } 1278 }; 1279 1280 static struct clk_regmap meson8b_vclk2_div4_div_gate = { 1281 .data = &(struct clk_regmap_gate_data){ 1282 .offset = HHI_VIID_CLK_DIV, 1283 .bit_idx = 2, 1284 }, 1285 .hw.init = &(struct clk_init_data){ 1286 .name = "vclk2_div4_en", 1287 .ops = &clk_regmap_gate_ro_ops, 1288 .parent_names = (const char *[]){ "vclk2_div4" }, 1289 .num_parents = 1, 1290 .flags = CLK_SET_RATE_PARENT, 1291 }, 1292 }; 1293 1294 static struct clk_fixed_factor meson8b_vclk2_div6_div = { 1295 .mult = 1, 1296 .div = 6, 1297 .hw.init = &(struct clk_init_data){ 1298 .name = "vclk2_div6", 1299 .ops = &clk_fixed_factor_ops, 1300 .parent_names = (const char *[]){ "vclk2_in_en" }, 1301 .num_parents = 1, 1302 .flags = CLK_SET_RATE_PARENT, 1303 } 1304 }; 1305 1306 static struct clk_regmap meson8b_vclk2_div6_div_gate = { 1307 .data = &(struct clk_regmap_gate_data){ 1308 .offset = HHI_VIID_CLK_DIV, 1309 .bit_idx = 3, 1310 }, 1311 .hw.init = &(struct clk_init_data){ 1312 .name = "vclk2_div6_en", 1313 .ops = &clk_regmap_gate_ro_ops, 1314 .parent_names = (const char *[]){ "vclk2_div6" }, 1315 .num_parents = 1, 1316 .flags = CLK_SET_RATE_PARENT, 1317 }, 1318 }; 1319 1320 static struct clk_fixed_factor meson8b_vclk2_div12_div = { 1321 .mult = 1, 1322 .div = 12, 1323 .hw.init = &(struct clk_init_data){ 1324 .name = "vclk2_div12", 1325 .ops = &clk_fixed_factor_ops, 1326 .parent_names = (const char *[]){ "vclk2_in_en" }, 1327 .num_parents = 1, 1328 .flags = CLK_SET_RATE_PARENT, 1329 } 1330 }; 1331 1332 static struct clk_regmap meson8b_vclk2_div12_div_gate = { 1333 .data = &(struct clk_regmap_gate_data){ 1334 .offset = HHI_VIID_CLK_DIV, 1335 .bit_idx = 4, 1336 }, 1337 .hw.init = &(struct clk_init_data){ 1338 .name = "vclk2_div12_en", 1339 .ops = &clk_regmap_gate_ro_ops, 1340 .parent_names = (const char *[]){ "vclk2_div12" }, 1341 .num_parents = 1, 1342 .flags = CLK_SET_RATE_PARENT, 1343 }, 1344 }; 1345 1346 static const char * const meson8b_vclk_enc_mux_parents[] = { 1347 "vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en", 1348 "vclk_div12_en", 1349 }; 1350 1351 static struct clk_regmap meson8b_cts_enct_sel = { 1352 .data = &(struct clk_regmap_mux_data){ 1353 .offset = HHI_VID_CLK_DIV, 1354 .mask = 0xf, 1355 .shift = 20, 1356 }, 1357 .hw.init = &(struct clk_init_data){ 1358 .name = "cts_enct_sel", 1359 .ops = &clk_regmap_mux_ro_ops, 1360 .parent_names = meson8b_vclk_enc_mux_parents, 1361 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), 1362 .flags = CLK_SET_RATE_PARENT, 1363 }, 1364 }; 1365 1366 static struct clk_regmap meson8b_cts_enct = { 1367 .data = &(struct clk_regmap_gate_data){ 1368 .offset = HHI_VID_CLK_CNTL2, 1369 .bit_idx = 1, 1370 }, 1371 .hw.init = &(struct clk_init_data){ 1372 .name = "cts_enct", 1373 .ops = &clk_regmap_gate_ro_ops, 1374 .parent_names = (const char *[]){ "cts_enct_sel" }, 1375 .num_parents = 1, 1376 .flags = CLK_SET_RATE_PARENT, 1377 }, 1378 }; 1379 1380 static struct clk_regmap meson8b_cts_encp_sel = { 1381 .data = &(struct clk_regmap_mux_data){ 1382 .offset = HHI_VID_CLK_DIV, 1383 .mask = 0xf, 1384 .shift = 24, 1385 }, 1386 .hw.init = &(struct clk_init_data){ 1387 .name = "cts_encp_sel", 1388 .ops = &clk_regmap_mux_ro_ops, 1389 .parent_names = meson8b_vclk_enc_mux_parents, 1390 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), 1391 .flags = CLK_SET_RATE_PARENT, 1392 }, 1393 }; 1394 1395 static struct clk_regmap meson8b_cts_encp = { 1396 .data = &(struct clk_regmap_gate_data){ 1397 .offset = HHI_VID_CLK_CNTL2, 1398 .bit_idx = 2, 1399 }, 1400 .hw.init = &(struct clk_init_data){ 1401 .name = "cts_encp", 1402 .ops = &clk_regmap_gate_ro_ops, 1403 .parent_names = (const char *[]){ "cts_encp_sel" }, 1404 .num_parents = 1, 1405 .flags = CLK_SET_RATE_PARENT, 1406 }, 1407 }; 1408 1409 static struct clk_regmap meson8b_cts_enci_sel = { 1410 .data = &(struct clk_regmap_mux_data){ 1411 .offset = HHI_VID_CLK_DIV, 1412 .mask = 0xf, 1413 .shift = 28, 1414 }, 1415 .hw.init = &(struct clk_init_data){ 1416 .name = "cts_enci_sel", 1417 .ops = &clk_regmap_mux_ro_ops, 1418 .parent_names = meson8b_vclk_enc_mux_parents, 1419 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), 1420 .flags = CLK_SET_RATE_PARENT, 1421 }, 1422 }; 1423 1424 static struct clk_regmap meson8b_cts_enci = { 1425 .data = &(struct clk_regmap_gate_data){ 1426 .offset = HHI_VID_CLK_CNTL2, 1427 .bit_idx = 0, 1428 }, 1429 .hw.init = &(struct clk_init_data){ 1430 .name = "cts_enci", 1431 .ops = &clk_regmap_gate_ro_ops, 1432 .parent_names = (const char *[]){ "cts_enci_sel" }, 1433 .num_parents = 1, 1434 .flags = CLK_SET_RATE_PARENT, 1435 }, 1436 }; 1437 1438 static struct clk_regmap meson8b_hdmi_tx_pixel_sel = { 1439 .data = &(struct clk_regmap_mux_data){ 1440 .offset = HHI_HDMI_CLK_CNTL, 1441 .mask = 0xf, 1442 .shift = 16, 1443 }, 1444 .hw.init = &(struct clk_init_data){ 1445 .name = "hdmi_tx_pixel_sel", 1446 .ops = &clk_regmap_mux_ro_ops, 1447 .parent_names = meson8b_vclk_enc_mux_parents, 1448 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), 1449 .flags = CLK_SET_RATE_PARENT, 1450 }, 1451 }; 1452 1453 static struct clk_regmap meson8b_hdmi_tx_pixel = { 1454 .data = &(struct clk_regmap_gate_data){ 1455 .offset = HHI_VID_CLK_CNTL2, 1456 .bit_idx = 5, 1457 }, 1458 .hw.init = &(struct clk_init_data){ 1459 .name = "hdmi_tx_pixel", 1460 .ops = &clk_regmap_gate_ro_ops, 1461 .parent_names = (const char *[]){ "hdmi_tx_pixel_sel" }, 1462 .num_parents = 1, 1463 .flags = CLK_SET_RATE_PARENT, 1464 }, 1465 }; 1466 1467 static const char * const meson8b_vclk2_enc_mux_parents[] = { 1468 "vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en", 1469 "vclk2_div12_en", 1470 }; 1471 1472 static struct clk_regmap meson8b_cts_encl_sel = { 1473 .data = &(struct clk_regmap_mux_data){ 1474 .offset = HHI_VIID_CLK_DIV, 1475 .mask = 0xf, 1476 .shift = 12, 1477 }, 1478 .hw.init = &(struct clk_init_data){ 1479 .name = "cts_encl_sel", 1480 .ops = &clk_regmap_mux_ro_ops, 1481 .parent_names = meson8b_vclk2_enc_mux_parents, 1482 .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents), 1483 .flags = CLK_SET_RATE_PARENT, 1484 }, 1485 }; 1486 1487 static struct clk_regmap meson8b_cts_encl = { 1488 .data = &(struct clk_regmap_gate_data){ 1489 .offset = HHI_VID_CLK_CNTL2, 1490 .bit_idx = 3, 1491 }, 1492 .hw.init = &(struct clk_init_data){ 1493 .name = "cts_encl", 1494 .ops = &clk_regmap_gate_ro_ops, 1495 .parent_names = (const char *[]){ "cts_encl_sel" }, 1496 .num_parents = 1, 1497 .flags = CLK_SET_RATE_PARENT, 1498 }, 1499 }; 1500 1501 static struct clk_regmap meson8b_cts_vdac0_sel = { 1502 .data = &(struct clk_regmap_mux_data){ 1503 .offset = HHI_VIID_CLK_DIV, 1504 .mask = 0xf, 1505 .shift = 28, 1506 }, 1507 .hw.init = &(struct clk_init_data){ 1508 .name = "cts_vdac0_sel", 1509 .ops = &clk_regmap_mux_ro_ops, 1510 .parent_names = meson8b_vclk2_enc_mux_parents, 1511 .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents), 1512 .flags = CLK_SET_RATE_PARENT, 1513 }, 1514 }; 1515 1516 static struct clk_regmap meson8b_cts_vdac0 = { 1517 .data = &(struct clk_regmap_gate_data){ 1518 .offset = HHI_VID_CLK_CNTL2, 1519 .bit_idx = 4, 1520 }, 1521 .hw.init = &(struct clk_init_data){ 1522 .name = "cts_vdac0", 1523 .ops = &clk_regmap_gate_ro_ops, 1524 .parent_names = (const char *[]){ "cts_vdac0_sel" }, 1525 .num_parents = 1, 1526 .flags = CLK_SET_RATE_PARENT, 1527 }, 1528 }; 1529 1530 static struct clk_regmap meson8b_hdmi_sys_sel = { 1531 .data = &(struct clk_regmap_mux_data){ 1532 .offset = HHI_HDMI_CLK_CNTL, 1533 .mask = 0x3, 1534 .shift = 9, 1535 .flags = CLK_MUX_ROUND_CLOSEST, 1536 }, 1537 .hw.init = &(struct clk_init_data){ 1538 .name = "hdmi_sys_sel", 1539 .ops = &clk_regmap_mux_ro_ops, 1540 /* FIXME: all other parents are unknown */ 1541 .parent_names = (const char *[]){ "xtal" }, 1542 .num_parents = 1, 1543 .flags = CLK_SET_RATE_NO_REPARENT, 1544 }, 1545 }; 1546 1547 static struct clk_regmap meson8b_hdmi_sys_div = { 1548 .data = &(struct clk_regmap_div_data){ 1549 .offset = HHI_HDMI_CLK_CNTL, 1550 .shift = 0, 1551 .width = 7, 1552 }, 1553 .hw.init = &(struct clk_init_data){ 1554 .name = "hdmi_sys_div", 1555 .ops = &clk_regmap_divider_ro_ops, 1556 .parent_names = (const char *[]){ "hdmi_sys_sel" }, 1557 .num_parents = 1, 1558 .flags = CLK_SET_RATE_PARENT, 1559 }, 1560 }; 1561 1562 static struct clk_regmap meson8b_hdmi_sys = { 1563 .data = &(struct clk_regmap_gate_data){ 1564 .offset = HHI_HDMI_CLK_CNTL, 1565 .bit_idx = 8, 1566 }, 1567 .hw.init = &(struct clk_init_data) { 1568 .name = "hdmi_sys", 1569 .ops = &clk_regmap_gate_ro_ops, 1570 .parent_names = (const char *[]){ "hdmi_sys_div" }, 1571 .num_parents = 1, 1572 .flags = CLK_SET_RATE_PARENT, 1573 }, 1574 }; 1575 1576 /* Everything Else (EE) domain gates */ 1577 1578 static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); 1579 static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1); 1580 static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5); 1581 static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6); 1582 static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7); 1583 static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8); 1584 static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9); 1585 static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10); 1586 static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11); 1587 static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12); 1588 static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13); 1589 static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14); 1590 static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15); 1591 static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16); 1592 static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17); 1593 static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18); 1594 static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19); 1595 static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23); 1596 static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30); 1597 1598 static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2); 1599 static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3); 1600 static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4); 1601 static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6); 1602 static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7); 1603 static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8); 1604 static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9); 1605 static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10); 1606 static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11); 1607 static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12); 1608 static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13); 1609 static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14); 1610 static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15); 1611 static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16); 1612 static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20); 1613 static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21); 1614 static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22); 1615 static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23); 1616 static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24); 1617 static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25); 1618 static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26); 1619 static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28); 1620 static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29); 1621 static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30); 1622 static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31); 1623 1624 static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1); 1625 static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); 1626 static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3); 1627 static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4); 1628 static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8); 1629 static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9); 1630 static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11); 1631 static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12); 1632 static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15); 1633 static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22); 1634 static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25); 1635 static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); 1636 static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29); 1637 1638 static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1); 1639 static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2); 1640 static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3); 1641 static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4); 1642 static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8); 1643 static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9); 1644 static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10); 1645 static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14); 1646 static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16); 1647 static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20); 1648 static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21); 1649 static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22); 1650 static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24); 1651 static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25); 1652 static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26); 1653 static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31); 1654 1655 /* Always On (AO) domain gates */ 1656 1657 static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0); 1658 static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1); 1659 static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2); 1660 static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3); 1661 1662 static struct clk_hw_onecell_data meson8b_hw_onecell_data = { 1663 .hws = { 1664 [CLKID_XTAL] = &meson8b_xtal.hw, 1665 [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, 1666 [CLKID_PLL_VID] = &meson8b_vid_pll.hw, 1667 [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, 1668 [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, 1669 [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, 1670 [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, 1671 [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, 1672 [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, 1673 [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, 1674 [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw, 1675 [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw, 1676 [CLKID_CLK81] = &meson8b_clk81.hw, 1677 [CLKID_DDR] = &meson8b_ddr.hw, 1678 [CLKID_DOS] = &meson8b_dos.hw, 1679 [CLKID_ISA] = &meson8b_isa.hw, 1680 [CLKID_PL301] = &meson8b_pl301.hw, 1681 [CLKID_PERIPHS] = &meson8b_periphs.hw, 1682 [CLKID_SPICC] = &meson8b_spicc.hw, 1683 [CLKID_I2C] = &meson8b_i2c.hw, 1684 [CLKID_SAR_ADC] = &meson8b_sar_adc.hw, 1685 [CLKID_SMART_CARD] = &meson8b_smart_card.hw, 1686 [CLKID_RNG0] = &meson8b_rng0.hw, 1687 [CLKID_UART0] = &meson8b_uart0.hw, 1688 [CLKID_SDHC] = &meson8b_sdhc.hw, 1689 [CLKID_STREAM] = &meson8b_stream.hw, 1690 [CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw, 1691 [CLKID_SDIO] = &meson8b_sdio.hw, 1692 [CLKID_ABUF] = &meson8b_abuf.hw, 1693 [CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw, 1694 [CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw, 1695 [CLKID_SPI] = &meson8b_spi.hw, 1696 [CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw, 1697 [CLKID_ETH] = &meson8b_eth.hw, 1698 [CLKID_DEMUX] = &meson8b_demux.hw, 1699 [CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw, 1700 [CLKID_IEC958] = &meson8b_iec958.hw, 1701 [CLKID_I2S_OUT] = &meson8b_i2s_out.hw, 1702 [CLKID_AMCLK] = &meson8b_amclk.hw, 1703 [CLKID_AIFIFO2] = &meson8b_aififo2.hw, 1704 [CLKID_MIXER] = &meson8b_mixer.hw, 1705 [CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw, 1706 [CLKID_ADC] = &meson8b_adc.hw, 1707 [CLKID_BLKMV] = &meson8b_blkmv.hw, 1708 [CLKID_AIU] = &meson8b_aiu.hw, 1709 [CLKID_UART1] = &meson8b_uart1.hw, 1710 [CLKID_G2D] = &meson8b_g2d.hw, 1711 [CLKID_USB0] = &meson8b_usb0.hw, 1712 [CLKID_USB1] = &meson8b_usb1.hw, 1713 [CLKID_RESET] = &meson8b_reset.hw, 1714 [CLKID_NAND] = &meson8b_nand.hw, 1715 [CLKID_DOS_PARSER] = &meson8b_dos_parser.hw, 1716 [CLKID_USB] = &meson8b_usb.hw, 1717 [CLKID_VDIN1] = &meson8b_vdin1.hw, 1718 [CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw, 1719 [CLKID_EFUSE] = &meson8b_efuse.hw, 1720 [CLKID_BOOT_ROM] = &meson8b_boot_rom.hw, 1721 [CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw, 1722 [CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw, 1723 [CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw, 1724 [CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw, 1725 [CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw, 1726 [CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw, 1727 [CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw, 1728 [CLKID_DVIN] = &meson8b_dvin.hw, 1729 [CLKID_UART2] = &meson8b_uart2.hw, 1730 [CLKID_SANA] = &meson8b_sana.hw, 1731 [CLKID_VPU_INTR] = &meson8b_vpu_intr.hw, 1732 [CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw, 1733 [CLKID_CLK81_A9] = &meson8b_clk81_a9.hw, 1734 [CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw, 1735 [CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw, 1736 [CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw, 1737 [CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw, 1738 [CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw, 1739 [CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw, 1740 [CLKID_DAC_CLK] = &meson8b_dac_clk.hw, 1741 [CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw, 1742 [CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw, 1743 [CLKID_ENC480P] = &meson8b_enc480p.hw, 1744 [CLKID_RNG1] = &meson8b_rng1.hw, 1745 [CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw, 1746 [CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw, 1747 [CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw, 1748 [CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw, 1749 [CLKID_EDP] = &meson8b_edp.hw, 1750 [CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw, 1751 [CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw, 1752 [CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw, 1753 [CLKID_AO_IFACE] = &meson8b_ao_iface.hw, 1754 [CLKID_MPLL0] = &meson8b_mpll0.hw, 1755 [CLKID_MPLL1] = &meson8b_mpll1.hw, 1756 [CLKID_MPLL2] = &meson8b_mpll2.hw, 1757 [CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw, 1758 [CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw, 1759 [CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw, 1760 [CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw, 1761 [CLKID_CPU_IN_DIV2] = &meson8b_cpu_in_div2.hw, 1762 [CLKID_CPU_IN_DIV3] = &meson8b_cpu_in_div3.hw, 1763 [CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw, 1764 [CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw, 1765 [CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw, 1766 [CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw, 1767 [CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw, 1768 [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw, 1769 [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw, 1770 [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw, 1771 [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, 1772 [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, 1773 [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, 1774 [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, 1775 [CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw, 1776 [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, 1777 [CLKID_CPU_CLK_DIV2] = &meson8b_cpu_clk_div2.hw, 1778 [CLKID_CPU_CLK_DIV3] = &meson8b_cpu_clk_div3.hw, 1779 [CLKID_CPU_CLK_DIV4] = &meson8b_cpu_clk_div4.hw, 1780 [CLKID_CPU_CLK_DIV5] = &meson8b_cpu_clk_div5.hw, 1781 [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw, 1782 [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw, 1783 [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw, 1784 [CLKID_ABP_SEL] = &meson8b_abp_clk_sel.hw, 1785 [CLKID_ABP] = &meson8b_abp_clk_gate.hw, 1786 [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw, 1787 [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw, 1788 [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw, 1789 [CLKID_AXI] = &meson8b_axi_clk_gate.hw, 1790 [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw, 1791 [CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw, 1792 [CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw, 1793 [CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw, 1794 [CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw, 1795 [CLKID_VID_PLL_IN_EN] = &meson8b_vid_pll_in_en.hw, 1796 [CLKID_VID_PLL_PRE_DIV] = &meson8b_vid_pll_pre_div.hw, 1797 [CLKID_VID_PLL_POST_DIV] = &meson8b_vid_pll_post_div.hw, 1798 [CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw, 1799 [CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw, 1800 [CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw, 1801 [CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw, 1802 [CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw, 1803 [CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw, 1804 [CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw, 1805 [CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw, 1806 [CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw, 1807 [CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw, 1808 [CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw, 1809 [CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw, 1810 [CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw, 1811 [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw, 1812 [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw, 1813 [CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw, 1814 [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw, 1815 [CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw, 1816 [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw, 1817 [CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw, 1818 [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw, 1819 [CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw, 1820 [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw, 1821 [CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw, 1822 [CLKID_CTS_ENCT] = &meson8b_cts_enct.hw, 1823 [CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw, 1824 [CLKID_CTS_ENCP] = &meson8b_cts_encp.hw, 1825 [CLKID_CTS_ENCI_SEL] = &meson8b_cts_enci_sel.hw, 1826 [CLKID_CTS_ENCI] = &meson8b_cts_enci.hw, 1827 [CLKID_HDMI_TX_PIXEL_SEL] = &meson8b_hdmi_tx_pixel_sel.hw, 1828 [CLKID_HDMI_TX_PIXEL] = &meson8b_hdmi_tx_pixel.hw, 1829 [CLKID_CTS_ENCL_SEL] = &meson8b_cts_encl_sel.hw, 1830 [CLKID_CTS_ENCL] = &meson8b_cts_encl.hw, 1831 [CLKID_CTS_VDAC0_SEL] = &meson8b_cts_vdac0_sel.hw, 1832 [CLKID_CTS_VDAC0] = &meson8b_cts_vdac0.hw, 1833 [CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw, 1834 [CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw, 1835 [CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw, 1836 [CLK_NR_CLKS] = NULL, 1837 }, 1838 .num = CLK_NR_CLKS, 1839 }; 1840 1841 static struct clk_regmap *const meson8b_clk_regmaps[] = { 1842 &meson8b_clk81, 1843 &meson8b_ddr, 1844 &meson8b_dos, 1845 &meson8b_isa, 1846 &meson8b_pl301, 1847 &meson8b_periphs, 1848 &meson8b_spicc, 1849 &meson8b_i2c, 1850 &meson8b_sar_adc, 1851 &meson8b_smart_card, 1852 &meson8b_rng0, 1853 &meson8b_uart0, 1854 &meson8b_sdhc, 1855 &meson8b_stream, 1856 &meson8b_async_fifo, 1857 &meson8b_sdio, 1858 &meson8b_abuf, 1859 &meson8b_hiu_iface, 1860 &meson8b_assist_misc, 1861 &meson8b_spi, 1862 &meson8b_i2s_spdif, 1863 &meson8b_eth, 1864 &meson8b_demux, 1865 &meson8b_aiu_glue, 1866 &meson8b_iec958, 1867 &meson8b_i2s_out, 1868 &meson8b_amclk, 1869 &meson8b_aififo2, 1870 &meson8b_mixer, 1871 &meson8b_mixer_iface, 1872 &meson8b_adc, 1873 &meson8b_blkmv, 1874 &meson8b_aiu, 1875 &meson8b_uart1, 1876 &meson8b_g2d, 1877 &meson8b_usb0, 1878 &meson8b_usb1, 1879 &meson8b_reset, 1880 &meson8b_nand, 1881 &meson8b_dos_parser, 1882 &meson8b_usb, 1883 &meson8b_vdin1, 1884 &meson8b_ahb_arb0, 1885 &meson8b_efuse, 1886 &meson8b_boot_rom, 1887 &meson8b_ahb_data_bus, 1888 &meson8b_ahb_ctrl_bus, 1889 &meson8b_hdmi_intr_sync, 1890 &meson8b_hdmi_pclk, 1891 &meson8b_usb1_ddr_bridge, 1892 &meson8b_usb0_ddr_bridge, 1893 &meson8b_mmc_pclk, 1894 &meson8b_dvin, 1895 &meson8b_uart2, 1896 &meson8b_sana, 1897 &meson8b_vpu_intr, 1898 &meson8b_sec_ahb_ahb3_bridge, 1899 &meson8b_clk81_a9, 1900 &meson8b_vclk2_venci0, 1901 &meson8b_vclk2_venci1, 1902 &meson8b_vclk2_vencp0, 1903 &meson8b_vclk2_vencp1, 1904 &meson8b_gclk_venci_int, 1905 &meson8b_gclk_vencp_int, 1906 &meson8b_dac_clk, 1907 &meson8b_aoclk_gate, 1908 &meson8b_iec958_gate, 1909 &meson8b_enc480p, 1910 &meson8b_rng1, 1911 &meson8b_gclk_vencl_int, 1912 &meson8b_vclk2_venclmcc, 1913 &meson8b_vclk2_vencl, 1914 &meson8b_vclk2_other, 1915 &meson8b_edp, 1916 &meson8b_ao_media_cpu, 1917 &meson8b_ao_ahb_sram, 1918 &meson8b_ao_ahb_bus, 1919 &meson8b_ao_iface, 1920 &meson8b_mpeg_clk_div, 1921 &meson8b_mpeg_clk_sel, 1922 &meson8b_mpll0, 1923 &meson8b_mpll1, 1924 &meson8b_mpll2, 1925 &meson8b_mpll0_div, 1926 &meson8b_mpll1_div, 1927 &meson8b_mpll2_div, 1928 &meson8b_fixed_pll, 1929 &meson8b_sys_pll, 1930 &meson8b_cpu_in_sel, 1931 &meson8b_cpu_scale_div, 1932 &meson8b_cpu_scale_out_sel, 1933 &meson8b_cpu_clk, 1934 &meson8b_mpll_prediv, 1935 &meson8b_fclk_div2, 1936 &meson8b_fclk_div3, 1937 &meson8b_fclk_div4, 1938 &meson8b_fclk_div5, 1939 &meson8b_fclk_div7, 1940 &meson8b_nand_clk_sel, 1941 &meson8b_nand_clk_div, 1942 &meson8b_nand_clk_gate, 1943 &meson8b_fixed_pll_dco, 1944 &meson8b_hdmi_pll_dco, 1945 &meson8b_sys_pll_dco, 1946 &meson8b_abp_clk_sel, 1947 &meson8b_abp_clk_gate, 1948 &meson8b_periph_clk_sel, 1949 &meson8b_periph_clk_gate, 1950 &meson8b_axi_clk_sel, 1951 &meson8b_axi_clk_gate, 1952 &meson8b_l2_dram_clk_sel, 1953 &meson8b_l2_dram_clk_gate, 1954 &meson8b_hdmi_pll_lvds_out, 1955 &meson8b_hdmi_pll_hdmi_out, 1956 &meson8b_vid_pll_in_sel, 1957 &meson8b_vid_pll_in_en, 1958 &meson8b_vid_pll_pre_div, 1959 &meson8b_vid_pll_post_div, 1960 &meson8b_vid_pll, 1961 &meson8b_vid_pll_final_div, 1962 &meson8b_vclk_in_sel, 1963 &meson8b_vclk_in_en, 1964 &meson8b_vclk_div1_gate, 1965 &meson8b_vclk_div2_div_gate, 1966 &meson8b_vclk_div4_div_gate, 1967 &meson8b_vclk_div6_div_gate, 1968 &meson8b_vclk_div12_div_gate, 1969 &meson8b_vclk2_in_sel, 1970 &meson8b_vclk2_clk_in_en, 1971 &meson8b_vclk2_div1_gate, 1972 &meson8b_vclk2_div2_div_gate, 1973 &meson8b_vclk2_div4_div_gate, 1974 &meson8b_vclk2_div6_div_gate, 1975 &meson8b_vclk2_div12_div_gate, 1976 &meson8b_cts_enct_sel, 1977 &meson8b_cts_enct, 1978 &meson8b_cts_encp_sel, 1979 &meson8b_cts_encp, 1980 &meson8b_cts_enci_sel, 1981 &meson8b_cts_enci, 1982 &meson8b_hdmi_tx_pixel_sel, 1983 &meson8b_hdmi_tx_pixel, 1984 &meson8b_cts_encl_sel, 1985 &meson8b_cts_encl, 1986 &meson8b_cts_vdac0_sel, 1987 &meson8b_cts_vdac0, 1988 &meson8b_hdmi_sys_sel, 1989 &meson8b_hdmi_sys_div, 1990 &meson8b_hdmi_sys, 1991 }; 1992 1993 static const struct meson8b_clk_reset_line { 1994 u32 reg; 1995 u8 bit_idx; 1996 } meson8b_clk_reset_bits[] = { 1997 [CLKC_RESET_L2_CACHE_SOFT_RESET] = { 1998 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30 1999 }, 2000 [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = { 2001 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29 2002 }, 2003 [CLKC_RESET_SCU_SOFT_RESET] = { 2004 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28 2005 }, 2006 [CLKC_RESET_CPU3_SOFT_RESET] = { 2007 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27 2008 }, 2009 [CLKC_RESET_CPU2_SOFT_RESET] = { 2010 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26 2011 }, 2012 [CLKC_RESET_CPU1_SOFT_RESET] = { 2013 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25 2014 }, 2015 [CLKC_RESET_CPU0_SOFT_RESET] = { 2016 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24 2017 }, 2018 [CLKC_RESET_A5_GLOBAL_RESET] = { 2019 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18 2020 }, 2021 [CLKC_RESET_A5_AXI_SOFT_RESET] = { 2022 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17 2023 }, 2024 [CLKC_RESET_A5_ABP_SOFT_RESET] = { 2025 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16 2026 }, 2027 [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = { 2028 .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30 2029 }, 2030 [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = { 2031 .reg = HHI_VID_CLK_CNTL, .bit_idx = 15 2032 }, 2033 [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = { 2034 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7 2035 }, 2036 [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = { 2037 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3 2038 }, 2039 [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = { 2040 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1 2041 }, 2042 [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = { 2043 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0 2044 }, 2045 }; 2046 2047 static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, 2048 unsigned long id, bool assert) 2049 { 2050 struct meson8b_clk_reset *meson8b_clk_reset = 2051 container_of(rcdev, struct meson8b_clk_reset, reset); 2052 unsigned long flags; 2053 const struct meson8b_clk_reset_line *reset; 2054 2055 if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) 2056 return -EINVAL; 2057 2058 reset = &meson8b_clk_reset_bits[id]; 2059 2060 spin_lock_irqsave(&meson_clk_lock, flags); 2061 2062 if (assert) 2063 regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, 2064 BIT(reset->bit_idx), BIT(reset->bit_idx)); 2065 else 2066 regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, 2067 BIT(reset->bit_idx), 0); 2068 2069 spin_unlock_irqrestore(&meson_clk_lock, flags); 2070 2071 return 0; 2072 } 2073 2074 static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev, 2075 unsigned long id) 2076 { 2077 return meson8b_clk_reset_update(rcdev, id, true); 2078 } 2079 2080 static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev, 2081 unsigned long id) 2082 { 2083 return meson8b_clk_reset_update(rcdev, id, false); 2084 } 2085 2086 static const struct reset_control_ops meson8b_clk_reset_ops = { 2087 .assert = meson8b_clk_reset_assert, 2088 .deassert = meson8b_clk_reset_deassert, 2089 }; 2090 2091 struct meson8b_nb_data { 2092 struct notifier_block nb; 2093 struct clk_hw_onecell_data *onecell_data; 2094 }; 2095 2096 static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb, 2097 unsigned long event, void *data) 2098 { 2099 struct meson8b_nb_data *nb_data = 2100 container_of(nb, struct meson8b_nb_data, nb); 2101 struct clk_hw **hws = nb_data->onecell_data->hws; 2102 struct clk_hw *cpu_clk_hw, *parent_clk_hw; 2103 struct clk *cpu_clk, *parent_clk; 2104 int ret; 2105 2106 switch (event) { 2107 case PRE_RATE_CHANGE: 2108 parent_clk_hw = hws[CLKID_XTAL]; 2109 break; 2110 2111 case POST_RATE_CHANGE: 2112 parent_clk_hw = hws[CLKID_CPU_SCALE_OUT_SEL]; 2113 break; 2114 2115 default: 2116 return NOTIFY_DONE; 2117 } 2118 2119 cpu_clk_hw = hws[CLKID_CPUCLK]; 2120 cpu_clk = __clk_lookup(clk_hw_get_name(cpu_clk_hw)); 2121 2122 parent_clk = __clk_lookup(clk_hw_get_name(parent_clk_hw)); 2123 2124 ret = clk_set_parent(cpu_clk, parent_clk); 2125 if (ret) 2126 return notifier_from_errno(ret); 2127 2128 udelay(100); 2129 2130 return NOTIFY_OK; 2131 } 2132 2133 static struct meson8b_nb_data meson8b_cpu_nb_data = { 2134 .nb.notifier_call = meson8b_cpu_clk_notifier_cb, 2135 .onecell_data = &meson8b_hw_onecell_data, 2136 }; 2137 2138 static const struct regmap_config clkc_regmap_config = { 2139 .reg_bits = 32, 2140 .val_bits = 32, 2141 .reg_stride = 4, 2142 }; 2143 2144 static void __init meson8b_clkc_init(struct device_node *np) 2145 { 2146 struct meson8b_clk_reset *rstc; 2147 const char *notifier_clk_name; 2148 struct clk *notifier_clk; 2149 void __iomem *clk_base; 2150 struct regmap *map; 2151 int i, ret; 2152 2153 map = syscon_node_to_regmap(of_get_parent(np)); 2154 if (IS_ERR(map)) { 2155 pr_info("failed to get HHI regmap - Trying obsolete regs\n"); 2156 2157 /* Generic clocks, PLLs and some of the reset-bits */ 2158 clk_base = of_iomap(np, 1); 2159 if (!clk_base) { 2160 pr_err("%s: Unable to map clk base\n", __func__); 2161 return; 2162 } 2163 2164 map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config); 2165 if (IS_ERR(map)) 2166 return; 2167 } 2168 2169 rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); 2170 if (!rstc) 2171 return; 2172 2173 /* Reset Controller */ 2174 rstc->regmap = map; 2175 rstc->reset.ops = &meson8b_clk_reset_ops; 2176 rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits); 2177 rstc->reset.of_node = np; 2178 ret = reset_controller_register(&rstc->reset); 2179 if (ret) { 2180 pr_err("%s: Failed to register clkc reset controller: %d\n", 2181 __func__, ret); 2182 return; 2183 } 2184 2185 /* Populate regmap for the regmap backed clocks */ 2186 for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++) 2187 meson8b_clk_regmaps[i]->map = map; 2188 2189 /* 2190 * register all clks 2191 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 2192 */ 2193 for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { 2194 /* array might be sparse */ 2195 if (!meson8b_hw_onecell_data.hws[i]) 2196 continue; 2197 2198 ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]); 2199 if (ret) 2200 return; 2201 } 2202 2203 /* 2204 * FIXME we shouldn't program the muxes in notifier handlers. The 2205 * tricky programming sequence will be handled by the forthcoming 2206 * coordinated clock rates mechanism once that feature is released. 2207 */ 2208 notifier_clk_name = clk_hw_get_name(&meson8b_cpu_scale_out_sel.hw); 2209 notifier_clk = __clk_lookup(notifier_clk_name); 2210 ret = clk_notifier_register(notifier_clk, &meson8b_cpu_nb_data.nb); 2211 if (ret) { 2212 pr_err("%s: failed to register the CPU clock notifier\n", 2213 __func__); 2214 return; 2215 } 2216 2217 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, 2218 &meson8b_hw_onecell_data); 2219 if (ret) 2220 pr_err("%s: failed to register clock provider\n", __func__); 2221 } 2222 2223 CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", 2224 meson8b_clkc_init); 2225 CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", 2226 meson8b_clkc_init); 2227 CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", 2228 meson8b_clkc_init); 2229