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