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