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