1 /* 2 * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * ZynqMP system level PM-API functions for clock control. 9 */ 10 11 #include <stdbool.h> 12 #include <string.h> 13 14 #include <arch_helpers.h> 15 #include <lib/mmio.h> 16 #include <plat/common/platform.h> 17 18 #include "pm_api_clock.h" 19 #include "pm_api_sys.h" 20 #include "pm_client.h" 21 #include "pm_common.h" 22 #include "pm_ipi.h" 23 24 #define CLK_NODE_MAX U(6) 25 26 #define CLK_PARENTS_ID_LEN U(16) 27 #define CLK_TOPOLOGY_NODE_OFFSET U(16) 28 #define CLK_TOPOLOGY_PAYLOAD_LEN U(12) 29 #define CLK_PARENTS_PAYLOAD_LEN U(12) 30 #define CLK_TYPE_SHIFT U(2) 31 #define CLK_CLKFLAGS_SHIFT U(8) 32 #define CLK_TYPEFLAGS_SHIFT U(24) 33 #define CLK_TYPEFLAGS2_SHIFT U(4) 34 #define CLK_TYPEFLAGS_BITS_MASK U(0xFF) 35 #define CLK_TYPEFLAGS2_BITS_MASK U(0x0F00) 36 #define CLK_TYPEFLAGS_BITS U(8) 37 38 #define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN) 39 40 #define NA_MULT U(0) 41 #define NA_DIV U(0) 42 #define NA_SHIFT U(0) 43 #define NA_WIDTH U(0) 44 #define NA_CLK_FLAGS U(0) 45 #define NA_TYPE_FLAGS U(0) 46 47 /* PLL nodes related definitions */ 48 #define PLL_PRESRC_MUX_SHIFT U(20) 49 #define PLL_PRESRC_MUX_WIDTH U(3) 50 #define PLL_POSTSRC_MUX_SHIFT U(24) 51 #define PLL_POSTSRC_MUX_WIDTH U(3) 52 #define PLL_DIV2_MUX_SHIFT U(16) 53 #define PLL_DIV2_MUX_WIDTH U(1) 54 #define PLL_BYPASS_MUX_SHIFT U(3) 55 #define PLL_BYPASS_MUX_WIDTH U(1) 56 57 /* Peripheral nodes related definitions */ 58 /* Peripheral Clocks */ 59 #define PERIPH_MUX_SHIFT U(0) 60 #define PERIPH_MUX_WIDTH U(3) 61 #define PERIPH_DIV1_SHIFT U(8) 62 #define PERIPH_DIV1_WIDTH U(6) 63 #define PERIPH_DIV2_SHIFT U(16) 64 #define PERIPH_DIV2_WIDTH U(6) 65 #define PERIPH_GATE_SHIFT U(24) 66 #define PERIPH_GATE_WIDTH U(1) 67 68 #define USB_GATE_SHIFT U(25) 69 70 /* External clock related definitions */ 71 72 #define EXT_CLK_MIO_DATA(mio) \ 73 [EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = { \ 74 .name = "mio_clk_"#mio, \ 75 } 76 77 #define EXT_CLK_INDEX(n) (n - CLK_MAX_OUTPUT_CLK) 78 79 /* Clock control related definitions */ 80 #define BIT_MASK(x, y) (((1U << (y)) - 1) << (x)) 81 82 #define ISPLL(id) (id == CLK_APLL_INT || \ 83 id == CLK_DPLL_INT || \ 84 id == CLK_VPLL_INT || \ 85 id == CLK_IOPLL_INT || \ 86 id == CLK_RPLL_INT) 87 88 89 #define PLLCTRL_BP_MASK BIT(3) 90 #define PLLCTRL_RESET_MASK U(1) 91 #define PLL_FRAC_OFFSET U(8) 92 #define PLL_FRAC_MODE U(1) 93 #define PLL_INT_MODE U(0) 94 #define PLL_FRAC_MODE_MASK U(0x80000000) 95 #define PLL_FRAC_MODE_SHIFT U(31) 96 #define PLL_FRAC_DATA_MASK U(0xFFFF) 97 #define PLL_FRAC_DATA_SHIFT U(0) 98 #define PLL_FBDIV_MASK U(0x7F00) 99 #define PLL_FBDIV_WIDTH U(7) 100 #define PLL_FBDIV_SHIFT U(8) 101 102 #define CLK_PLL_RESET_ASSERT U(1) 103 #define CLK_PLL_RESET_RELEASE U(2) 104 #define CLK_PLL_RESET_PULSE (CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE) 105 106 /* Common topology definitions */ 107 #define GENERIC_MUX \ 108 { \ 109 .type = TYPE_MUX, \ 110 .offset = PERIPH_MUX_SHIFT, \ 111 .width = PERIPH_MUX_WIDTH, \ 112 .clkflags = CLK_SET_RATE_NO_REPARENT | \ 113 CLK_IS_BASIC, \ 114 .typeflags = NA_TYPE_FLAGS, \ 115 .mult = NA_MULT, \ 116 .div = NA_DIV, \ 117 } 118 119 #define IGNORE_UNUSED_MUX \ 120 { \ 121 .type = TYPE_MUX, \ 122 .offset = PERIPH_MUX_SHIFT, \ 123 .width = PERIPH_MUX_WIDTH, \ 124 .clkflags = CLK_IGNORE_UNUSED | \ 125 CLK_SET_RATE_NO_REPARENT | \ 126 CLK_IS_BASIC, \ 127 .typeflags = NA_TYPE_FLAGS, \ 128 .mult = NA_MULT, \ 129 .div = NA_DIV, \ 130 } 131 132 #define GENERIC_DIV1 \ 133 { \ 134 .type = TYPE_DIV1, \ 135 .offset = PERIPH_DIV1_SHIFT, \ 136 .width = PERIPH_DIV1_WIDTH, \ 137 .clkflags = CLK_SET_RATE_NO_REPARENT | \ 138 CLK_IS_BASIC, \ 139 .typeflags = CLK_DIVIDER_ONE_BASED | \ 140 CLK_DIVIDER_ALLOW_ZERO, \ 141 .mult = NA_MULT, \ 142 .div = NA_DIV, \ 143 } 144 145 #define GENERIC_DIV2 \ 146 { \ 147 .type = TYPE_DIV2, \ 148 .offset = PERIPH_DIV2_SHIFT, \ 149 .width = PERIPH_DIV2_WIDTH, \ 150 .clkflags = CLK_SET_RATE_NO_REPARENT | \ 151 CLK_SET_RATE_PARENT | \ 152 CLK_IS_BASIC, \ 153 .typeflags = CLK_DIVIDER_ONE_BASED | \ 154 CLK_DIVIDER_ALLOW_ZERO, \ 155 .mult = NA_MULT, \ 156 .div = NA_DIV, \ 157 } 158 159 #define IGNORE_UNUSED_DIV(id) \ 160 { \ 161 .type = TYPE_DIV##id, \ 162 .offset = PERIPH_DIV##id##_SHIFT, \ 163 .width = PERIPH_DIV##id##_WIDTH, \ 164 .clkflags = CLK_IGNORE_UNUSED | \ 165 CLK_SET_RATE_NO_REPARENT | \ 166 CLK_IS_BASIC, \ 167 .typeflags = CLK_DIVIDER_ONE_BASED | \ 168 CLK_DIVIDER_ALLOW_ZERO, \ 169 .mult = NA_MULT, \ 170 .div = NA_DIV, \ 171 } 172 173 #define GENERIC_GATE \ 174 { \ 175 .type = TYPE_GATE, \ 176 .offset = PERIPH_GATE_SHIFT, \ 177 .width = PERIPH_GATE_WIDTH, \ 178 .clkflags = CLK_SET_RATE_PARENT | \ 179 CLK_SET_RATE_GATE | \ 180 CLK_IS_BASIC, \ 181 .typeflags = NA_TYPE_FLAGS, \ 182 .mult = NA_MULT, \ 183 .div = NA_DIV, \ 184 } 185 186 #define IGNORE_UNUSED_GATE \ 187 { \ 188 .type = TYPE_GATE, \ 189 .offset = PERIPH_GATE_SHIFT, \ 190 .width = PERIPH_GATE_WIDTH, \ 191 .clkflags = CLK_SET_RATE_PARENT | \ 192 CLK_IGNORE_UNUSED | \ 193 CLK_IS_BASIC, \ 194 .typeflags = NA_TYPE_FLAGS, \ 195 .mult = NA_MULT, \ 196 .div = NA_DIV, \ 197 } 198 199 /** 200 * struct pm_clock_node - Clock topology node information 201 * @type: Topology type (mux/div1/div2/gate/pll/fixed factor) 202 * @offset: Offset in control register 203 * @width: Width of the specific type in control register 204 * @clkflags: Clk specific flags 205 * @typeflags: Type specific flags 206 * @mult: Multiplier for fixed factor 207 * @div: Divisor for fixed factor 208 */ 209 struct pm_clock_node { 210 uint16_t clkflags; 211 uint16_t typeflags; 212 uint8_t type; 213 uint8_t offset; 214 uint8_t width; 215 uint8_t mult:4; 216 uint8_t div:4; 217 }; 218 219 /** 220 * struct pm_clock - Clock structure 221 * @name: Clock name 222 * @control_reg: Control register address 223 * @status_reg: Status register address 224 * @parents: Parents for first clock node. Lower byte indicates parent 225 * clock id and upper byte indicate flags for that id. 226 * pm_clock_node: Clock nodes 227 */ 228 struct pm_clock { 229 char name[CLK_NAME_LEN]; 230 uint8_t num_nodes; 231 unsigned int control_reg; 232 unsigned int status_reg; 233 int32_t (*parents)[]; 234 struct pm_clock_node(*nodes)[]; 235 }; 236 237 /** 238 * struct pm_clock - Clock structure 239 * @name: Clock name 240 */ 241 struct pm_ext_clock { 242 char name[CLK_NAME_LEN]; 243 }; 244 245 /* PLL Clocks */ 246 static struct pm_clock_node generic_pll_nodes[] = { 247 { 248 .type = TYPE_PLL, 249 .offset = NA_SHIFT, 250 .width = NA_WIDTH, 251 .clkflags = CLK_SET_RATE_NO_REPARENT, 252 .typeflags = NA_TYPE_FLAGS, 253 .mult = NA_MULT, 254 .div = NA_DIV, 255 }, 256 }; 257 258 static struct pm_clock_node ignore_unused_pll_nodes[] = { 259 { 260 .type = TYPE_PLL, 261 .offset = NA_SHIFT, 262 .width = NA_WIDTH, 263 .clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT, 264 .typeflags = NA_TYPE_FLAGS, 265 .mult = NA_MULT, 266 .div = NA_DIV, 267 }, 268 }; 269 270 static struct pm_clock_node generic_pll_pre_src_nodes[] = { 271 { 272 .type = TYPE_MUX, 273 .offset = PLL_PRESRC_MUX_SHIFT, 274 .width = PLL_PRESRC_MUX_WIDTH, 275 .clkflags = CLK_IS_BASIC, 276 .typeflags = NA_TYPE_FLAGS, 277 .mult = NA_MULT, 278 .div = NA_DIV, 279 }, 280 }; 281 282 static struct pm_clock_node generic_pll_half_nodes[] = { 283 { 284 .type = TYPE_FIXEDFACTOR, 285 .offset = NA_SHIFT, 286 .width = NA_WIDTH, 287 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, 288 .typeflags = NA_TYPE_FLAGS, 289 .mult = 1, 290 .div = 2, 291 }, 292 }; 293 294 static struct pm_clock_node generic_pll_int_nodes[] = { 295 { 296 .type = TYPE_MUX, 297 .offset = PLL_DIV2_MUX_SHIFT, 298 .width = PLL_DIV2_MUX_WIDTH, 299 .clkflags = CLK_SET_RATE_NO_REPARENT | 300 CLK_SET_RATE_PARENT | 301 CLK_IS_BASIC, 302 .typeflags = NA_TYPE_FLAGS, 303 .mult = NA_MULT, 304 .div = NA_DIV, 305 }, 306 }; 307 308 static struct pm_clock_node generic_pll_post_src_nodes[] = { 309 { 310 .type = TYPE_MUX, 311 .offset = PLL_POSTSRC_MUX_SHIFT, 312 .width = PLL_POSTSRC_MUX_WIDTH, 313 .clkflags = CLK_IS_BASIC, 314 .typeflags = NA_TYPE_FLAGS, 315 .mult = NA_MULT, 316 .div = NA_DIV, 317 }, 318 }; 319 320 static struct pm_clock_node generic_pll_system_nodes[] = { 321 { 322 .type = TYPE_MUX, 323 .offset = PLL_BYPASS_MUX_SHIFT, 324 .width = PLL_BYPASS_MUX_WIDTH, 325 .clkflags = CLK_SET_RATE_NO_REPARENT | 326 CLK_SET_RATE_PARENT | 327 CLK_IS_BASIC, 328 .typeflags = NA_TYPE_FLAGS, 329 .mult = NA_MULT, 330 .div = NA_DIV, 331 }, 332 }; 333 334 static struct pm_clock_node acpu_nodes[] = { 335 { 336 .type = TYPE_MUX, 337 .offset = PERIPH_MUX_SHIFT, 338 .width = PERIPH_MUX_WIDTH, 339 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, 340 .typeflags = NA_TYPE_FLAGS, 341 .mult = NA_MULT, 342 .div = NA_DIV, 343 }, 344 { 345 .type = TYPE_DIV1, 346 .offset = PERIPH_DIV1_SHIFT, 347 .width = PERIPH_DIV1_WIDTH, 348 .clkflags = CLK_IS_BASIC, 349 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 350 .mult = NA_MULT, 351 .div = NA_DIV, 352 }, 353 }; 354 355 static struct pm_clock_node generic_mux_div_nodes[] = { 356 GENERIC_MUX, 357 GENERIC_DIV1, 358 }; 359 360 static struct pm_clock_node generic_mux_div_gate_nodes[] = { 361 GENERIC_MUX, 362 GENERIC_DIV1, 363 GENERIC_GATE, 364 }; 365 366 static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = { 367 GENERIC_MUX, 368 GENERIC_DIV1, 369 IGNORE_UNUSED_GATE, 370 }; 371 372 static struct pm_clock_node generic_mux_div_div_gate_nodes[] = { 373 GENERIC_MUX, 374 GENERIC_DIV1, 375 GENERIC_DIV2, 376 GENERIC_GATE, 377 }; 378 379 static struct pm_clock_node dp_audio_video_ref_nodes[] = { 380 { 381 .type = TYPE_MUX, 382 .offset = PERIPH_MUX_SHIFT, 383 .width = PERIPH_MUX_WIDTH, 384 .clkflags = CLK_SET_RATE_NO_REPARENT | 385 CLK_SET_RATE_PARENT | CLK_IS_BASIC, 386 .typeflags = CLK_FRAC, 387 .mult = NA_MULT, 388 .div = NA_DIV, 389 }, 390 { 391 .type = TYPE_DIV1, 392 .offset = PERIPH_DIV1_SHIFT, 393 .width = PERIPH_DIV1_WIDTH, 394 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT | 395 CLK_IS_BASIC, 396 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO | 397 CLK_FRAC, 398 .mult = NA_MULT, 399 .div = NA_DIV, 400 }, 401 { 402 .type = TYPE_DIV2, 403 .offset = PERIPH_DIV2_SHIFT, 404 .width = PERIPH_DIV2_WIDTH, 405 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT | 406 CLK_IS_BASIC, 407 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO | 408 CLK_FRAC, 409 .mult = NA_MULT, 410 .div = NA_DIV, 411 }, 412 { 413 .type = TYPE_GATE, 414 .offset = PERIPH_GATE_SHIFT, 415 .width = PERIPH_GATE_WIDTH, 416 .clkflags = CLK_SET_RATE_PARENT | 417 CLK_SET_RATE_GATE | 418 CLK_IS_BASIC, 419 .typeflags = NA_TYPE_FLAGS, 420 .mult = NA_MULT, 421 .div = NA_DIV, 422 }, 423 }; 424 425 static struct pm_clock_node usb_nodes[] = { 426 GENERIC_MUX, 427 GENERIC_DIV1, 428 GENERIC_DIV2, 429 { 430 .type = TYPE_GATE, 431 .offset = USB_GATE_SHIFT, 432 .width = PERIPH_GATE_WIDTH, 433 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC | 434 CLK_SET_RATE_GATE, 435 .typeflags = NA_TYPE_FLAGS, 436 .mult = NA_MULT, 437 .div = NA_DIV, 438 }, 439 }; 440 441 static struct pm_clock_node generic_domain_crossing_nodes[] = { 442 { 443 .type = TYPE_DIV1, 444 .offset = 8, 445 .width = 6, 446 .clkflags = CLK_IS_BASIC, 447 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 448 .mult = NA_MULT, 449 .div = NA_DIV, 450 }, 451 }; 452 453 static struct pm_clock_node rpll_to_fpd_nodes[] = { 454 { 455 .type = TYPE_DIV1, 456 .offset = 8, 457 .width = 6, 458 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, 459 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 460 .mult = NA_MULT, 461 .div = NA_DIV, 462 }, 463 }; 464 465 static struct pm_clock_node acpu_half_nodes[] = { 466 { 467 .type = TYPE_FIXEDFACTOR, 468 .offset = 0, 469 .width = 1, 470 .clkflags = 0, 471 .typeflags = 0, 472 .mult = 1, 473 .div = 2, 474 }, 475 { 476 .type = TYPE_GATE, 477 .offset = 25, 478 .width = PERIPH_GATE_WIDTH, 479 .clkflags = CLK_IGNORE_UNUSED | 480 CLK_SET_RATE_PARENT | 481 CLK_IS_BASIC, 482 .typeflags = NA_TYPE_FLAGS, 483 .mult = NA_MULT, 484 .div = NA_DIV, 485 }, 486 }; 487 488 static struct pm_clock_node acpu_full_nodes[] = { 489 { 490 .type = TYPE_GATE, 491 .offset = 24, 492 .width = PERIPH_GATE_WIDTH, 493 .clkflags = CLK_IGNORE_UNUSED | 494 CLK_SET_RATE_PARENT | 495 CLK_IS_BASIC, 496 .typeflags = NA_TYPE_FLAGS, 497 .mult = NA_MULT, 498 .div = NA_DIV, 499 }, 500 }; 501 502 static struct pm_clock_node wdt_nodes[] = { 503 { 504 .type = TYPE_MUX, 505 .offset = 0, 506 .width = 1, 507 .clkflags = CLK_SET_RATE_PARENT | 508 CLK_SET_RATE_NO_REPARENT | 509 CLK_IS_BASIC, 510 .typeflags = NA_TYPE_FLAGS, 511 .mult = NA_MULT, 512 .div = NA_DIV, 513 }, 514 }; 515 516 static struct pm_clock_node ddr_nodes[] = { 517 GENERIC_MUX, 518 { 519 .type = TYPE_DIV1, 520 .offset = 8, 521 .width = 6, 522 .clkflags = CLK_IS_BASIC | CLK_IS_CRITICAL, 523 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 524 .mult = NA_MULT, 525 .div = NA_DIV, 526 }, 527 }; 528 529 static struct pm_clock_node pl_nodes[] = { 530 GENERIC_MUX, 531 { 532 .type = TYPE_DIV1, 533 .offset = PERIPH_DIV1_SHIFT, 534 .width = PERIPH_DIV1_WIDTH, 535 .clkflags = CLK_IS_BASIC, 536 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 537 .mult = NA_MULT, 538 .div = NA_DIV, 539 }, 540 { 541 .type = TYPE_DIV2, 542 .offset = PERIPH_DIV2_SHIFT, 543 .width = PERIPH_DIV2_WIDTH, 544 .clkflags = CLK_IS_BASIC | CLK_SET_RATE_PARENT, 545 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 546 .mult = NA_MULT, 547 .div = NA_DIV, 548 }, 549 { 550 .type = TYPE_GATE, 551 .offset = PERIPH_GATE_SHIFT, 552 .width = PERIPH_GATE_WIDTH, 553 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, 554 .typeflags = NA_TYPE_FLAGS, 555 .mult = NA_MULT, 556 .div = NA_DIV, 557 }, 558 }; 559 560 static struct pm_clock_node gpu_pp0_nodes[] = { 561 { 562 .type = TYPE_GATE, 563 .offset = 25, 564 .width = PERIPH_GATE_WIDTH, 565 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, 566 .typeflags = NA_TYPE_FLAGS, 567 .mult = NA_MULT, 568 .div = NA_DIV, 569 }, 570 }; 571 572 static struct pm_clock_node gpu_pp1_nodes[] = { 573 { 574 .type = TYPE_GATE, 575 .offset = 26, 576 .width = PERIPH_GATE_WIDTH, 577 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, 578 .typeflags = NA_TYPE_FLAGS, 579 .mult = NA_MULT, 580 .div = NA_DIV, 581 }, 582 }; 583 584 static struct pm_clock_node gem_ref_ungated_nodes[] = { 585 GENERIC_MUX, 586 { 587 .type = TYPE_DIV1, 588 .offset = 8, 589 .width = 6, 590 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, 591 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 592 .mult = NA_MULT, 593 .div = NA_DIV, 594 }, 595 { 596 .type = TYPE_DIV2, 597 .offset = 16, 598 .width = 6, 599 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC | 600 CLK_SET_RATE_PARENT, 601 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 602 .mult = NA_MULT, 603 .div = NA_DIV, 604 }, 605 }; 606 607 static struct pm_clock_node gem0_ref_nodes[] = { 608 { 609 .type = TYPE_MUX, 610 .offset = 1, 611 .width = 1, 612 .clkflags = CLK_SET_RATE_PARENT | 613 CLK_SET_RATE_NO_REPARENT | 614 CLK_IS_BASIC, 615 .typeflags = NA_TYPE_FLAGS, 616 .mult = NA_MULT, 617 .div = NA_DIV, 618 }, 619 }; 620 621 static struct pm_clock_node gem1_ref_nodes[] = { 622 { 623 .type = TYPE_MUX, 624 .offset = 6, 625 .width = 1, 626 .clkflags = CLK_SET_RATE_PARENT | 627 CLK_SET_RATE_NO_REPARENT | 628 CLK_IS_BASIC, 629 .typeflags = NA_TYPE_FLAGS, 630 .mult = NA_MULT, 631 .div = NA_DIV, 632 }, 633 }; 634 635 static struct pm_clock_node gem2_ref_nodes[] = { 636 { 637 .type = TYPE_MUX, 638 .offset = 11, 639 .width = 1, 640 .clkflags = CLK_SET_RATE_PARENT | 641 CLK_SET_RATE_NO_REPARENT | 642 CLK_IS_BASIC, 643 .typeflags = NA_TYPE_FLAGS, 644 .mult = NA_MULT, 645 .div = NA_DIV, 646 }, 647 }; 648 649 static struct pm_clock_node gem3_ref_nodes[] = { 650 { 651 .type = TYPE_MUX, 652 .offset = 16, 653 .width = 1, 654 .clkflags = CLK_SET_RATE_PARENT | 655 CLK_SET_RATE_NO_REPARENT | 656 CLK_IS_BASIC, 657 .typeflags = NA_TYPE_FLAGS, 658 .mult = NA_MULT, 659 .div = NA_DIV, 660 }, 661 }; 662 663 static struct pm_clock_node gem_tx_nodes[] = { 664 { 665 .type = TYPE_GATE, 666 .offset = 25, 667 .width = PERIPH_GATE_WIDTH, 668 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, 669 .typeflags = NA_TYPE_FLAGS, 670 .mult = NA_MULT, 671 .div = NA_DIV, 672 }, 673 }; 674 675 static struct pm_clock_node gem_rx_nodes[] = { 676 { 677 .type = TYPE_GATE, 678 .offset = 26, 679 .width = PERIPH_GATE_WIDTH, 680 .clkflags = CLK_IS_BASIC, 681 .typeflags = NA_TYPE_FLAGS, 682 .mult = NA_MULT, 683 .div = NA_DIV, 684 }, 685 }; 686 687 static struct pm_clock_node gem_tsu_nodes[] = { 688 { 689 .type = TYPE_MUX, 690 .offset = 20, 691 .width = 2, 692 .clkflags = CLK_SET_RATE_PARENT | 693 CLK_SET_RATE_NO_REPARENT | 694 CLK_IS_BASIC, 695 .typeflags = NA_TYPE_FLAGS, 696 .mult = NA_MULT, 697 .div = NA_DIV, 698 }, 699 }; 700 701 static struct pm_clock_node can0_mio_nodes[] = { 702 { 703 .type = TYPE_MUX, 704 .offset = 0, 705 .width = 7, 706 .clkflags = CLK_SET_RATE_PARENT | 707 CLK_SET_RATE_NO_REPARENT | 708 CLK_IS_BASIC, 709 .typeflags = NA_TYPE_FLAGS, 710 .mult = NA_MULT, 711 .div = NA_DIV, 712 }, 713 }; 714 715 static struct pm_clock_node can1_mio_nodes[] = { 716 { 717 .type = TYPE_MUX, 718 .offset = 15, 719 .width = 1, 720 .clkflags = CLK_SET_RATE_PARENT | 721 CLK_SET_RATE_NO_REPARENT | 722 CLK_IS_BASIC, 723 .typeflags = NA_TYPE_FLAGS, 724 .mult = NA_MULT, 725 .div = NA_DIV, 726 }, 727 }; 728 729 static struct pm_clock_node can0_nodes[] = { 730 { 731 .type = TYPE_MUX, 732 .offset = 7, 733 .width = 1, 734 .clkflags = CLK_SET_RATE_PARENT | 735 CLK_SET_RATE_NO_REPARENT | 736 CLK_IS_BASIC, 737 .typeflags = NA_TYPE_FLAGS, 738 .mult = NA_MULT, 739 .div = NA_DIV, 740 }, 741 }; 742 743 static struct pm_clock_node can1_nodes[] = { 744 { 745 .type = TYPE_MUX, 746 .offset = 22, 747 .width = 1, 748 .clkflags = CLK_SET_RATE_PARENT | 749 CLK_SET_RATE_NO_REPARENT | 750 CLK_IS_BASIC, 751 .typeflags = NA_TYPE_FLAGS, 752 .mult = NA_MULT, 753 .div = NA_DIV, 754 }, 755 }; 756 757 static struct pm_clock_node cpu_r5_core_nodes[] = { 758 { 759 .type = TYPE_GATE, 760 .offset = 25, 761 .width = PERIPH_GATE_WIDTH, 762 .clkflags = CLK_IGNORE_UNUSED | 763 CLK_IS_BASIC, 764 .typeflags = NA_TYPE_FLAGS, 765 .mult = NA_MULT, 766 .div = NA_DIV, 767 }, 768 }; 769 770 static struct pm_clock_node dll_ref_nodes[] = { 771 { 772 .type = TYPE_MUX, 773 .offset = 0, 774 .width = 3, 775 .clkflags = CLK_SET_RATE_PARENT | 776 CLK_SET_RATE_NO_REPARENT | 777 CLK_IS_BASIC, 778 .typeflags = NA_TYPE_FLAGS, 779 .mult = NA_MULT, 780 .div = NA_DIV, 781 }, 782 }; 783 784 static struct pm_clock_node timestamp_ref_nodes[] = { 785 GENERIC_MUX, 786 { 787 .type = TYPE_DIV1, 788 .offset = 8, 789 .width = 6, 790 .clkflags = CLK_IS_BASIC, 791 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 792 .mult = NA_MULT, 793 .div = NA_DIV, 794 }, 795 IGNORE_UNUSED_GATE, 796 }; 797 798 static int32_t can_mio_parents[] = { 799 EXT_CLK_MIO0, EXT_CLK_MIO1, EXT_CLK_MIO2, EXT_CLK_MIO3, 800 EXT_CLK_MIO4, EXT_CLK_MIO5, EXT_CLK_MIO6, EXT_CLK_MIO7, 801 EXT_CLK_MIO8, EXT_CLK_MIO9, EXT_CLK_MIO10, EXT_CLK_MIO11, 802 EXT_CLK_MIO12, EXT_CLK_MIO13, EXT_CLK_MIO14, EXT_CLK_MIO15, 803 EXT_CLK_MIO16, EXT_CLK_MIO17, EXT_CLK_MIO18, EXT_CLK_MIO19, 804 EXT_CLK_MIO20, EXT_CLK_MIO21, EXT_CLK_MIO22, EXT_CLK_MIO23, 805 EXT_CLK_MIO24, EXT_CLK_MIO25, EXT_CLK_MIO26, EXT_CLK_MIO27, 806 EXT_CLK_MIO28, EXT_CLK_MIO29, EXT_CLK_MIO30, EXT_CLK_MIO31, 807 EXT_CLK_MIO32, EXT_CLK_MIO33, EXT_CLK_MIO34, EXT_CLK_MIO35, 808 EXT_CLK_MIO36, EXT_CLK_MIO37, EXT_CLK_MIO38, EXT_CLK_MIO39, 809 EXT_CLK_MIO40, EXT_CLK_MIO41, EXT_CLK_MIO42, EXT_CLK_MIO43, 810 EXT_CLK_MIO44, EXT_CLK_MIO45, EXT_CLK_MIO46, EXT_CLK_MIO47, 811 EXT_CLK_MIO48, EXT_CLK_MIO49, EXT_CLK_MIO50, EXT_CLK_MIO51, 812 EXT_CLK_MIO52, EXT_CLK_MIO53, EXT_CLK_MIO54, EXT_CLK_MIO55, 813 EXT_CLK_MIO56, EXT_CLK_MIO57, EXT_CLK_MIO58, EXT_CLK_MIO59, 814 EXT_CLK_MIO60, EXT_CLK_MIO61, EXT_CLK_MIO62, EXT_CLK_MIO63, 815 EXT_CLK_MIO64, EXT_CLK_MIO65, EXT_CLK_MIO66, EXT_CLK_MIO67, 816 EXT_CLK_MIO68, EXT_CLK_MIO69, EXT_CLK_MIO70, EXT_CLK_MIO71, 817 EXT_CLK_MIO72, EXT_CLK_MIO73, EXT_CLK_MIO74, EXT_CLK_MIO75, 818 EXT_CLK_MIO76, EXT_CLK_MIO77, CLK_NA_PARENT 819 }; 820 821 /* Clock array containing clock informaton */ 822 static struct pm_clock clocks[] = { 823 [CLK_APLL_INT] = { 824 .name = "apll_int", 825 .control_reg = CRF_APB_APLL_CTRL, 826 .status_reg = CRF_APB_PLL_STATUS, 827 .parents = &((int32_t []) {CLK_APLL_PRE_SRC, CLK_NA_PARENT}), 828 .nodes = &ignore_unused_pll_nodes, 829 .num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes), 830 }, 831 [CLK_APLL_PRE_SRC] = { 832 .name = "apll_pre_src", 833 .control_reg = CRF_APB_APLL_CTRL, 834 .status_reg = CRF_APB_PLL_STATUS, 835 .parents = &((int32_t []) { 836 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 837 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 838 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 839 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 840 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 841 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 842 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 843 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 844 CLK_NA_PARENT 845 }), 846 .nodes = &generic_pll_pre_src_nodes, 847 .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes), 848 }, 849 [CLK_APLL_HALF] = { 850 .name = "apll_half", 851 .control_reg = CRF_APB_APLL_CTRL, 852 .status_reg = CRF_APB_PLL_STATUS, 853 .parents = &((int32_t []) {CLK_APLL_INT, CLK_NA_PARENT}), 854 .nodes = &generic_pll_half_nodes, 855 .num_nodes = ARRAY_SIZE(generic_pll_half_nodes), 856 }, 857 [CLK_APLL_INT_MUX] = { 858 .name = "apll_int_mux", 859 .control_reg = CRF_APB_APLL_CTRL, 860 .status_reg = CRF_APB_PLL_STATUS, 861 .parents = &((int32_t []) { 862 CLK_APLL_INT, 863 CLK_APLL_HALF, 864 CLK_NA_PARENT 865 }), 866 .nodes = &generic_pll_int_nodes, 867 .num_nodes = ARRAY_SIZE(generic_pll_int_nodes), 868 }, 869 [CLK_APLL_POST_SRC] = { 870 .name = "apll_post_src", 871 .control_reg = CRF_APB_APLL_CTRL, 872 .status_reg = CRF_APB_PLL_STATUS, 873 .parents = &((int32_t []) { 874 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 875 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 876 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 877 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 878 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 879 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 880 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 881 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 882 CLK_NA_PARENT 883 }), 884 .nodes = &generic_pll_post_src_nodes, 885 .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes), 886 }, 887 [CLK_APLL] = { 888 .name = "apll", 889 .control_reg = CRF_APB_APLL_CTRL, 890 .status_reg = CRF_APB_PLL_STATUS, 891 .parents = &((int32_t []) { 892 CLK_APLL_INT_MUX, 893 CLK_APLL_POST_SRC, 894 CLK_NA_PARENT 895 }), 896 .nodes = &generic_pll_system_nodes, 897 .num_nodes = ARRAY_SIZE(generic_pll_system_nodes), 898 }, 899 [CLK_DPLL_INT] = { 900 .name = "dpll_int", 901 .control_reg = CRF_APB_DPLL_CTRL, 902 .status_reg = CRF_APB_PLL_STATUS, 903 .parents = &((int32_t []) {CLK_DPLL_PRE_SRC, CLK_NA_PARENT}), 904 .nodes = &generic_pll_nodes, 905 .num_nodes = ARRAY_SIZE(generic_pll_nodes), 906 }, 907 [CLK_DPLL_PRE_SRC] = { 908 .name = "dpll_pre_src", 909 .control_reg = CRF_APB_DPLL_CTRL, 910 .status_reg = CRF_APB_PLL_STATUS, 911 .parents = &((int32_t []) { 912 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 913 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 914 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 915 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 916 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 917 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 918 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 919 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 920 CLK_NA_PARENT 921 }), 922 .nodes = &generic_pll_pre_src_nodes, 923 .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes), 924 }, 925 [CLK_DPLL_HALF] = { 926 .name = "dpll_half", 927 .control_reg = CRF_APB_DPLL_CTRL, 928 .status_reg = CRF_APB_PLL_STATUS, 929 .parents = &((int32_t []) {CLK_DPLL_INT, CLK_NA_PARENT}), 930 .nodes = &generic_pll_half_nodes, 931 .num_nodes = ARRAY_SIZE(generic_pll_half_nodes), 932 }, 933 [CLK_DPLL_INT_MUX] = { 934 .name = "dpll_int_mux", 935 .control_reg = CRF_APB_DPLL_CTRL, 936 .status_reg = CRF_APB_PLL_STATUS, 937 .parents = &((int32_t []) { 938 CLK_DPLL_INT, 939 CLK_DPLL_HALF, 940 CLK_NA_PARENT 941 }), 942 .nodes = &generic_pll_int_nodes, 943 .num_nodes = ARRAY_SIZE(generic_pll_int_nodes), 944 }, 945 [CLK_DPLL_POST_SRC] = { 946 .name = "dpll_post_src", 947 .control_reg = CRF_APB_DPLL_CTRL, 948 .status_reg = CRF_APB_PLL_STATUS, 949 .parents = &((int32_t []) { 950 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 951 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 952 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 953 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 954 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 955 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 956 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 957 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 958 CLK_NA_PARENT 959 }), 960 .nodes = &generic_pll_post_src_nodes, 961 .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes), 962 }, 963 [CLK_DPLL] = { 964 .name = "dpll", 965 .control_reg = CRF_APB_DPLL_CTRL, 966 .status_reg = CRF_APB_PLL_STATUS, 967 .parents = &((int32_t []) { 968 CLK_DPLL_INT_MUX, 969 CLK_DPLL_POST_SRC, 970 CLK_NA_PARENT 971 }), 972 .nodes = &generic_pll_system_nodes, 973 .num_nodes = ARRAY_SIZE(generic_pll_system_nodes), 974 }, 975 [CLK_VPLL_INT] = { 976 .name = "vpll_int", 977 .control_reg = CRF_APB_VPLL_CTRL, 978 .status_reg = CRF_APB_PLL_STATUS, 979 .parents = &((int32_t []) {CLK_VPLL_PRE_SRC, CLK_NA_PARENT}), 980 .nodes = &ignore_unused_pll_nodes, 981 .num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes), 982 }, 983 [CLK_VPLL_PRE_SRC] = { 984 .name = "vpll_pre_src", 985 .control_reg = CRF_APB_VPLL_CTRL, 986 .status_reg = CRF_APB_PLL_STATUS, 987 .parents = &((int32_t []) { 988 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 989 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 990 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 991 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 992 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 993 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 994 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 995 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 996 CLK_NA_PARENT 997 }), 998 .nodes = &generic_pll_pre_src_nodes, 999 .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes), 1000 }, 1001 [CLK_VPLL_HALF] = { 1002 .name = "vpll_half", 1003 .control_reg = CRF_APB_VPLL_CTRL, 1004 .status_reg = CRF_APB_PLL_STATUS, 1005 .parents = &((int32_t []) {CLK_VPLL_INT, CLK_NA_PARENT}), 1006 .nodes = &generic_pll_half_nodes, 1007 .num_nodes = ARRAY_SIZE(generic_pll_half_nodes), 1008 }, 1009 [CLK_VPLL_INT_MUX] = { 1010 .name = "vpll_int_mux", 1011 .control_reg = CRF_APB_VPLL_CTRL, 1012 .status_reg = CRF_APB_PLL_STATUS, 1013 .parents = &((int32_t []) { 1014 CLK_VPLL_INT, 1015 CLK_VPLL_HALF, 1016 CLK_NA_PARENT 1017 }), 1018 .nodes = &generic_pll_int_nodes, 1019 .num_nodes = ARRAY_SIZE(generic_pll_int_nodes), 1020 }, 1021 [CLK_VPLL_POST_SRC] = { 1022 .name = "vpll_post_src", 1023 .control_reg = CRF_APB_VPLL_CTRL, 1024 .status_reg = CRF_APB_PLL_STATUS, 1025 .parents = &((int32_t []) { 1026 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1027 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1028 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1029 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1030 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 1031 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 1032 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 1033 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 1034 CLK_NA_PARENT 1035 }), 1036 .nodes = &generic_pll_post_src_nodes, 1037 .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes), 1038 }, 1039 [CLK_VPLL] = { 1040 .name = "vpll", 1041 .control_reg = CRF_APB_VPLL_CTRL, 1042 .status_reg = CRF_APB_PLL_STATUS, 1043 .parents = &((int32_t []) { 1044 CLK_VPLL_INT_MUX, 1045 CLK_VPLL_POST_SRC, 1046 CLK_NA_PARENT 1047 }), 1048 .nodes = &generic_pll_system_nodes, 1049 .num_nodes = ARRAY_SIZE(generic_pll_system_nodes), 1050 }, 1051 [CLK_IOPLL_INT] = { 1052 .name = "iopll_int", 1053 .control_reg = CRL_APB_IOPLL_CTRL, 1054 .status_reg = CRF_APB_PLL_STATUS, 1055 .parents = &((int32_t []) {CLK_IOPLL_PRE_SRC, CLK_NA_PARENT}), 1056 .nodes = &generic_pll_nodes, 1057 .num_nodes = ARRAY_SIZE(generic_pll_nodes), 1058 }, 1059 [CLK_IOPLL_PRE_SRC] = { 1060 .name = "iopll_pre_src", 1061 .control_reg = CRL_APB_IOPLL_CTRL, 1062 .status_reg = CRF_APB_PLL_STATUS, 1063 .parents = &((int32_t []) { 1064 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1065 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1066 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1067 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1068 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 1069 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 1070 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 1071 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 1072 CLK_NA_PARENT 1073 }), 1074 .nodes = &generic_pll_pre_src_nodes, 1075 .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes), 1076 }, 1077 [CLK_IOPLL_HALF] = { 1078 .name = "iopll_half", 1079 .control_reg = CRL_APB_IOPLL_CTRL, 1080 .status_reg = CRF_APB_PLL_STATUS, 1081 .parents = &((int32_t []) {CLK_IOPLL_INT, CLK_NA_PARENT}), 1082 .nodes = &generic_pll_half_nodes, 1083 .num_nodes = ARRAY_SIZE(generic_pll_half_nodes), 1084 }, 1085 [CLK_IOPLL_INT_MUX] = { 1086 .name = "iopll_int_mux", 1087 .control_reg = CRL_APB_IOPLL_CTRL, 1088 .status_reg = CRF_APB_PLL_STATUS, 1089 .parents = &((int32_t []) { 1090 CLK_IOPLL_INT, 1091 CLK_IOPLL_HALF, 1092 CLK_NA_PARENT 1093 }), 1094 .nodes = &generic_pll_int_nodes, 1095 .num_nodes = ARRAY_SIZE(generic_pll_int_nodes), 1096 }, 1097 [CLK_IOPLL_POST_SRC] = { 1098 .name = "iopll_post_src", 1099 .control_reg = CRL_APB_IOPLL_CTRL, 1100 .status_reg = CRF_APB_PLL_STATUS, 1101 .parents = &((int32_t []) { 1102 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1103 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1104 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1105 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1106 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 1107 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 1108 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 1109 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 1110 CLK_NA_PARENT 1111 }), 1112 .nodes = &generic_pll_post_src_nodes, 1113 .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes), 1114 }, 1115 [CLK_IOPLL] = { 1116 .name = "iopll", 1117 .control_reg = CRL_APB_IOPLL_CTRL, 1118 .status_reg = CRF_APB_PLL_STATUS, 1119 .parents = &((int32_t []) { 1120 CLK_IOPLL_INT_MUX, 1121 CLK_IOPLL_POST_SRC, 1122 CLK_NA_PARENT 1123 }), 1124 .nodes = &generic_pll_system_nodes, 1125 .num_nodes = ARRAY_SIZE(generic_pll_system_nodes), 1126 }, 1127 [CLK_RPLL_INT] = { 1128 .name = "rpll_int", 1129 .control_reg = CRL_APB_RPLL_CTRL, 1130 .status_reg = CRF_APB_PLL_STATUS, 1131 .parents = &((int32_t []) {CLK_RPLL_PRE_SRC, CLK_NA_PARENT}), 1132 .nodes = &generic_pll_nodes, 1133 .num_nodes = ARRAY_SIZE(generic_pll_nodes), 1134 }, 1135 [CLK_RPLL_PRE_SRC] = { 1136 .name = "rpll_pre_src", 1137 .control_reg = CRL_APB_RPLL_CTRL, 1138 .status_reg = CRF_APB_PLL_STATUS, 1139 .parents = &((int32_t []) { 1140 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1141 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1142 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1143 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1144 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 1145 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 1146 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 1147 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 1148 CLK_NA_PARENT 1149 }), 1150 1151 .nodes = &generic_pll_pre_src_nodes, 1152 .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes), 1153 }, 1154 [CLK_RPLL_HALF] = { 1155 .name = "rpll_half", 1156 .control_reg = CRL_APB_RPLL_CTRL, 1157 .status_reg = CRF_APB_PLL_STATUS, 1158 .parents = &((int32_t []) {CLK_RPLL_INT, CLK_NA_PARENT}), 1159 .nodes = &generic_pll_half_nodes, 1160 .num_nodes = ARRAY_SIZE(generic_pll_half_nodes), 1161 }, 1162 [CLK_RPLL_INT_MUX] = { 1163 .name = "rpll_int_mux", 1164 .control_reg = CRL_APB_RPLL_CTRL, 1165 .status_reg = CRF_APB_PLL_STATUS, 1166 .parents = &((int32_t []) { 1167 CLK_RPLL_INT, 1168 CLK_RPLL_HALF, 1169 CLK_NA_PARENT 1170 }), 1171 .nodes = &generic_pll_int_nodes, 1172 .num_nodes = ARRAY_SIZE(generic_pll_int_nodes), 1173 }, 1174 [CLK_RPLL_POST_SRC] = { 1175 .name = "rpll_post_src", 1176 .control_reg = CRL_APB_RPLL_CTRL, 1177 .status_reg = CRF_APB_PLL_STATUS, 1178 .parents = &((int32_t []) { 1179 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1180 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1181 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1182 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1183 EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT, 1184 EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT, 1185 EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT, 1186 EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT, 1187 CLK_NA_PARENT 1188 }), 1189 .nodes = &generic_pll_post_src_nodes, 1190 .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes), 1191 }, 1192 [CLK_RPLL] = { 1193 .name = "rpll", 1194 .control_reg = CRL_APB_RPLL_CTRL, 1195 .status_reg = CRL_APB_PLL_STATUS, 1196 .parents = &((int32_t []) { 1197 CLK_RPLL_INT_MUX, 1198 CLK_RPLL_POST_SRC, 1199 CLK_NA_PARENT 1200 }), 1201 .nodes = &generic_pll_system_nodes, 1202 .num_nodes = ARRAY_SIZE(generic_pll_system_nodes), 1203 }, 1204 /* Peripheral Clocks */ 1205 [CLK_ACPU] = { 1206 .name = "acpu", 1207 .control_reg = CRF_APB_ACPU_CTRL, 1208 .status_reg = 0, 1209 .parents = &((int32_t []) { 1210 CLK_APLL, 1211 CLK_DUMMY_PARENT, 1212 CLK_DPLL, 1213 CLK_VPLL, 1214 CLK_NA_PARENT 1215 }), 1216 .nodes = &acpu_nodes, 1217 .num_nodes = ARRAY_SIZE(acpu_nodes), 1218 }, 1219 [CLK_ACPU_FULL] = { 1220 .name = "acpu_full", 1221 .control_reg = CRF_APB_ACPU_CTRL, 1222 .status_reg = 0, 1223 .parents = &((int32_t []) { 1224 CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 1225 CLK_NA_PARENT 1226 }), 1227 .nodes = &acpu_full_nodes, 1228 .num_nodes = ARRAY_SIZE(acpu_full_nodes), 1229 }, 1230 [CLK_DBG_TRACE] = { 1231 .name = "dbg_trace", 1232 .control_reg = CRF_APB_DBG_TRACE_CTRL, 1233 .status_reg = 0, 1234 .parents = &((int32_t []) { 1235 CLK_IOPLL_TO_FPD, 1236 CLK_DUMMY_PARENT, 1237 CLK_DPLL, 1238 CLK_APLL, 1239 CLK_NA_PARENT 1240 }), 1241 .nodes = &generic_mux_div_gate_nodes, 1242 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1243 }, 1244 [CLK_DBG_FPD] = { 1245 .name = "dbg_fpd", 1246 .control_reg = CRF_APB_DBG_FPD_CTRL, 1247 .status_reg = 0, 1248 .parents = &((int32_t []) { 1249 CLK_IOPLL_TO_FPD, 1250 CLK_DUMMY_PARENT, 1251 CLK_DPLL, 1252 CLK_APLL, 1253 CLK_NA_PARENT 1254 }), 1255 .nodes = &generic_mux_div_gate_nodes, 1256 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1257 }, 1258 [CLK_DBG_TSTMP] = { 1259 .name = "dbg_tstmp", 1260 .control_reg = CRF_APB_DBG_TSTMP_CTRL, 1261 .status_reg = 0, 1262 .parents = &((int32_t []) { 1263 CLK_IOPLL_TO_FPD, 1264 CLK_DUMMY_PARENT, 1265 CLK_DPLL, 1266 CLK_APLL, 1267 CLK_NA_PARENT 1268 }), 1269 .nodes = &generic_mux_div_nodes, 1270 .num_nodes = ARRAY_SIZE(generic_mux_div_nodes), 1271 }, 1272 [CLK_DP_VIDEO_REF] = { 1273 .name = "dp_video_ref", 1274 .control_reg = CRF_APB_DP_VIDEO_REF_CTRL, 1275 .status_reg = 0, 1276 .parents = &((int32_t []) { 1277 CLK_VPLL, 1278 CLK_DUMMY_PARENT, 1279 CLK_DPLL, 1280 CLK_RPLL_TO_FPD, 1281 CLK_NA_PARENT 1282 }), 1283 .nodes = &dp_audio_video_ref_nodes, 1284 .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes), 1285 }, 1286 [CLK_DP_AUDIO_REF] = { 1287 .name = "dp_audio_ref", 1288 .control_reg = CRF_APB_DP_AUDIO_REF_CTRL, 1289 .status_reg = 0, 1290 .parents = &((int32_t []) { 1291 CLK_VPLL, 1292 CLK_DUMMY_PARENT, 1293 CLK_DPLL, 1294 CLK_RPLL_TO_FPD, 1295 CLK_NA_PARENT 1296 }), 1297 .nodes = &dp_audio_video_ref_nodes, 1298 .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes), 1299 }, 1300 [CLK_DP_STC_REF] = { 1301 .name = "dp_stc_ref", 1302 .control_reg = CRF_APB_DP_STC_REF_CTRL, 1303 .status_reg = 0, 1304 .parents = &((int32_t []) { 1305 CLK_VPLL, 1306 CLK_DUMMY_PARENT, 1307 CLK_DPLL, 1308 CLK_RPLL_TO_FPD, 1309 CLK_NA_PARENT 1310 }), 1311 .nodes = &generic_mux_div_div_gate_nodes, 1312 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1313 }, 1314 [CLK_DPDMA_REF] = { 1315 .name = "dpdma_ref", 1316 .control_reg = CRF_APB_DPDMA_REF_CTRL, 1317 .status_reg = 0, 1318 .parents = &((int32_t []) { 1319 CLK_APLL, 1320 CLK_DUMMY_PARENT, 1321 CLK_VPLL, 1322 CLK_DPLL, 1323 CLK_NA_PARENT 1324 }), 1325 .nodes = &generic_mux_div_gate_nodes, 1326 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1327 }, 1328 [CLK_DDR_REF] = { 1329 .name = "ddr_ref", 1330 .control_reg = CRF_APB_DDR_CTRL, 1331 .status_reg = 0, 1332 .parents = &((int32_t []) { 1333 CLK_DPLL, 1334 CLK_VPLL, 1335 CLK_NA_PARENT 1336 }), 1337 .nodes = &ddr_nodes, 1338 .num_nodes = ARRAY_SIZE(ddr_nodes), 1339 }, 1340 [CLK_GPU_REF] = { 1341 .name = "gpu_ref", 1342 .control_reg = CRF_APB_GPU_REF_CTRL, 1343 .status_reg = 0, 1344 .parents = &((int32_t []) { 1345 CLK_IOPLL_TO_FPD, 1346 CLK_DUMMY_PARENT, 1347 CLK_VPLL, 1348 CLK_DPLL, 1349 CLK_NA_PARENT 1350 }), 1351 .nodes = &generic_mux_div_gate_nodes, 1352 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1353 }, 1354 [CLK_SATA_REF] = { 1355 .name = "sata_ref", 1356 .control_reg = CRF_APB_SATA_REF_CTRL, 1357 .status_reg = 0, 1358 .parents = &((int32_t []) { 1359 CLK_IOPLL_TO_FPD, 1360 CLK_DUMMY_PARENT, 1361 CLK_APLL, 1362 CLK_DPLL, 1363 CLK_NA_PARENT 1364 }), 1365 .nodes = &generic_mux_div_gate_nodes, 1366 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1367 }, 1368 [CLK_PCIE_REF] = { 1369 .name = "pcie_ref", 1370 .control_reg = CRF_APB_PCIE_REF_CTRL, 1371 .status_reg = 0, 1372 .parents = &((int32_t []) { 1373 CLK_IOPLL_TO_FPD, 1374 CLK_DUMMY_PARENT, 1375 CLK_RPLL_TO_FPD, 1376 CLK_DPLL, 1377 CLK_NA_PARENT 1378 }), 1379 .nodes = &generic_mux_div_gate_nodes, 1380 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1381 }, 1382 [CLK_GDMA_REF] = { 1383 .name = "gdma_ref", 1384 .control_reg = CRF_APB_GDMA_REF_CTRL, 1385 .status_reg = 0, 1386 .parents = &((int32_t []) { 1387 CLK_APLL, 1388 CLK_DUMMY_PARENT, 1389 CLK_VPLL, 1390 CLK_DPLL, 1391 CLK_NA_PARENT 1392 }), 1393 .nodes = &generic_mux_div_gate_nodes, 1394 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1395 }, 1396 [CLK_GTGREF0_REF] = { 1397 .name = "gtgref0_ref", 1398 .control_reg = CRF_APB_GTGREF0_REF_CTRL, 1399 .status_reg = 0, 1400 .parents = &((int32_t []) { 1401 CLK_IOPLL_TO_FPD, 1402 CLK_DUMMY_PARENT, 1403 CLK_APLL, 1404 CLK_DPLL, 1405 CLK_NA_PARENT 1406 }), 1407 .nodes = &generic_mux_div_gate_nodes, 1408 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1409 }, 1410 [CLK_TOPSW_MAIN] = { 1411 .name = "topsw_main", 1412 .control_reg = CRF_APB_TOPSW_MAIN_CTRL, 1413 .status_reg = 0, 1414 .parents = &((int32_t []) { 1415 CLK_APLL, 1416 CLK_DUMMY_PARENT, 1417 CLK_VPLL, 1418 CLK_DPLL, 1419 CLK_NA_PARENT 1420 }), 1421 .nodes = &generic_mux_div_unused_gate_nodes, 1422 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1423 }, 1424 [CLK_TOPSW_LSBUS] = { 1425 .name = "topsw_lsbus", 1426 .control_reg = CRF_APB_TOPSW_LSBUS_CTRL, 1427 .status_reg = 0, 1428 .parents = &((int32_t []) { 1429 CLK_APLL, 1430 CLK_DUMMY_PARENT, 1431 CLK_IOPLL_TO_FPD, 1432 CLK_DPLL, 1433 CLK_NA_PARENT 1434 }), 1435 .nodes = &generic_mux_div_unused_gate_nodes, 1436 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1437 }, 1438 [CLK_IOU_SWITCH] = { 1439 .name = "iou_switch", 1440 .control_reg = CRL_APB_IOU_SWITCH_CTRL, 1441 .status_reg = 0, 1442 .parents = &((int32_t []) { 1443 CLK_RPLL, 1444 CLK_DUMMY_PARENT, 1445 CLK_IOPLL, 1446 CLK_DPLL_TO_LPD, 1447 CLK_NA_PARENT 1448 }), 1449 .nodes = &generic_mux_div_unused_gate_nodes, 1450 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1451 }, 1452 [CLK_GEM0_REF_UNGATED] = { 1453 .name = "gem0_ref_ung", 1454 .control_reg = CRL_APB_GEM0_REF_CTRL, 1455 .status_reg = 0, 1456 .parents = &((int32_t []) { 1457 CLK_IOPLL, 1458 CLK_DUMMY_PARENT, 1459 CLK_RPLL, 1460 CLK_DPLL_TO_LPD, 1461 CLK_NA_PARENT 1462 }), 1463 .nodes = &gem_ref_ungated_nodes, 1464 .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), 1465 }, 1466 [CLK_GEM1_REF_UNGATED] = { 1467 .name = "gem1_ref_ung", 1468 .control_reg = CRL_APB_GEM1_REF_CTRL, 1469 .status_reg = 0, 1470 .parents = &((int32_t []) { 1471 CLK_IOPLL, 1472 CLK_DUMMY_PARENT, 1473 CLK_RPLL, 1474 CLK_DPLL_TO_LPD, 1475 CLK_NA_PARENT 1476 }), 1477 .nodes = &gem_ref_ungated_nodes, 1478 .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), 1479 }, 1480 [CLK_GEM2_REF_UNGATED] = { 1481 .name = "gem2_ref_ung", 1482 .control_reg = CRL_APB_GEM2_REF_CTRL, 1483 .status_reg = 0, 1484 .parents = &((int32_t []) { 1485 CLK_IOPLL, 1486 CLK_DUMMY_PARENT, 1487 CLK_RPLL, 1488 CLK_DPLL_TO_LPD, 1489 CLK_NA_PARENT 1490 }), 1491 .nodes = &gem_ref_ungated_nodes, 1492 .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), 1493 }, 1494 [CLK_GEM3_REF_UNGATED] = { 1495 .name = "gem3_ref_ung", 1496 .control_reg = CRL_APB_GEM3_REF_CTRL, 1497 .status_reg = 0, 1498 .parents = &((int32_t []) { 1499 CLK_IOPLL, 1500 CLK_DUMMY_PARENT, 1501 CLK_RPLL, 1502 CLK_DPLL_TO_LPD, 1503 CLK_NA_PARENT 1504 }), 1505 .nodes = &gem_ref_ungated_nodes, 1506 .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), 1507 }, 1508 [CLK_GEM0_REF] = { 1509 .name = "gem0_ref", 1510 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1511 .status_reg = 0, 1512 .parents = &((int32_t []) { 1513 CLK_GEM0_REF_UNGATED | 1514 (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1515 EXT_CLK_GEM0_TX_EMIO | CLK_EXTERNAL_PARENT, 1516 CLK_NA_PARENT 1517 }), 1518 .nodes = &gem0_ref_nodes, 1519 .num_nodes = ARRAY_SIZE(gem0_ref_nodes), 1520 }, 1521 [CLK_GEM1_REF] = { 1522 .name = "gem1_ref", 1523 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1524 .status_reg = 0, 1525 .parents = &((int32_t []) { 1526 CLK_GEM1_REF_UNGATED | 1527 (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1528 EXT_CLK_GEM1_TX_EMIO | CLK_EXTERNAL_PARENT, 1529 CLK_NA_PARENT 1530 }), 1531 .nodes = &gem1_ref_nodes, 1532 .num_nodes = ARRAY_SIZE(gem1_ref_nodes), 1533 }, 1534 [CLK_GEM2_REF] = { 1535 .name = "gem2_ref", 1536 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1537 .status_reg = 0, 1538 .parents = &((int32_t []) { 1539 CLK_GEM2_REF_UNGATED | 1540 (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1541 EXT_CLK_GEM2_TX_EMIO | CLK_EXTERNAL_PARENT, 1542 CLK_NA_PARENT 1543 }), 1544 .nodes = &gem2_ref_nodes, 1545 .num_nodes = ARRAY_SIZE(gem2_ref_nodes), 1546 }, 1547 [CLK_GEM3_REF] = { 1548 .name = "gem3_ref", 1549 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1550 .status_reg = 0, 1551 .parents = &((int32_t []) { 1552 CLK_GEM3_REF_UNGATED | 1553 (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1554 EXT_CLK_GEM3_TX_EMIO | CLK_EXTERNAL_PARENT, 1555 CLK_NA_PARENT 1556 }), 1557 .nodes = &gem3_ref_nodes, 1558 .num_nodes = ARRAY_SIZE(gem3_ref_nodes), 1559 }, 1560 [CLK_USB0_BUS_REF] = { 1561 .name = "usb0_bus_ref", 1562 .control_reg = CRL_APB_USB0_BUS_REF_CTRL, 1563 .status_reg = 0, 1564 .parents = &((int32_t []) { 1565 CLK_IOPLL, 1566 CLK_DUMMY_PARENT, 1567 CLK_RPLL, 1568 CLK_DPLL_TO_LPD, 1569 CLK_NA_PARENT 1570 }), 1571 .nodes = &usb_nodes, 1572 .num_nodes = ARRAY_SIZE(usb_nodes), 1573 }, 1574 [CLK_USB1_BUS_REF] = { 1575 .name = "usb1_bus_ref", 1576 .control_reg = CRL_APB_USB1_BUS_REF_CTRL, 1577 .status_reg = 0, 1578 .parents = &((int32_t []) { 1579 CLK_IOPLL, 1580 CLK_DUMMY_PARENT, 1581 CLK_RPLL, 1582 CLK_DPLL_TO_LPD, 1583 CLK_NA_PARENT 1584 }), 1585 .nodes = &usb_nodes, 1586 .num_nodes = ARRAY_SIZE(usb_nodes), 1587 }, 1588 [CLK_USB3_DUAL_REF] = { 1589 .name = "usb3_dual_ref", 1590 .control_reg = CRL_APB_USB3_DUAL_REF_CTRL, 1591 .status_reg = 0, 1592 .parents = &((int32_t []) { 1593 CLK_IOPLL, 1594 CLK_DUMMY_PARENT, 1595 CLK_RPLL, 1596 CLK_DPLL_TO_LPD, 1597 CLK_NA_PARENT 1598 }), 1599 .nodes = &usb_nodes, 1600 .num_nodes = ARRAY_SIZE(usb_nodes), 1601 }, 1602 [CLK_QSPI_REF] = { 1603 .name = "qspi_ref", 1604 .control_reg = CRL_APB_QSPI_REF_CTRL, 1605 .status_reg = 0, 1606 .parents = &((int32_t []) { 1607 CLK_IOPLL, 1608 CLK_DUMMY_PARENT, 1609 CLK_RPLL, 1610 CLK_DPLL_TO_LPD, 1611 CLK_NA_PARENT 1612 }), 1613 .nodes = &generic_mux_div_div_gate_nodes, 1614 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1615 }, 1616 [CLK_SDIO0_REF] = { 1617 .name = "sdio0_ref", 1618 .control_reg = CRL_APB_SDIO0_REF_CTRL, 1619 .status_reg = 0, 1620 .parents = &((int32_t []) { 1621 CLK_IOPLL, 1622 CLK_DUMMY_PARENT, 1623 CLK_RPLL, 1624 CLK_VPLL_TO_LPD, 1625 CLK_NA_PARENT 1626 }), 1627 .nodes = &generic_mux_div_div_gate_nodes, 1628 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1629 }, 1630 [CLK_SDIO1_REF] = { 1631 .name = "sdio1_ref", 1632 .control_reg = CRL_APB_SDIO1_REF_CTRL, 1633 .status_reg = 0, 1634 .parents = &((int32_t []) { 1635 CLK_IOPLL, 1636 CLK_DUMMY_PARENT, 1637 CLK_RPLL, 1638 CLK_VPLL_TO_LPD, 1639 CLK_NA_PARENT 1640 }), 1641 .nodes = &generic_mux_div_div_gate_nodes, 1642 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1643 }, 1644 [CLK_UART0_REF] = { 1645 .name = "uart0_ref", 1646 .control_reg = CRL_APB_UART0_REF_CTRL, 1647 .status_reg = 0, 1648 .parents = &((int32_t []) { 1649 CLK_IOPLL, 1650 CLK_DUMMY_PARENT, 1651 CLK_RPLL, 1652 CLK_DPLL_TO_LPD, 1653 CLK_NA_PARENT 1654 }), 1655 .nodes = &generic_mux_div_div_gate_nodes, 1656 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1657 }, 1658 [CLK_UART1_REF] = { 1659 .name = "uart1_ref", 1660 .control_reg = CRL_APB_UART1_REF_CTRL, 1661 .status_reg = 0, 1662 .parents = &((int32_t []) { 1663 CLK_IOPLL, 1664 CLK_DUMMY_PARENT, 1665 CLK_RPLL, 1666 CLK_DPLL_TO_LPD, 1667 CLK_NA_PARENT 1668 }), 1669 .nodes = &generic_mux_div_div_gate_nodes, 1670 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1671 }, 1672 [CLK_SPI0_REF] = { 1673 .name = "spi0_ref", 1674 .control_reg = CRL_APB_SPI0_REF_CTRL, 1675 .status_reg = 0, 1676 .parents = &((int32_t []) { 1677 CLK_IOPLL, 1678 CLK_DUMMY_PARENT, 1679 CLK_RPLL, 1680 CLK_DPLL_TO_LPD, 1681 CLK_NA_PARENT 1682 }), 1683 .nodes = &generic_mux_div_div_gate_nodes, 1684 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1685 }, 1686 [CLK_SPI1_REF] = { 1687 .name = "spi1_ref", 1688 .control_reg = CRL_APB_SPI1_REF_CTRL, 1689 .status_reg = 0, 1690 .parents = &((int32_t []) { 1691 CLK_IOPLL, 1692 CLK_DUMMY_PARENT, 1693 CLK_RPLL, 1694 CLK_DPLL_TO_LPD, 1695 CLK_NA_PARENT 1696 }), 1697 .nodes = &generic_mux_div_div_gate_nodes, 1698 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1699 }, 1700 [CLK_CAN0_REF] = { 1701 .name = "can0_ref", 1702 .control_reg = CRL_APB_CAN0_REF_CTRL, 1703 .status_reg = 0, 1704 .parents = &((int32_t []) { 1705 CLK_IOPLL, 1706 CLK_DUMMY_PARENT, 1707 CLK_RPLL, 1708 CLK_DPLL_TO_LPD, 1709 CLK_NA_PARENT 1710 }), 1711 .nodes = &generic_mux_div_div_gate_nodes, 1712 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1713 }, 1714 [CLK_CAN1_REF] = { 1715 .name = "can1_ref", 1716 .control_reg = CRL_APB_CAN1_REF_CTRL, 1717 .status_reg = 0, 1718 .parents = &((int32_t []) { 1719 CLK_IOPLL, 1720 CLK_DUMMY_PARENT, 1721 CLK_RPLL, 1722 CLK_DPLL_TO_LPD, 1723 CLK_NA_PARENT 1724 }), 1725 .nodes = &generic_mux_div_div_gate_nodes, 1726 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1727 }, 1728 [CLK_NAND_REF] = { 1729 .name = "nand_ref", 1730 .control_reg = CRL_APB_NAND_REF_CTRL, 1731 .status_reg = 0, 1732 .parents = &((int32_t []) { 1733 CLK_IOPLL, 1734 CLK_DUMMY_PARENT, 1735 CLK_RPLL, 1736 CLK_DPLL_TO_LPD, 1737 CLK_NA_PARENT 1738 }), 1739 .nodes = &generic_mux_div_div_gate_nodes, 1740 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1741 }, 1742 [CLK_GEM_TSU_REF] = { 1743 .name = "gem_tsu_ref", 1744 .control_reg = CRL_APB_GEM_TSU_REF_CTRL, 1745 .status_reg = 0, 1746 .parents = &((int32_t []) { 1747 CLK_IOPLL, 1748 CLK_DUMMY_PARENT, 1749 CLK_RPLL, 1750 CLK_DPLL_TO_LPD, 1751 CLK_NA_PARENT 1752 }), 1753 .nodes = &generic_mux_div_div_gate_nodes, 1754 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1755 }, 1756 [CLK_DLL_REF] = { 1757 .name = "dll_ref", 1758 .control_reg = CRL_APB_DLL_REF_CTRL, 1759 .status_reg = 0, 1760 .parents = &((int32_t []) { 1761 CLK_IOPLL, 1762 CLK_RPLL, 1763 CLK_NA_PARENT 1764 }), 1765 .nodes = &dll_ref_nodes, 1766 .num_nodes = ARRAY_SIZE(dll_ref_nodes), 1767 }, 1768 [CLK_ADMA_REF] = { 1769 .name = "adma_ref", 1770 .control_reg = CRL_APB_ADMA_REF_CTRL, 1771 .status_reg = 0, 1772 .parents = &((int32_t []) { 1773 CLK_RPLL, 1774 CLK_DUMMY_PARENT, 1775 CLK_IOPLL, 1776 CLK_DPLL_TO_LPD, 1777 CLK_NA_PARENT 1778 }), 1779 .nodes = &generic_mux_div_gate_nodes, 1780 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1781 }, 1782 [CLK_DBG_LPD] = { 1783 .name = "dbg_lpd", 1784 .control_reg = CRL_APB_DBG_LPD_CTRL, 1785 .status_reg = 0, 1786 .parents = &((int32_t []) { 1787 CLK_RPLL, 1788 CLK_DUMMY_PARENT, 1789 CLK_IOPLL, 1790 CLK_DPLL_TO_LPD, 1791 CLK_NA_PARENT 1792 }), 1793 .nodes = &generic_mux_div_gate_nodes, 1794 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1795 }, 1796 [CLK_CPU_R5] = { 1797 .name = "cpu_r5", 1798 .control_reg = CRL_APB_CPU_R5_CTRL, 1799 .status_reg = 0, 1800 .parents = &((int32_t []) { 1801 CLK_RPLL, 1802 CLK_DUMMY_PARENT, 1803 CLK_IOPLL, 1804 CLK_DPLL_TO_LPD, 1805 CLK_NA_PARENT 1806 }), 1807 .nodes = &generic_mux_div_unused_gate_nodes, 1808 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1809 }, 1810 [CLK_CSU_PLL] = { 1811 .name = "csu_pll", 1812 .control_reg = CRL_APB_CSU_PLL_CTRL, 1813 .status_reg = 0, 1814 .parents = &((int32_t []) { 1815 CLK_IOPLL, 1816 CLK_DUMMY_PARENT, 1817 CLK_RPLL, 1818 CLK_DPLL_TO_LPD, 1819 CLK_NA_PARENT 1820 }), 1821 .nodes = &generic_mux_div_gate_nodes, 1822 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1823 }, 1824 [CLK_PCAP] = { 1825 .name = "pcap", 1826 .control_reg = CRL_APB_PCAP_CTRL, 1827 .status_reg = 0, 1828 .parents = &((int32_t []) { 1829 CLK_IOPLL, 1830 CLK_DUMMY_PARENT, 1831 CLK_RPLL, 1832 CLK_DPLL_TO_LPD, 1833 CLK_NA_PARENT 1834 }), 1835 .nodes = &generic_mux_div_gate_nodes, 1836 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1837 }, 1838 [CLK_LPD_LSBUS] = { 1839 .name = "lpd_lsbus", 1840 .control_reg = CRL_APB_LPD_LSBUS_CTRL, 1841 .status_reg = 0, 1842 .parents = &((int32_t []) { 1843 CLK_RPLL, 1844 CLK_DUMMY_PARENT, 1845 CLK_IOPLL, 1846 CLK_DPLL_TO_LPD, 1847 CLK_NA_PARENT 1848 }), 1849 .nodes = &generic_mux_div_unused_gate_nodes, 1850 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1851 }, 1852 [CLK_LPD_SWITCH] = { 1853 .name = "lpd_switch", 1854 .control_reg = CRL_APB_LPD_SWITCH_CTRL, 1855 .status_reg = 0, 1856 .parents = &((int32_t []) { 1857 CLK_RPLL, 1858 CLK_DUMMY_PARENT, 1859 CLK_IOPLL, 1860 CLK_DPLL_TO_LPD, 1861 CLK_NA_PARENT 1862 }), 1863 .nodes = &generic_mux_div_unused_gate_nodes, 1864 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1865 }, 1866 [CLK_I2C0_REF] = { 1867 .name = "i2c0_ref", 1868 .control_reg = CRL_APB_I2C0_REF_CTRL, 1869 .status_reg = 0, 1870 .parents = &((int32_t []) { 1871 CLK_IOPLL, 1872 CLK_DUMMY_PARENT, 1873 CLK_RPLL, 1874 CLK_DPLL_TO_LPD, 1875 CLK_NA_PARENT 1876 }), 1877 .nodes = &generic_mux_div_div_gate_nodes, 1878 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1879 }, 1880 [CLK_I2C1_REF] = { 1881 .name = "i2c1_ref", 1882 .control_reg = CRL_APB_I2C1_REF_CTRL, 1883 .status_reg = 0, 1884 .parents = &((int32_t []) { 1885 CLK_IOPLL, 1886 CLK_DUMMY_PARENT, 1887 CLK_RPLL, 1888 CLK_DPLL_TO_LPD, 1889 CLK_NA_PARENT 1890 }), 1891 .nodes = &generic_mux_div_div_gate_nodes, 1892 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1893 }, 1894 [CLK_TIMESTAMP_REF] = { 1895 .name = "timestamp_ref", 1896 .control_reg = CRL_APB_TIMESTAMP_REF_CTRL, 1897 .status_reg = 0, 1898 .parents = &((int32_t []) { 1899 CLK_IOPLL, 1900 CLK_DUMMY_PARENT, 1901 CLK_RPLL, 1902 CLK_DPLL_TO_LPD, 1903 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1904 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1905 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1906 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1907 CLK_NA_PARENT 1908 }), 1909 .nodes = ×tamp_ref_nodes, 1910 .num_nodes = ARRAY_SIZE(timestamp_ref_nodes), 1911 }, 1912 [CLK_PL0_REF] = { 1913 .name = "pl0_ref", 1914 .control_reg = CRL_APB_PL0_REF_CTRL, 1915 .status_reg = 0, 1916 .parents = &((int32_t []) { 1917 CLK_IOPLL, 1918 CLK_DUMMY_PARENT, 1919 CLK_RPLL, 1920 CLK_DPLL_TO_LPD, 1921 CLK_NA_PARENT 1922 }), 1923 .nodes = &pl_nodes, 1924 .num_nodes = ARRAY_SIZE(pl_nodes), 1925 }, 1926 [CLK_PL1_REF] = { 1927 .name = "pl1_ref", 1928 .control_reg = CRL_APB_PL1_REF_CTRL, 1929 .status_reg = 0, 1930 .parents = &((int32_t []) { 1931 CLK_IOPLL, 1932 CLK_DUMMY_PARENT, 1933 CLK_RPLL, 1934 CLK_DPLL_TO_LPD, 1935 CLK_NA_PARENT 1936 }), 1937 .nodes = &pl_nodes, 1938 .num_nodes = ARRAY_SIZE(pl_nodes), 1939 }, 1940 [CLK_PL2_REF] = { 1941 .name = "pl2_ref", 1942 .control_reg = CRL_APB_PL2_REF_CTRL, 1943 .status_reg = 0, 1944 .parents = &((int32_t []) { 1945 CLK_IOPLL, 1946 CLK_DUMMY_PARENT, 1947 CLK_RPLL, 1948 CLK_DPLL_TO_LPD, 1949 CLK_NA_PARENT 1950 }), 1951 .nodes = &pl_nodes, 1952 .num_nodes = ARRAY_SIZE(pl_nodes), 1953 }, 1954 [CLK_PL3_REF] = { 1955 .name = "pl3_ref", 1956 .control_reg = CRL_APB_PL3_REF_CTRL, 1957 .status_reg = 0, 1958 .parents = &((int32_t []) { 1959 CLK_IOPLL, 1960 CLK_DUMMY_PARENT, 1961 CLK_RPLL, 1962 CLK_DPLL_TO_LPD, 1963 CLK_NA_PARENT 1964 }), 1965 .nodes = &pl_nodes, 1966 .num_nodes = ARRAY_SIZE(pl_nodes), 1967 }, 1968 [CLK_AMS_REF] = { 1969 .name = "ams_ref", 1970 .control_reg = CRL_APB_AMS_REF_CTRL, 1971 .status_reg = 0, 1972 .parents = &((int32_t []) { 1973 CLK_RPLL, 1974 CLK_DUMMY_PARENT, 1975 CLK_IOPLL, 1976 CLK_DPLL_TO_LPD, 1977 CLK_NA_PARENT 1978 }), 1979 .nodes = &generic_mux_div_div_gate_nodes, 1980 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1981 }, 1982 [CLK_IOPLL_TO_FPD] = { 1983 .name = "iopll_to_fpd", 1984 .control_reg = CRL_APB_IOPLL_TO_FPD_CTRL, 1985 .status_reg = 0, 1986 .parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}), 1987 .nodes = &generic_domain_crossing_nodes, 1988 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 1989 }, 1990 [CLK_RPLL_TO_FPD] = { 1991 .name = "rpll_to_fpd", 1992 .control_reg = CRL_APB_RPLL_TO_FPD_CTRL, 1993 .status_reg = 0, 1994 .parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}), 1995 .nodes = &rpll_to_fpd_nodes, 1996 .num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes), 1997 }, 1998 [CLK_APLL_TO_LPD] = { 1999 .name = "apll_to_lpd", 2000 .control_reg = CRF_APB_APLL_TO_LPD_CTRL, 2001 .status_reg = 0, 2002 .parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}), 2003 .nodes = &generic_domain_crossing_nodes, 2004 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 2005 }, 2006 [CLK_DPLL_TO_LPD] = { 2007 .name = "dpll_to_lpd", 2008 .control_reg = CRF_APB_DPLL_TO_LPD_CTRL, 2009 .status_reg = 0, 2010 .parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}), 2011 .nodes = &generic_domain_crossing_nodes, 2012 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 2013 }, 2014 [CLK_VPLL_TO_LPD] = { 2015 .name = "vpll_to_lpd", 2016 .control_reg = CRF_APB_VPLL_TO_LPD_CTRL, 2017 .status_reg = 0, 2018 .parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}), 2019 .nodes = &generic_domain_crossing_nodes, 2020 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 2021 }, 2022 [CLK_GEM0_TX] = { 2023 .name = "gem0_tx", 2024 .control_reg = CRL_APB_GEM0_REF_CTRL, 2025 .status_reg = 0, 2026 .parents = &((int32_t []) { 2027 CLK_GEM0_REF, 2028 CLK_NA_PARENT 2029 }), 2030 .nodes = &gem_tx_nodes, 2031 .num_nodes = ARRAY_SIZE(gem_tx_nodes), 2032 }, 2033 [CLK_GEM1_TX] = { 2034 .name = "gem1_tx", 2035 .control_reg = CRL_APB_GEM1_REF_CTRL, 2036 .status_reg = 0, 2037 .parents = &((int32_t []) { 2038 CLK_GEM1_REF, 2039 CLK_NA_PARENT 2040 }), 2041 .nodes = &gem_tx_nodes, 2042 .num_nodes = ARRAY_SIZE(gem_tx_nodes), 2043 }, 2044 [CLK_GEM2_TX] = { 2045 .name = "gem2_tx", 2046 .control_reg = CRL_APB_GEM2_REF_CTRL, 2047 .status_reg = 0, 2048 .parents = &((int32_t []) { 2049 CLK_GEM2_REF, 2050 CLK_NA_PARENT 2051 }), 2052 .nodes = &gem_tx_nodes, 2053 .num_nodes = ARRAY_SIZE(gem_tx_nodes), 2054 }, 2055 [CLK_GEM3_TX] = { 2056 .name = "gem3_tx", 2057 .control_reg = CRL_APB_GEM3_REF_CTRL, 2058 .status_reg = 0, 2059 .parents = &((int32_t []) { 2060 CLK_GEM3_REF, 2061 CLK_NA_PARENT 2062 }), 2063 .nodes = &gem_tx_nodes, 2064 .num_nodes = ARRAY_SIZE(gem_tx_nodes), 2065 }, 2066 [CLK_GEM0_RX] = { 2067 .name = "gem0_rx", 2068 .control_reg = CRL_APB_GEM0_REF_CTRL, 2069 .status_reg = 0, 2070 .parents = &((int32_t []) { 2071 EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT, 2072 CLK_NA_PARENT 2073 }), 2074 .nodes = &gem_rx_nodes, 2075 .num_nodes = ARRAY_SIZE(gem_rx_nodes), 2076 }, 2077 [CLK_GEM1_RX] = { 2078 .name = "gem1_rx", 2079 .control_reg = CRL_APB_GEM1_REF_CTRL, 2080 .status_reg = 0, 2081 .parents = &((int32_t []) { 2082 EXT_CLK_GEM1_RX_EMIO | CLK_EXTERNAL_PARENT, 2083 CLK_NA_PARENT 2084 }), 2085 .nodes = &gem_rx_nodes, 2086 .num_nodes = ARRAY_SIZE(gem_rx_nodes), 2087 }, 2088 [CLK_GEM2_RX] = { 2089 .name = "gem2_rx", 2090 .control_reg = CRL_APB_GEM2_REF_CTRL, 2091 .status_reg = 0, 2092 .parents = &((int32_t []) { 2093 EXT_CLK_GEM2_RX_EMIO | CLK_EXTERNAL_PARENT, 2094 CLK_NA_PARENT 2095 }), 2096 .nodes = &gem_rx_nodes, 2097 .num_nodes = ARRAY_SIZE(gem_rx_nodes), 2098 }, 2099 [CLK_GEM3_RX] = { 2100 .name = "gem3_rx", 2101 .control_reg = CRL_APB_GEM3_REF_CTRL, 2102 .status_reg = 0, 2103 .parents = &((int32_t []) { 2104 EXT_CLK_GEM3_RX_EMIO | CLK_EXTERNAL_PARENT, 2105 CLK_NA_PARENT 2106 }), 2107 .nodes = &gem_rx_nodes, 2108 .num_nodes = ARRAY_SIZE(gem_rx_nodes), 2109 }, 2110 [CLK_ACPU_HALF] = { 2111 .name = "acpu_half", 2112 .control_reg = CRF_APB_ACPU_CTRL, 2113 .status_reg = 0, 2114 .parents = &((int32_t []) { 2115 CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2116 CLK_NA_PARENT 2117 }), 2118 .nodes = &acpu_half_nodes, 2119 .num_nodes = ARRAY_SIZE(acpu_half_nodes), 2120 }, 2121 [CLK_FPD_WDT] = { 2122 .name = "fpd_wdt", 2123 .control_reg = FPD_SLCR_WDT_CLK_SEL, 2124 .status_reg = 0, 2125 .parents = &((int32_t []) { 2126 CLK_TOPSW_LSBUS, 2127 EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT, 2128 CLK_NA_PARENT 2129 }), 2130 .nodes = &wdt_nodes, 2131 .num_nodes = ARRAY_SIZE(wdt_nodes), 2132 }, 2133 [CLK_GPU_PP0_REF] = { 2134 .name = "gpu_pp0_ref", 2135 .control_reg = CRF_APB_GPU_REF_CTRL, 2136 .status_reg = 0, 2137 .parents = &((int32_t []) { 2138 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2139 CLK_NA_PARENT 2140 }), 2141 .nodes = &gpu_pp0_nodes, 2142 .num_nodes = ARRAY_SIZE(gpu_pp0_nodes), 2143 }, 2144 [CLK_GPU_PP1_REF] = { 2145 .name = "gpu_pp1_ref", 2146 .control_reg = CRF_APB_GPU_REF_CTRL, 2147 .status_reg = 0, 2148 .parents = &((int32_t []) { 2149 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2150 CLK_NA_PARENT 2151 }), 2152 .nodes = &gpu_pp1_nodes, 2153 .num_nodes = ARRAY_SIZE(gpu_pp1_nodes), 2154 }, 2155 [CLK_GEM_TSU] = { 2156 .name = "gem_tsu", 2157 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 2158 .status_reg = 0, 2159 .parents = &((int32_t []) { 2160 CLK_GEM_TSU_REF, 2161 CLK_GEM_TSU_REF, 2162 EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT, 2163 EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT, 2164 CLK_NA_PARENT 2165 }), 2166 .nodes = &gem_tsu_nodes, 2167 .num_nodes = ARRAY_SIZE(gem_tsu_nodes), 2168 }, 2169 [CLK_CPU_R5_CORE] = { 2170 .name = "cpu_r5_core", 2171 .control_reg = CRL_APB_CPU_R5_CTRL, 2172 .status_reg = 0, 2173 .parents = &((int32_t []) { 2174 CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2175 CLK_DUMMY_PARENT, 2176 CLK_NA_PARENT 2177 }), 2178 .nodes = &cpu_r5_core_nodes, 2179 .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes), 2180 }, 2181 [CLK_CAN0_MIO] = { 2182 .name = "can0_mio", 2183 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2184 .status_reg = 0, 2185 .parents = &can_mio_parents, 2186 .nodes = &can0_mio_nodes, 2187 .num_nodes = ARRAY_SIZE(can0_mio_nodes), 2188 }, 2189 [CLK_CAN1_MIO] = { 2190 .name = "can1_mio", 2191 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2192 .status_reg = 0, 2193 .parents = &can_mio_parents, 2194 .nodes = &can1_mio_nodes, 2195 .num_nodes = ARRAY_SIZE(can1_mio_nodes), 2196 }, 2197 [CLK_CAN0] = { 2198 .name = "can0", 2199 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2200 .status_reg = 0, 2201 .parents = &((int32_t []) { 2202 CLK_CAN0_REF, 2203 CLK_CAN0_MIO, 2204 CLK_NA_PARENT 2205 }), 2206 .nodes = &can0_nodes, 2207 .num_nodes = ARRAY_SIZE(can0_nodes), 2208 }, 2209 [CLK_CAN1] = { 2210 .name = "can1", 2211 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2212 .status_reg = 0, 2213 .parents = &((int32_t []) { 2214 CLK_CAN1_REF, 2215 CLK_CAN1_MIO, 2216 CLK_NA_PARENT 2217 }), 2218 .nodes = &can1_nodes, 2219 .num_nodes = ARRAY_SIZE(can1_nodes), 2220 }, 2221 [CLK_LPD_WDT] = { 2222 .name = "lpd_wdt", 2223 .control_reg = IOU_SLCR_WDT_CLK_SEL, 2224 .status_reg = 0, 2225 .parents = &((int32_t []) { 2226 CLK_LPD_LSBUS, 2227 EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT, 2228 CLK_NA_PARENT 2229 }), 2230 .nodes = &wdt_nodes, 2231 .num_nodes = ARRAY_SIZE(wdt_nodes), 2232 }, 2233 }; 2234 2235 static struct pm_ext_clock ext_clocks[] = { 2236 [EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = { 2237 .name = "pss_ref_clk", 2238 }, 2239 [EXT_CLK_INDEX(EXT_CLK_VIDEO)] = { 2240 .name = "video_clk", 2241 }, 2242 [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = { 2243 .name = "pss_alt_ref_clk", 2244 }, 2245 [EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = { 2246 .name = "aux_ref_clk", 2247 }, 2248 [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = { 2249 .name = "video_clk", 2250 }, 2251 [EXT_CLK_INDEX(EXT_CLK_SWDT0)] = { 2252 .name = "swdt0_ext_clk", 2253 }, 2254 [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = { 2255 .name = "swdt1_ext_clk", 2256 }, 2257 [EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = { 2258 .name = "gem0_tx_ext", 2259 }, 2260 [EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = { 2261 .name = "gem1_tx_ext", 2262 }, 2263 [EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = { 2264 .name = "gem2_tx_ext", 2265 }, 2266 [EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = { 2267 .name = "gem3_tx_ext", 2268 }, 2269 [EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = { 2270 .name = "gem0_rx_ext", 2271 }, 2272 [EXT_CLK_INDEX(EXT_CLK_GEM1_RX_EMIO)] = { 2273 .name = "gem1_rx_ext", 2274 }, 2275 [EXT_CLK_INDEX(EXT_CLK_GEM2_RX_EMIO)] = { 2276 .name = "gem2_rx_ext", 2277 }, 2278 [EXT_CLK_INDEX(EXT_CLK_GEM3_RX_EMIO)] = { 2279 .name = "gem3_rx_ext", 2280 }, 2281 [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = { 2282 .name = "mio_clk_50_51", 2283 }, 2284 EXT_CLK_MIO_DATA(0), 2285 EXT_CLK_MIO_DATA(1), 2286 EXT_CLK_MIO_DATA(2), 2287 EXT_CLK_MIO_DATA(3), 2288 EXT_CLK_MIO_DATA(4), 2289 EXT_CLK_MIO_DATA(5), 2290 EXT_CLK_MIO_DATA(6), 2291 EXT_CLK_MIO_DATA(7), 2292 EXT_CLK_MIO_DATA(8), 2293 EXT_CLK_MIO_DATA(9), 2294 EXT_CLK_MIO_DATA(10), 2295 EXT_CLK_MIO_DATA(11), 2296 EXT_CLK_MIO_DATA(12), 2297 EXT_CLK_MIO_DATA(13), 2298 EXT_CLK_MIO_DATA(14), 2299 EXT_CLK_MIO_DATA(15), 2300 EXT_CLK_MIO_DATA(16), 2301 EXT_CLK_MIO_DATA(17), 2302 EXT_CLK_MIO_DATA(18), 2303 EXT_CLK_MIO_DATA(19), 2304 EXT_CLK_MIO_DATA(20), 2305 EXT_CLK_MIO_DATA(21), 2306 EXT_CLK_MIO_DATA(22), 2307 EXT_CLK_MIO_DATA(23), 2308 EXT_CLK_MIO_DATA(24), 2309 EXT_CLK_MIO_DATA(25), 2310 EXT_CLK_MIO_DATA(26), 2311 EXT_CLK_MIO_DATA(27), 2312 EXT_CLK_MIO_DATA(28), 2313 EXT_CLK_MIO_DATA(29), 2314 EXT_CLK_MIO_DATA(30), 2315 EXT_CLK_MIO_DATA(31), 2316 EXT_CLK_MIO_DATA(32), 2317 EXT_CLK_MIO_DATA(33), 2318 EXT_CLK_MIO_DATA(34), 2319 EXT_CLK_MIO_DATA(35), 2320 EXT_CLK_MIO_DATA(36), 2321 EXT_CLK_MIO_DATA(37), 2322 EXT_CLK_MIO_DATA(38), 2323 EXT_CLK_MIO_DATA(39), 2324 EXT_CLK_MIO_DATA(40), 2325 EXT_CLK_MIO_DATA(41), 2326 EXT_CLK_MIO_DATA(42), 2327 EXT_CLK_MIO_DATA(43), 2328 EXT_CLK_MIO_DATA(44), 2329 EXT_CLK_MIO_DATA(45), 2330 EXT_CLK_MIO_DATA(46), 2331 EXT_CLK_MIO_DATA(47), 2332 EXT_CLK_MIO_DATA(48), 2333 EXT_CLK_MIO_DATA(49), 2334 EXT_CLK_MIO_DATA(50), 2335 EXT_CLK_MIO_DATA(51), 2336 EXT_CLK_MIO_DATA(52), 2337 EXT_CLK_MIO_DATA(53), 2338 EXT_CLK_MIO_DATA(54), 2339 EXT_CLK_MIO_DATA(55), 2340 EXT_CLK_MIO_DATA(56), 2341 EXT_CLK_MIO_DATA(57), 2342 EXT_CLK_MIO_DATA(58), 2343 EXT_CLK_MIO_DATA(59), 2344 EXT_CLK_MIO_DATA(60), 2345 EXT_CLK_MIO_DATA(61), 2346 EXT_CLK_MIO_DATA(62), 2347 EXT_CLK_MIO_DATA(63), 2348 EXT_CLK_MIO_DATA(64), 2349 EXT_CLK_MIO_DATA(65), 2350 EXT_CLK_MIO_DATA(66), 2351 EXT_CLK_MIO_DATA(67), 2352 EXT_CLK_MIO_DATA(68), 2353 EXT_CLK_MIO_DATA(69), 2354 EXT_CLK_MIO_DATA(70), 2355 EXT_CLK_MIO_DATA(71), 2356 EXT_CLK_MIO_DATA(72), 2357 EXT_CLK_MIO_DATA(73), 2358 EXT_CLK_MIO_DATA(74), 2359 EXT_CLK_MIO_DATA(75), 2360 EXT_CLK_MIO_DATA(76), 2361 EXT_CLK_MIO_DATA(77), 2362 }; 2363 2364 /* Array of clock which are invalid for this variant */ 2365 static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB, 2366 CLK_ACPU_FULL, 2367 CLK_ACPU_HALF, 2368 CLK_APLL_TO_LPD, 2369 CLK_DBG_FPD, 2370 CLK_DBG_LPD, 2371 CLK_DBG_TRACE, 2372 CLK_DBG_TSTMP, 2373 CLK_DDR_REF, 2374 CLK_TOPSW_MAIN, 2375 CLK_GTGREF0_REF, 2376 CLK_LPD_SWITCH, 2377 CLK_CPU_R5, 2378 CLK_CPU_R5_CORE, 2379 CLK_CSU_SPB, 2380 CLK_CSU_PLL, 2381 CLK_PCAP, 2382 CLK_IOU_SWITCH, 2383 CLK_DLL_REF, 2384 CLK_TIMESTAMP_REF, 2385 }; 2386 2387 /** 2388 * pm_clock_valid - Check if clock is valid or not 2389 * @clock_id Id of the clock to be queried 2390 * 2391 * This function is used to check if given clock is valid 2392 * or not for the chip variant. 2393 * 2394 * List of invalid clocks are maintained in array list for 2395 * different variants. 2396 * 2397 * Return: Returns 1 if clock is valid else 0. 2398 */ 2399 static bool pm_clock_valid(unsigned int clock_id) 2400 { 2401 unsigned int i; 2402 2403 for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++) 2404 if (pm_clk_invalid_list[i] == clock_id) 2405 return 0; 2406 2407 return 1; 2408 } 2409 2410 /** 2411 * pm_clock_type - Get clock's type 2412 * @clock_id Id of the clock to be queried 2413 * 2414 * This function is used to check type of clock (OUTPUT/EXTERNAL). 2415 * 2416 * Return: Returns type of clock (OUTPUT/EXTERNAL). 2417 */ 2418 static unsigned int pm_clock_type(unsigned int clock_id) 2419 { 2420 return (clock_id < CLK_MAX_OUTPUT_CLK) ? 2421 CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL; 2422 } 2423 2424 /** 2425 * pm_api_clock_get_num_clocks() - PM call to request number of clocks 2426 * @nclocks Number of clocks 2427 * 2428 * This function is used by master to get number of clocks. 2429 * 2430 * @return Returns success. 2431 */ 2432 enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks) 2433 { 2434 *nclocks = CLK_MAX; 2435 2436 return PM_RET_SUCCESS; 2437 } 2438 2439 /** 2440 * pm_api_clock_get_name() - PM call to request a clock's name 2441 * @clock_id Clock ID 2442 * @name Name of clock (max 16 bytes) 2443 * 2444 * This function is used by master to get nmae of clock specified 2445 * by given clock ID. 2446 * 2447 * @return Returns success. In case of error, name data is 0. 2448 */ 2449 void pm_api_clock_get_name(unsigned int clock_id, char *name) 2450 { 2451 if (clock_id == CLK_MAX) 2452 memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ? 2453 CLK_NAME_LEN : sizeof(END_OF_CLK)); 2454 else if (!pm_clock_valid(clock_id)) 2455 memset(name, 0, CLK_NAME_LEN); 2456 else if (clock_id < CLK_MAX_OUTPUT_CLK) 2457 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN); 2458 else 2459 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name, 2460 CLK_NAME_LEN); 2461 } 2462 2463 /** 2464 * pm_api_clock_get_topology() - PM call to request a clock's topology 2465 * @clock_id Clock ID 2466 * @index Topology index for next toplogy node 2467 * @topology Buffer to store nodes in topology and flags 2468 * 2469 * This function is used by master to get topology information for the 2470 * clock specified by given clock ID. Each response would return 3 2471 * topology nodes. To get next nodes, caller needs to call this API with 2472 * index of next node. Index starts from 0. 2473 * 2474 * @return Returns status, either success or error+reason 2475 */ 2476 enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, 2477 unsigned int index, 2478 uint32_t *topology) 2479 { 2480 struct pm_clock_node *clock_nodes; 2481 uint8_t num_nodes; 2482 unsigned int i; 2483 uint16_t typeflags; 2484 2485 if (!pm_clock_valid(clock_id)) 2486 return PM_RET_ERROR_ARGS; 2487 2488 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2489 return PM_RET_ERROR_NOTSUPPORTED; 2490 2491 2492 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN); 2493 clock_nodes = *clocks[clock_id].nodes; 2494 num_nodes = clocks[clock_id].num_nodes; 2495 2496 /* Skip parent till index */ 2497 if (index >= num_nodes) 2498 return PM_RET_SUCCESS; 2499 2500 for (i = 0; i < 3U; i++) { 2501 if ((index + i) == num_nodes) 2502 break; 2503 topology[i] = clock_nodes[index + i].type; 2504 topology[i] |= clock_nodes[index + i].clkflags << 2505 CLK_CLKFLAGS_SHIFT; 2506 typeflags = clock_nodes[index + i].typeflags; 2507 topology[i] |= (typeflags & CLK_TYPEFLAGS_BITS_MASK) << 2508 CLK_TYPEFLAGS_SHIFT; 2509 topology[i] |= (typeflags & CLK_TYPEFLAGS2_BITS_MASK) >> 2510 (CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT); 2511 } 2512 2513 return PM_RET_SUCCESS; 2514 } 2515 2516 /** 2517 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed 2518 * factor parameters for fixed clock 2519 * @clock_id Clock ID 2520 * @mul Multiplication value 2521 * @div Divisor value 2522 * 2523 * This function is used by master to get fixed factor parameers for the 2524 * fixed clock. This API is application only for the fixed clock. 2525 * 2526 * @return Returns status, either success or error+reason 2527 */ 2528 enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id, 2529 uint32_t *mul, 2530 uint32_t *div) 2531 { 2532 struct pm_clock_node *clock_nodes; 2533 uint8_t num_nodes; 2534 unsigned int type, i; 2535 2536 if (!pm_clock_valid(clock_id)) 2537 return PM_RET_ERROR_ARGS; 2538 2539 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2540 return PM_RET_ERROR_NOTSUPPORTED; 2541 2542 clock_nodes = *clocks[clock_id].nodes; 2543 num_nodes = clocks[clock_id].num_nodes; 2544 2545 for (i = 0; i < num_nodes; i++) { 2546 type = clock_nodes[i].type; 2547 if (type == TYPE_FIXEDFACTOR) { 2548 *mul = clock_nodes[i].mult; 2549 *div = clock_nodes[i].div; 2550 break; 2551 } 2552 } 2553 2554 /* Clock is not fixed clock */ 2555 if (i == num_nodes) 2556 return PM_RET_ERROR_ARGS; 2557 2558 return PM_RET_SUCCESS; 2559 } 2560 2561 /** 2562 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents 2563 * @clock_id Clock ID 2564 * @index Index of next parent 2565 * @parents Parents of the given clock 2566 * 2567 * This function is used by master to get clock's parents information. 2568 * This API will return 3 parents with a single response. To get other 2569 * parents, master should call same API in loop with new parent index 2570 * till error is returned. 2571 * 2572 * E.g First call should have index 0 which will return parents 0, 1 and 2573 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and 2574 * so on. 2575 * 2576 * @return Returns status, either success or error+reason 2577 */ 2578 enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, 2579 unsigned int index, 2580 uint32_t *parents) 2581 { 2582 unsigned int i; 2583 int32_t *clk_parents; 2584 2585 if (!pm_clock_valid(clock_id)) 2586 return PM_RET_ERROR_ARGS; 2587 2588 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2589 return PM_RET_ERROR_NOTSUPPORTED; 2590 2591 clk_parents = *clocks[clock_id].parents; 2592 if (clk_parents == NULL) 2593 return PM_RET_ERROR_ARGS; 2594 2595 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN); 2596 2597 /* Skip parent till index */ 2598 for (i = 0; i < index; i++) 2599 if (clk_parents[i] == CLK_NA_PARENT) 2600 return PM_RET_SUCCESS; 2601 2602 for (i = 0; i < 3; i++) { 2603 parents[i] = clk_parents[index + i]; 2604 if (clk_parents[index + i] == CLK_NA_PARENT) 2605 break; 2606 } 2607 2608 return PM_RET_SUCCESS; 2609 } 2610 2611 /** 2612 * pm_api_clock_get_attributes() - PM call to request a clock's attributes 2613 * @clock_id Clock ID 2614 * @attr Clock attributes 2615 * 2616 * This function is used by master to get clock's attributes 2617 * (e.g. valid, clock type, etc). 2618 * 2619 * @return Returns status, either success or error+reason 2620 */ 2621 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, 2622 uint32_t *attr) 2623 { 2624 if (clock_id >= CLK_MAX) 2625 return PM_RET_ERROR_ARGS; 2626 2627 /* Clock valid bit */ 2628 *attr = pm_clock_valid(clock_id); 2629 2630 /* Clock type (Output/External) */ 2631 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT); 2632 2633 return PM_RET_SUCCESS; 2634 } 2635 2636 /** 2637 * pm_api_clock_get_max_divisor - PM call to get max divisor 2638 * @clock_id Clock ID 2639 * @div_type Divisor Type (TYPE_DIV1 or TYPE_DIV2) 2640 * @max_div Maximum supported divisor 2641 * 2642 * This function is used by master to get maximum supported value. 2643 * 2644 * Return: Returns status, either success or error+reason. 2645 */ 2646 enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id, 2647 uint8_t div_type, 2648 uint32_t *max_div) 2649 { 2650 uint32_t i; 2651 struct pm_clock_node *nodes; 2652 2653 if (clock_id >= CLK_MAX_OUTPUT_CLK) 2654 return PM_RET_ERROR_ARGS; 2655 2656 nodes = *clocks[clock_id].nodes; 2657 for (i = 0; i < clocks[clock_id].num_nodes; i++) { 2658 if (nodes[i].type == div_type) { 2659 if (CLK_DIVIDER_POWER_OF_TWO & 2660 nodes[i].typeflags) { 2661 *max_div = (1 << (BIT(nodes[i].width) - 1)); 2662 } else { 2663 *max_div = BIT(nodes[i].width) - 1; 2664 } 2665 return PM_RET_SUCCESS; 2666 } 2667 } 2668 2669 return PM_RET_ERROR_ARGS; 2670 } 2671 2672 /** 2673 * struct pm_pll - PLL related data required to map IOCTL-based PLL control 2674 * implemented by linux to system-level EEMI APIs 2675 * @nid: PLL node ID 2676 * @cid: PLL clock ID 2677 * @pre_src: Pre-source PLL clock ID 2678 * @post_src: Post-source PLL clock ID 2679 * @div2: DIV2 PLL clock ID 2680 * @bypass: PLL output clock ID that maps to bypass select output 2681 * @mode: PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE) 2682 */ 2683 struct pm_pll { 2684 const enum pm_node_id nid; 2685 const enum clock_id cid; 2686 const enum clock_id pre_src; 2687 const enum clock_id post_src; 2688 const enum clock_id div2; 2689 const enum clock_id bypass; 2690 uint8_t mode; 2691 }; 2692 2693 static struct pm_pll pm_plls[] = { 2694 { 2695 .nid = NODE_IOPLL, 2696 .cid = CLK_IOPLL_INT, 2697 .pre_src = CLK_IOPLL_PRE_SRC, 2698 .post_src = CLK_IOPLL_POST_SRC, 2699 .div2 = CLK_IOPLL_INT_MUX, 2700 .bypass = CLK_IOPLL, 2701 }, { 2702 .nid = NODE_RPLL, 2703 .cid = CLK_RPLL_INT, 2704 .pre_src = CLK_RPLL_PRE_SRC, 2705 .post_src = CLK_RPLL_POST_SRC, 2706 .div2 = CLK_RPLL_INT_MUX, 2707 .bypass = CLK_RPLL, 2708 }, { 2709 .nid = NODE_APLL, 2710 .cid = CLK_APLL_INT, 2711 .pre_src = CLK_APLL_PRE_SRC, 2712 .post_src = CLK_APLL_POST_SRC, 2713 .div2 = CLK_APLL_INT_MUX, 2714 .bypass = CLK_APLL, 2715 }, { 2716 .nid = NODE_VPLL, 2717 .cid = CLK_VPLL_INT, 2718 .pre_src = CLK_VPLL_PRE_SRC, 2719 .post_src = CLK_VPLL_POST_SRC, 2720 .div2 = CLK_VPLL_INT_MUX, 2721 .bypass = CLK_VPLL, 2722 }, { 2723 .nid = NODE_DPLL, 2724 .cid = CLK_DPLL_INT, 2725 .pre_src = CLK_DPLL_PRE_SRC, 2726 .post_src = CLK_DPLL_POST_SRC, 2727 .div2 = CLK_DPLL_INT_MUX, 2728 .bypass = CLK_DPLL, 2729 }, 2730 }; 2731 2732 /** 2733 * pm_clock_get_pll() - Get PLL structure by PLL clock ID 2734 * @clock_id Clock ID of the target PLL 2735 * 2736 * @return Pointer to PLL structure if found, NULL otherwise 2737 */ 2738 struct pm_pll *pm_clock_get_pll(enum clock_id clock_id) 2739 { 2740 uint32_t i; 2741 2742 for (i = 0; i < ARRAY_SIZE(pm_plls); i++) { 2743 if (pm_plls[i].cid == clock_id) 2744 return &pm_plls[i]; 2745 } 2746 2747 return NULL; 2748 } 2749 2750 /** 2751 * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID 2752 * @clock_id Clock ID of the target PLL 2753 * @node_id Location to store node ID of the target PLL 2754 * 2755 * @return PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise 2756 */ 2757 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id, 2758 enum pm_node_id *node_id) 2759 { 2760 struct pm_pll *pll = pm_clock_get_pll(clock_id); 2761 2762 if (pll) { 2763 *node_id = pll->nid; 2764 return PM_RET_SUCCESS; 2765 } 2766 2767 return PM_RET_ERROR_ARGS; 2768 } 2769 2770 /** 2771 * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock ID 2772 * @clock_id Clock ID 2773 * 2774 * @return Pointer to PLL structure if found, NULL otherwise 2775 */ 2776 struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id) 2777 { 2778 uint32_t i; 2779 2780 for (i = 0; i < ARRAY_SIZE(pm_plls); i++) { 2781 if (pm_plls[i].pre_src == clock_id || 2782 pm_plls[i].post_src == clock_id || 2783 pm_plls[i].div2 == clock_id || 2784 pm_plls[i].bypass == clock_id) { 2785 return &pm_plls[i]; 2786 } 2787 } 2788 2789 return NULL; 2790 } 2791 2792 /** 2793 * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL) 2794 * @pll: PLL to be locked 2795 * 2796 * This function is used to map IOCTL/linux-based PLL handling to system-level 2797 * EEMI APIs 2798 * 2799 * Return: Error if the argument is not valid or status as returned by PMU 2800 */ 2801 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll) 2802 { 2803 if (!pll) 2804 return PM_RET_ERROR_ARGS; 2805 2806 /* Set the PLL mode according to the buffered mode value */ 2807 if (pll->mode == PLL_FRAC_MODE) 2808 return pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL); 2809 2810 return pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER); 2811 } 2812 2813 /** 2814 * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL) 2815 * @pll PLL to be bypassed/reset 2816 * 2817 * This function is used to map IOCTL/linux-based PLL handling to system-level 2818 * EEMI APIs 2819 * 2820 * Return: Error if the argument is not valid or status as returned by PMU 2821 */ 2822 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll) 2823 { 2824 if (!pll) 2825 return PM_RET_ERROR_ARGS; 2826 2827 return pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET); 2828 } 2829 2830 /** 2831 * pm_clock_pll_get_state - Get state of the PLL 2832 * @pll Pointer to the target PLL structure 2833 * @state Location to store the state: 1/0 ("Enabled"/"Disabled") 2834 * 2835 * "Enable" actually means that the PLL is locked and its bypass is deasserted, 2836 * "Disable" means that it is bypassed. 2837 * 2838 * Return: PM_RET_ERROR_ARGS error if the argument is not valid, success if 2839 * returned state value is valid or an error if returned by PMU 2840 */ 2841 enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll, 2842 unsigned int *state) 2843 { 2844 enum pm_ret_status status; 2845 enum pm_pll_mode mode; 2846 2847 if (!pll || !state) 2848 return PM_RET_ERROR_ARGS; 2849 2850 status = pm_pll_get_mode(pll->nid, &mode); 2851 if (status != PM_RET_SUCCESS) 2852 return status; 2853 2854 if (mode == PM_PLL_MODE_RESET) 2855 *state = 0; 2856 else 2857 *state = 1; 2858 2859 return PM_RET_SUCCESS; 2860 } 2861 2862 /** 2863 * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id 2864 * @pll Target PLL structure 2865 * @clock_id Id of the clock 2866 * @parent_index parent index (=mux select value) 2867 * 2868 * The whole clock-tree implementation relies on the fact that parent indexes 2869 * match to the multiplexer select values. This function has to rely on that 2870 * assumption as well => parent_index is actually the mux select value. 2871 * 2872 * Return: Returns status, either success or error+reason. 2873 */ 2874 enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll, 2875 enum clock_id clock_id, 2876 unsigned int parent_index) 2877 { 2878 if (!pll) 2879 return PM_RET_ERROR_ARGS; 2880 if (pll->pre_src == clock_id) 2881 return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC, 2882 parent_index); 2883 if (pll->post_src == clock_id) 2884 return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC, 2885 parent_index); 2886 if (pll->div2 == clock_id) 2887 return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2, 2888 parent_index); 2889 2890 return PM_RET_ERROR_ARGS; 2891 } 2892 2893 /** 2894 * pm_clock_pll_get_parent - Get mux select value of PLL-related clock parent 2895 * @pll Target PLL structure 2896 * @clock_id Id of the clock 2897 * @parent_index parent index (=mux select value) 2898 * 2899 * This function is used by master to get parent index for PLL-related clock. 2900 * 2901 * Return: Returns status, either success or error+reason. 2902 */ 2903 enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll, 2904 enum clock_id clock_id, 2905 unsigned int *parent_index) 2906 { 2907 if (!pll) 2908 return PM_RET_ERROR_ARGS; 2909 if (pll->pre_src == clock_id) 2910 return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC, 2911 parent_index); 2912 if (pll->post_src == clock_id) 2913 return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC, 2914 parent_index); 2915 if (pll->div2 == clock_id) 2916 return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2, 2917 parent_index); 2918 if (pll->bypass == clock_id) { 2919 *parent_index = 0; 2920 return PM_RET_SUCCESS; 2921 } 2922 2923 return PM_RET_ERROR_ARGS; 2924 } 2925 2926 /** 2927 * pm_clock_set_pll_mode() - Set PLL mode 2928 * @clock_id PLL clock id 2929 * @mode Mode fractional/integer 2930 * 2931 * This function buffers/saves the PLL mode that is set. 2932 * 2933 * @return Success if mode is buffered or error if an argument is invalid 2934 */ 2935 enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id, 2936 unsigned int mode) 2937 { 2938 struct pm_pll *pll = pm_clock_get_pll(clock_id); 2939 2940 if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) 2941 return PM_RET_ERROR_ARGS; 2942 pll->mode = mode; 2943 2944 return PM_RET_SUCCESS; 2945 } 2946 2947 /** 2948 * pm_clock_get_pll_mode() - Get PLL mode 2949 * @clock_id PLL clock id 2950 * @mode Location to store the mode (fractional/integer) 2951 * 2952 * This function returns buffered PLL mode. 2953 * 2954 * @return Success if mode is stored or error if an argument is invalid 2955 */ 2956 enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id, 2957 unsigned int *mode) 2958 { 2959 struct pm_pll *pll = pm_clock_get_pll(clock_id); 2960 2961 if (!pll || !mode) 2962 return PM_RET_ERROR_ARGS; 2963 *mode = pll->mode; 2964 2965 return PM_RET_SUCCESS; 2966 } 2967 2968 /** 2969 * pm_clock_id_is_valid() - Check if given clock ID is valid 2970 * @clock_id ID of the clock to be checked 2971 * 2972 * @return Returns success if clock_id is valid, otherwise an error 2973 */ 2974 enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id) 2975 { 2976 if (!pm_clock_valid(clock_id)) 2977 return PM_RET_ERROR_ARGS; 2978 2979 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2980 return PM_RET_ERROR_NOTSUPPORTED; 2981 2982 return PM_RET_SUCCESS; 2983 } 2984 2985 /** 2986 * pm_clock_has_div() - Check if the clock has divider with given ID 2987 * @clock_id Clock ID 2988 * @div_id Divider ID 2989 * 2990 * @return True(1)=clock has the divider, false(0)=otherwise 2991 */ 2992 uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id) 2993 { 2994 uint32_t i; 2995 struct pm_clock_node *nodes; 2996 2997 if (clock_id >= CLK_MAX_OUTPUT_CLK) 2998 return 0; 2999 3000 nodes = *clocks[clock_id].nodes; 3001 for (i = 0; i < clocks[clock_id].num_nodes; i++) { 3002 if (nodes[i].type == TYPE_DIV1) { 3003 if (div_id == PM_CLOCK_DIV0_ID) 3004 return 1; 3005 } else if (nodes[i].type == TYPE_DIV2) { 3006 if (div_id == PM_CLOCK_DIV1_ID) 3007 return 1; 3008 } 3009 } 3010 3011 return 0; 3012 } 3013