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