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