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