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 .type = TYPE_GATE, 337 .offset = PERIPH_GATE_SHIFT, 338 .width = PERIPH_GATE_WIDTH, 339 .clkflags = CLK_SET_RATE_PARENT | 340 CLK_IGNORE_UNUSED | 341 CLK_IS_BASIC | 342 CLK_IS_CRITICAL, 343 .typeflags = NA_TYPE_FLAGS, 344 .mult = NA_MULT, 345 .div = NA_DIV, 346 }, 347 }; 348 349 static struct pm_clock_node generic_mux_div_nodes[] = { 350 GENERIC_MUX, 351 GENERIC_DIV(1), 352 }; 353 354 static struct pm_clock_node generic_mux_div_gate_nodes[] = { 355 GENERIC_MUX, 356 GENERIC_DIV(1), 357 GENERIC_GATE, 358 }; 359 360 static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = { 361 GENERIC_MUX, 362 GENERIC_DIV(1), 363 IGNORE_UNUSED_GATE, 364 }; 365 366 static struct pm_clock_node generic_mux_div_div_gate_nodes[] = { 367 GENERIC_MUX, 368 GENERIC_DIV(1), 369 GENERIC_DIV(2), 370 GENERIC_GATE, 371 }; 372 373 static struct pm_clock_node dp_audio_video_ref_nodes[] = { 374 { 375 .type = TYPE_MUX, 376 .offset = PERIPH_MUX_SHIFT, 377 .width = PERIPH_MUX_WIDTH, 378 .clkflags = CLK_SET_RATE_NO_REPARENT | 379 CLK_SET_RATE_PARENT | 380 CLK_FRAC | CLK_IS_BASIC, 381 .typeflags = NA_TYPE_FLAGS, 382 .mult = NA_MULT, 383 .div = NA_DIV, 384 }, 385 { 386 .type = TYPE_DIV1, 387 .offset = PERIPH_DIV1_SHIFT, 388 .width = PERIPH_DIV1_WIDTH, 389 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT | 390 CLK_FRAC | CLK_IS_BASIC, 391 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 392 .mult = NA_MULT, 393 .div = NA_DIV, 394 }, 395 { 396 .type = TYPE_DIV2, 397 .offset = PERIPH_DIV2_SHIFT, 398 .width = PERIPH_DIV2_WIDTH, 399 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT | 400 CLK_FRAC | CLK_IS_BASIC, 401 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 402 .mult = NA_MULT, 403 .div = NA_DIV, 404 }, 405 { 406 .type = TYPE_GATE, 407 .offset = PERIPH_GATE_SHIFT, 408 .width = PERIPH_GATE_WIDTH, 409 .clkflags = CLK_SET_RATE_PARENT | 410 CLK_SET_RATE_GATE | 411 CLK_IS_BASIC, 412 .typeflags = NA_TYPE_FLAGS, 413 .mult = NA_MULT, 414 .div = NA_DIV, 415 }, 416 }; 417 418 static struct pm_clock_node usb_nodes[] = { 419 GENERIC_MUX, 420 GENERIC_DIV(1), 421 GENERIC_DIV(2), 422 { 423 .type = TYPE_GATE, 424 .offset = USB_GATE_SHIFT, 425 .width = PERIPH_GATE_WIDTH, 426 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC | 427 CLK_SET_RATE_GATE, 428 .typeflags = NA_TYPE_FLAGS, 429 .mult = NA_MULT, 430 .div = NA_DIV, 431 }, 432 }; 433 434 static struct pm_clock_node generic_domain_crossing_nodes[] = { 435 { 436 .type = TYPE_DIV1, 437 .offset = 8, 438 .width = 6, 439 .clkflags = 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 rpll_to_fpd_nodes[] = { 447 { 448 .type = TYPE_DIV1, 449 .offset = 8, 450 .width = 6, 451 .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, 452 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 453 .mult = NA_MULT, 454 .div = NA_DIV, 455 }, 456 }; 457 458 static struct pm_clock_node acpu_half_nodes[] = { 459 { 460 .type = TYPE_FIXEDFACTOR, 461 .offset = 0, 462 .width = 1, 463 .clkflags = 0, 464 .typeflags = 0, 465 .mult = 1, 466 .div = 2, 467 }, 468 { 469 .type = TYPE_GATE, 470 .offset = 25, 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_DBG_TRACE] = { 1211 .name = "dbg_trace", 1212 .control_reg = CRF_APB_DBG_TRACE_CTRL, 1213 .status_reg = 0, 1214 .parents = &((int32_t []) { 1215 CLK_IOPLL_TO_FPD, 1216 CLK_DUMMY_PARENT, 1217 CLK_DPLL, 1218 CLK_APLL, 1219 CLK_NA_PARENT 1220 }), 1221 .nodes = &generic_mux_div_gate_nodes, 1222 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1223 }, 1224 [CLK_DBG_FPD] = { 1225 .name = "dbg_fpd", 1226 .control_reg = CRF_APB_DBG_FPD_CTRL, 1227 .status_reg = 0, 1228 .parents = &((int32_t []) { 1229 CLK_IOPLL_TO_FPD, 1230 CLK_DUMMY_PARENT, 1231 CLK_DPLL, 1232 CLK_APLL, 1233 CLK_NA_PARENT 1234 }), 1235 .nodes = &generic_mux_div_gate_nodes, 1236 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1237 }, 1238 [CLK_DBG_TSTMP] = { 1239 .name = "dbg_tstmp", 1240 .control_reg = CRF_APB_DBG_TSTMP_CTRL, 1241 .status_reg = 0, 1242 .parents = &((int32_t []) { 1243 CLK_IOPLL_TO_FPD, 1244 CLK_DUMMY_PARENT, 1245 CLK_DPLL, 1246 CLK_APLL, 1247 CLK_NA_PARENT 1248 }), 1249 .nodes = &generic_mux_div_nodes, 1250 .num_nodes = ARRAY_SIZE(generic_mux_div_nodes), 1251 }, 1252 [CLK_DP_VIDEO_REF] = { 1253 .name = "dp_video_ref", 1254 .control_reg = CRF_APB_DP_VIDEO_REF_CTRL, 1255 .status_reg = 0, 1256 .parents = &((int32_t []) { 1257 CLK_VPLL, 1258 CLK_DUMMY_PARENT, 1259 CLK_DPLL, 1260 CLK_RPLL_TO_FPD, 1261 CLK_NA_PARENT 1262 }), 1263 .nodes = &dp_audio_video_ref_nodes, 1264 .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes), 1265 }, 1266 [CLK_DP_AUDIO_REF] = { 1267 .name = "dp_audio_ref", 1268 .control_reg = CRF_APB_DP_AUDIO_REF_CTRL, 1269 .status_reg = 0, 1270 .parents = &((int32_t []) { 1271 CLK_VPLL, 1272 CLK_DUMMY_PARENT, 1273 CLK_DPLL, 1274 CLK_RPLL_TO_FPD, 1275 CLK_NA_PARENT 1276 }), 1277 .nodes = &dp_audio_video_ref_nodes, 1278 .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes), 1279 }, 1280 [CLK_DP_STC_REF] = { 1281 .name = "dp_stc_ref", 1282 .control_reg = CRF_APB_DP_STC_REF_CTRL, 1283 .status_reg = 0, 1284 .parents = &((int32_t []) { 1285 CLK_VPLL, 1286 CLK_DUMMY_PARENT, 1287 CLK_DPLL, 1288 CLK_RPLL_TO_FPD, 1289 CLK_NA_PARENT 1290 }), 1291 .nodes = &generic_mux_div_div_gate_nodes, 1292 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1293 }, 1294 [CLK_DPDMA_REF] = { 1295 .name = "dpdma_ref", 1296 .control_reg = CRF_APB_DPDMA_REF_CTRL, 1297 .status_reg = 0, 1298 .parents = &((int32_t []) { 1299 CLK_APLL, 1300 CLK_DUMMY_PARENT, 1301 CLK_VPLL, 1302 CLK_DPLL, 1303 CLK_NA_PARENT 1304 }), 1305 .nodes = &generic_mux_div_gate_nodes, 1306 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1307 }, 1308 [CLK_DDR_REF] = { 1309 .name = "ddr_ref", 1310 .control_reg = CRF_APB_DDR_CTRL, 1311 .status_reg = 0, 1312 .parents = &((int32_t []) { 1313 CLK_DPLL, 1314 CLK_VPLL, 1315 CLK_NA_PARENT 1316 }), 1317 .nodes = &ddr_nodes, 1318 .num_nodes = ARRAY_SIZE(ddr_nodes), 1319 }, 1320 [CLK_GPU_REF] = { 1321 .name = "gpu_ref", 1322 .control_reg = CRF_APB_GPU_REF_CTRL, 1323 .status_reg = 0, 1324 .parents = &((int32_t []) { 1325 CLK_IOPLL_TO_FPD, 1326 CLK_DUMMY_PARENT, 1327 CLK_VPLL, 1328 CLK_DPLL, 1329 CLK_NA_PARENT 1330 }), 1331 .nodes = &generic_mux_div_gate_nodes, 1332 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1333 }, 1334 [CLK_SATA_REF] = { 1335 .name = "sata_ref", 1336 .control_reg = CRF_APB_SATA_REF_CTRL, 1337 .status_reg = 0, 1338 .parents = &((int32_t []) { 1339 CLK_IOPLL_TO_FPD, 1340 CLK_DUMMY_PARENT, 1341 CLK_APLL, 1342 CLK_DPLL, 1343 CLK_NA_PARENT 1344 }), 1345 .nodes = &generic_mux_div_gate_nodes, 1346 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1347 }, 1348 [CLK_PCIE_REF] = { 1349 .name = "pcie_ref", 1350 .control_reg = CRF_APB_PCIE_REF_CTRL, 1351 .status_reg = 0, 1352 .parents = &((int32_t []) { 1353 CLK_IOPLL_TO_FPD, 1354 CLK_DUMMY_PARENT, 1355 CLK_RPLL_TO_FPD, 1356 CLK_DPLL, 1357 CLK_NA_PARENT 1358 }), 1359 .nodes = &generic_mux_div_gate_nodes, 1360 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1361 }, 1362 [CLK_GDMA_REF] = { 1363 .name = "gdma_ref", 1364 .control_reg = CRF_APB_GDMA_REF_CTRL, 1365 .status_reg = 0, 1366 .parents = &((int32_t []) { 1367 CLK_APLL, 1368 CLK_DUMMY_PARENT, 1369 CLK_VPLL, 1370 CLK_DPLL, 1371 CLK_NA_PARENT 1372 }), 1373 .nodes = &generic_mux_div_gate_nodes, 1374 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1375 }, 1376 [CLK_GTGREF0_REF] = { 1377 .name = "gtgref0_ref", 1378 .control_reg = CRF_APB_GTGREF0_REF_CTRL, 1379 .status_reg = 0, 1380 .parents = &((int32_t []) { 1381 CLK_IOPLL_TO_FPD, 1382 CLK_DUMMY_PARENT, 1383 CLK_APLL, 1384 CLK_DPLL, 1385 CLK_NA_PARENT 1386 }), 1387 .nodes = &generic_mux_div_gate_nodes, 1388 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1389 }, 1390 [CLK_TOPSW_MAIN] = { 1391 .name = "topsw_main", 1392 .control_reg = CRF_APB_TOPSW_MAIN_CTRL, 1393 .status_reg = 0, 1394 .parents = &((int32_t []) { 1395 CLK_APLL, 1396 CLK_DUMMY_PARENT, 1397 CLK_VPLL, 1398 CLK_DPLL, 1399 CLK_NA_PARENT 1400 }), 1401 .nodes = &generic_mux_div_unused_gate_nodes, 1402 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1403 }, 1404 [CLK_TOPSW_LSBUS] = { 1405 .name = "topsw_lsbus", 1406 .control_reg = CRF_APB_TOPSW_LSBUS_CTRL, 1407 .status_reg = 0, 1408 .parents = &((int32_t []) { 1409 CLK_APLL, 1410 CLK_DUMMY_PARENT, 1411 CLK_IOPLL_TO_FPD, 1412 CLK_DPLL, 1413 CLK_NA_PARENT 1414 }), 1415 .nodes = &generic_mux_div_unused_gate_nodes, 1416 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1417 }, 1418 [CLK_IOU_SWITCH] = { 1419 .name = "iou_switch", 1420 .control_reg = CRL_APB_IOU_SWITCH_CTRL, 1421 .status_reg = 0, 1422 .parents = &((int32_t []) { 1423 CLK_RPLL, 1424 CLK_DUMMY_PARENT, 1425 CLK_IOPLL, 1426 CLK_DPLL_TO_LPD, 1427 CLK_NA_PARENT 1428 }), 1429 .nodes = &generic_mux_div_unused_gate_nodes, 1430 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1431 }, 1432 [CLK_GEM0_REF] = { 1433 .name = "gem0_ref", 1434 .control_reg = CRL_APB_GEM0_REF_CTRL, 1435 .status_reg = 0, 1436 .parents = &((int32_t []) { 1437 CLK_IOPLL, 1438 CLK_DUMMY_PARENT, 1439 CLK_RPLL, 1440 CLK_DPLL_TO_LPD, 1441 CLK_NA_PARENT 1442 }), 1443 .nodes = &gem_nodes, 1444 .num_nodes = ARRAY_SIZE(gem_nodes), 1445 }, 1446 [CLK_GEM1_REF] = { 1447 .name = "gem1_ref", 1448 .control_reg = CRL_APB_GEM1_REF_CTRL, 1449 .status_reg = 0, 1450 .parents = &((int32_t []) { 1451 CLK_IOPLL, 1452 CLK_DUMMY_PARENT, 1453 CLK_RPLL, 1454 CLK_DPLL_TO_LPD, 1455 CLK_NA_PARENT 1456 }), 1457 .nodes = &gem_nodes, 1458 .num_nodes = ARRAY_SIZE(gem_nodes), 1459 }, 1460 [CLK_GEM2_REF] = { 1461 .name = "gem2_ref", 1462 .control_reg = CRL_APB_GEM2_REF_CTRL, 1463 .status_reg = 0, 1464 .parents = &((int32_t []) { 1465 CLK_IOPLL, 1466 CLK_DUMMY_PARENT, 1467 CLK_RPLL, 1468 CLK_DPLL_TO_LPD, 1469 CLK_NA_PARENT 1470 }), 1471 .nodes = &gem_nodes, 1472 .num_nodes = ARRAY_SIZE(gem_nodes), 1473 }, 1474 [CLK_GEM3_REF] = { 1475 .name = "gem3_ref", 1476 .control_reg = CRL_APB_GEM3_REF_CTRL, 1477 .status_reg = 0, 1478 .parents = &((int32_t []) { 1479 CLK_IOPLL, 1480 CLK_DUMMY_PARENT, 1481 CLK_RPLL, 1482 CLK_DPLL_TO_LPD, 1483 CLK_NA_PARENT 1484 }), 1485 .nodes = &gem_nodes, 1486 .num_nodes = ARRAY_SIZE(gem_nodes), 1487 }, 1488 [CLK_USB0_BUS_REF] = { 1489 .name = "usb0_bus_ref", 1490 .control_reg = CRL_APB_USB0_BUS_REF_CTRL, 1491 .status_reg = 0, 1492 .parents = &((int32_t []) { 1493 CLK_IOPLL, 1494 CLK_DUMMY_PARENT, 1495 CLK_RPLL, 1496 CLK_DPLL_TO_LPD, 1497 CLK_NA_PARENT 1498 }), 1499 .nodes = &usb_nodes, 1500 .num_nodes = ARRAY_SIZE(usb_nodes), 1501 }, 1502 [CLK_USB1_BUS_REF] = { 1503 .name = "usb1_bus_ref", 1504 .control_reg = CRL_APB_USB1_BUS_REF_CTRL, 1505 .status_reg = 0, 1506 .parents = &((int32_t []) { 1507 CLK_IOPLL, 1508 CLK_DUMMY_PARENT, 1509 CLK_RPLL, 1510 CLK_DPLL_TO_LPD, 1511 CLK_NA_PARENT 1512 }), 1513 .nodes = &usb_nodes, 1514 .num_nodes = ARRAY_SIZE(usb_nodes), 1515 }, 1516 [CLK_USB3_DUAL_REF] = { 1517 .name = "usb3_dual_ref", 1518 .control_reg = CRL_APB_USB3_DUAL_REF_CTRL, 1519 .status_reg = 0, 1520 .parents = &((int32_t []) { 1521 CLK_IOPLL, 1522 CLK_DUMMY_PARENT, 1523 CLK_RPLL, 1524 CLK_DPLL_TO_LPD, 1525 CLK_NA_PARENT 1526 }), 1527 .nodes = &usb_nodes, 1528 .num_nodes = ARRAY_SIZE(usb_nodes), 1529 }, 1530 [CLK_QSPI_REF] = { 1531 .name = "qspi_ref", 1532 .control_reg = CRL_APB_QSPI_REF_CTRL, 1533 .status_reg = 0, 1534 .parents = &((int32_t []) { 1535 CLK_IOPLL, 1536 CLK_DUMMY_PARENT, 1537 CLK_RPLL, 1538 CLK_DPLL_TO_LPD, 1539 CLK_NA_PARENT 1540 }), 1541 .nodes = &generic_mux_div_div_gate_nodes, 1542 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1543 }, 1544 [CLK_SDIO0_REF] = { 1545 .name = "sdio0_ref", 1546 .control_reg = CRL_APB_SDIO0_REF_CTRL, 1547 .status_reg = 0, 1548 .parents = &((int32_t []) { 1549 CLK_IOPLL, 1550 CLK_DUMMY_PARENT, 1551 CLK_RPLL, 1552 CLK_VPLL_TO_LPD, 1553 CLK_NA_PARENT 1554 }), 1555 .nodes = &generic_mux_div_div_gate_nodes, 1556 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1557 }, 1558 [CLK_SDIO1_REF] = { 1559 .name = "sdio1_ref", 1560 .control_reg = CRL_APB_SDIO1_REF_CTRL, 1561 .status_reg = 0, 1562 .parents = &((int32_t []) { 1563 CLK_IOPLL, 1564 CLK_DUMMY_PARENT, 1565 CLK_RPLL, 1566 CLK_VPLL_TO_LPD, 1567 CLK_NA_PARENT 1568 }), 1569 .nodes = &generic_mux_div_div_gate_nodes, 1570 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1571 }, 1572 [CLK_UART0_REF] = { 1573 .name = "uart0_ref", 1574 .control_reg = CRL_APB_UART0_REF_CTRL, 1575 .status_reg = 0, 1576 .parents = &((int32_t []) { 1577 CLK_IOPLL, 1578 CLK_DUMMY_PARENT, 1579 CLK_RPLL, 1580 CLK_DPLL_TO_LPD, 1581 CLK_NA_PARENT 1582 }), 1583 .nodes = &generic_mux_div_div_gate_nodes, 1584 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1585 }, 1586 [CLK_UART1_REF] = { 1587 .name = "uart1_ref", 1588 .control_reg = CRL_APB_UART1_REF_CTRL, 1589 .status_reg = 0, 1590 .parents = &((int32_t []) { 1591 CLK_IOPLL, 1592 CLK_DUMMY_PARENT, 1593 CLK_RPLL, 1594 CLK_DPLL_TO_LPD, 1595 CLK_NA_PARENT 1596 }), 1597 .nodes = &generic_mux_div_div_gate_nodes, 1598 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1599 }, 1600 [CLK_SPI0_REF] = { 1601 .name = "spi0_ref", 1602 .control_reg = CRL_APB_SPI0_REF_CTRL, 1603 .status_reg = 0, 1604 .parents = &((int32_t []) { 1605 CLK_IOPLL, 1606 CLK_DUMMY_PARENT, 1607 CLK_RPLL, 1608 CLK_DPLL_TO_LPD, 1609 CLK_NA_PARENT 1610 }), 1611 .nodes = &generic_mux_div_div_gate_nodes, 1612 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1613 }, 1614 [CLK_SPI1_REF] = { 1615 .name = "spi1_ref", 1616 .control_reg = CRL_APB_SPI1_REF_CTRL, 1617 .status_reg = 0, 1618 .parents = &((int32_t []) { 1619 CLK_IOPLL, 1620 CLK_DUMMY_PARENT, 1621 CLK_RPLL, 1622 CLK_DPLL_TO_LPD, 1623 CLK_NA_PARENT 1624 }), 1625 .nodes = &generic_mux_div_div_gate_nodes, 1626 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1627 }, 1628 [CLK_CAN0_REF] = { 1629 .name = "can0_ref", 1630 .control_reg = CRL_APB_CAN0_REF_CTRL, 1631 .status_reg = 0, 1632 .parents = &((int32_t []) { 1633 CLK_IOPLL, 1634 CLK_DUMMY_PARENT, 1635 CLK_RPLL, 1636 CLK_DPLL_TO_LPD, 1637 CLK_NA_PARENT 1638 }), 1639 .nodes = &generic_mux_div_div_gate_nodes, 1640 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1641 }, 1642 [CLK_CAN1_REF] = { 1643 .name = "can1_ref", 1644 .control_reg = CRL_APB_CAN1_REF_CTRL, 1645 .status_reg = 0, 1646 .parents = &((int32_t []) { 1647 CLK_IOPLL, 1648 CLK_DUMMY_PARENT, 1649 CLK_RPLL, 1650 CLK_DPLL_TO_LPD, 1651 CLK_NA_PARENT 1652 }), 1653 .nodes = &generic_mux_div_div_gate_nodes, 1654 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1655 }, 1656 [CLK_NAND_REF] = { 1657 .name = "nand_ref", 1658 .control_reg = CRL_APB_NAND_REF_CTRL, 1659 .status_reg = 0, 1660 .parents = &((int32_t []) { 1661 CLK_IOPLL, 1662 CLK_DUMMY_PARENT, 1663 CLK_RPLL, 1664 CLK_DPLL_TO_LPD, 1665 CLK_NA_PARENT 1666 }), 1667 .nodes = &generic_mux_div_div_gate_nodes, 1668 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1669 }, 1670 [CLK_GEM_TSU_REF] = { 1671 .name = "gem_tsu_ref", 1672 .control_reg = CRL_APB_GEM_TSU_REF_CTRL, 1673 .status_reg = 0, 1674 .parents = &((int32_t []) { 1675 CLK_IOPLL, 1676 CLK_DUMMY_PARENT, 1677 CLK_RPLL, 1678 CLK_DPLL_TO_LPD, 1679 CLK_NA_PARENT 1680 }), 1681 .nodes = &generic_mux_div_div_gate_nodes, 1682 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1683 }, 1684 [CLK_DLL_REF] = { 1685 .name = "dll_ref", 1686 .control_reg = CRL_APB_DLL_REF_CTRL, 1687 .status_reg = 0, 1688 .parents = &((int32_t []) { 1689 CLK_IOPLL, 1690 CLK_RPLL, 1691 CLK_NA_PARENT 1692 }), 1693 .nodes = &dll_ref_nodes, 1694 .num_nodes = ARRAY_SIZE(dll_ref_nodes), 1695 }, 1696 [CLK_ADMA_REF] = { 1697 .name = "adma_ref", 1698 .control_reg = CRL_APB_ADMA_REF_CTRL, 1699 .status_reg = 0, 1700 .parents = &((int32_t []) { 1701 CLK_RPLL, 1702 CLK_DUMMY_PARENT, 1703 CLK_IOPLL, 1704 CLK_DPLL_TO_LPD, 1705 CLK_NA_PARENT 1706 }), 1707 .nodes = &generic_mux_div_gate_nodes, 1708 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1709 }, 1710 [CLK_DBG_LPD] = { 1711 .name = "dbg_lpd", 1712 .control_reg = CRL_APB_DBG_LPD_CTRL, 1713 .status_reg = 0, 1714 .parents = &((int32_t []) { 1715 CLK_RPLL, 1716 CLK_DUMMY_PARENT, 1717 CLK_IOPLL, 1718 CLK_DPLL_TO_LPD, 1719 CLK_NA_PARENT 1720 }), 1721 .nodes = &generic_mux_div_gate_nodes, 1722 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1723 }, 1724 [CLK_CPU_R5] = { 1725 .name = "cpu_r5", 1726 .control_reg = CRL_APB_CPU_R5_CTRL, 1727 .status_reg = 0, 1728 .parents = &((int32_t []) { 1729 CLK_RPLL, 1730 CLK_DUMMY_PARENT, 1731 CLK_IOPLL, 1732 CLK_DPLL_TO_LPD, 1733 CLK_NA_PARENT 1734 }), 1735 .nodes = &generic_mux_div_unused_gate_nodes, 1736 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1737 }, 1738 [CLK_CSU_PLL] = { 1739 .name = "csu_pll", 1740 .control_reg = CRL_APB_CSU_PLL_CTRL, 1741 .status_reg = 0, 1742 .parents = &((int32_t []) { 1743 CLK_IOPLL, 1744 CLK_DUMMY_PARENT, 1745 CLK_RPLL, 1746 CLK_DPLL_TO_LPD, 1747 CLK_NA_PARENT 1748 }), 1749 .nodes = &generic_mux_div_gate_nodes, 1750 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1751 }, 1752 [CLK_PCAP] = { 1753 .name = "pcap", 1754 .control_reg = CRL_APB_PCAP_CTRL, 1755 .status_reg = 0, 1756 .parents = &((int32_t []) { 1757 CLK_IOPLL, 1758 CLK_DUMMY_PARENT, 1759 CLK_RPLL, 1760 CLK_DPLL_TO_LPD, 1761 CLK_NA_PARENT 1762 }), 1763 .nodes = &generic_mux_div_gate_nodes, 1764 .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes), 1765 }, 1766 [CLK_LPD_LSBUS] = { 1767 .name = "lpd_lsbus", 1768 .control_reg = CRL_APB_LPD_LSBUS_CTRL, 1769 .status_reg = 0, 1770 .parents = &((int32_t []) { 1771 CLK_RPLL, 1772 CLK_DUMMY_PARENT, 1773 CLK_IOPLL, 1774 CLK_DPLL_TO_LPD, 1775 CLK_NA_PARENT 1776 }), 1777 .nodes = &generic_mux_div_unused_gate_nodes, 1778 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1779 }, 1780 [CLK_LPD_SWITCH] = { 1781 .name = "lpd_switch", 1782 .control_reg = CRL_APB_LPD_SWITCH_CTRL, 1783 .status_reg = 0, 1784 .parents = &((int32_t []) { 1785 CLK_RPLL, 1786 CLK_DUMMY_PARENT, 1787 CLK_IOPLL, 1788 CLK_DPLL_TO_LPD, 1789 CLK_NA_PARENT 1790 }), 1791 .nodes = &generic_mux_div_unused_gate_nodes, 1792 .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), 1793 }, 1794 [CLK_I2C0_REF] = { 1795 .name = "i2c0_ref", 1796 .control_reg = CRL_APB_I2C0_REF_CTRL, 1797 .status_reg = 0, 1798 .parents = &((int32_t []) { 1799 CLK_IOPLL, 1800 CLK_DUMMY_PARENT, 1801 CLK_RPLL, 1802 CLK_DPLL_TO_LPD, 1803 CLK_NA_PARENT 1804 }), 1805 .nodes = &generic_mux_div_div_gate_nodes, 1806 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1807 }, 1808 [CLK_I2C1_REF] = { 1809 .name = "i2c1_ref", 1810 .control_reg = CRL_APB_I2C1_REF_CTRL, 1811 .status_reg = 0, 1812 .parents = &((int32_t []) { 1813 CLK_IOPLL, 1814 CLK_DUMMY_PARENT, 1815 CLK_RPLL, 1816 CLK_DPLL_TO_LPD, 1817 CLK_NA_PARENT 1818 }), 1819 .nodes = &generic_mux_div_div_gate_nodes, 1820 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1821 }, 1822 [CLK_TIMESTAMP_REF] = { 1823 .name = "timestamp_ref", 1824 .control_reg = CRL_APB_TIMESTAMP_REF_CTRL, 1825 .status_reg = 0, 1826 .parents = &((int32_t []) { 1827 CLK_IOPLL, 1828 CLK_DUMMY_PARENT, 1829 CLK_RPLL, 1830 CLK_DPLL_TO_LPD, 1831 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1832 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1833 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1834 EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT, 1835 CLK_NA_PARENT 1836 }), 1837 .nodes = ×tamp_ref_nodes, 1838 .num_nodes = ARRAY_SIZE(timestamp_ref_nodes), 1839 }, 1840 [CLK_PL0_REF] = { 1841 .name = "pl0_ref", 1842 .control_reg = CRL_APB_PL0_REF_CTRL, 1843 .status_reg = 0, 1844 .parents = &((int32_t []) { 1845 CLK_IOPLL, 1846 CLK_DUMMY_PARENT, 1847 CLK_RPLL, 1848 CLK_DPLL_TO_LPD, 1849 CLK_NA_PARENT 1850 }), 1851 .nodes = &pl_nodes, 1852 .num_nodes = ARRAY_SIZE(pl_nodes), 1853 }, 1854 [CLK_PL1_REF] = { 1855 .name = "pl1_ref", 1856 .control_reg = CRL_APB_PL1_REF_CTRL, 1857 .status_reg = 0, 1858 .parents = &((int32_t []) { 1859 CLK_IOPLL, 1860 CLK_DUMMY_PARENT, 1861 CLK_RPLL, 1862 CLK_DPLL_TO_LPD, 1863 CLK_NA_PARENT 1864 }), 1865 .nodes = &pl_nodes, 1866 .num_nodes = ARRAY_SIZE(pl_nodes), 1867 }, 1868 [CLK_PL2_REF] = { 1869 .name = "pl2_ref", 1870 .control_reg = CRL_APB_PL2_REF_CTRL, 1871 .status_reg = 0, 1872 .parents = &((int32_t []) { 1873 CLK_IOPLL, 1874 CLK_DUMMY_PARENT, 1875 CLK_RPLL, 1876 CLK_DPLL_TO_LPD, 1877 CLK_NA_PARENT 1878 }), 1879 .nodes = &pl_nodes, 1880 .num_nodes = ARRAY_SIZE(pl_nodes), 1881 }, 1882 [CLK_PL3_REF] = { 1883 .name = "pl3_ref", 1884 .control_reg = CRL_APB_PL3_REF_CTRL, 1885 .status_reg = 0, 1886 .parents = &((int32_t []) { 1887 CLK_IOPLL, 1888 CLK_DUMMY_PARENT, 1889 CLK_RPLL, 1890 CLK_DPLL_TO_LPD, 1891 CLK_NA_PARENT 1892 }), 1893 .nodes = &pl_nodes, 1894 .num_nodes = ARRAY_SIZE(pl_nodes), 1895 }, 1896 [CLK_AMS_REF] = { 1897 .name = "ams_ref", 1898 .control_reg = CRL_APB_AMS_REF_CTRL, 1899 .status_reg = 0, 1900 .parents = &((int32_t []) { 1901 CLK_RPLL, 1902 CLK_DUMMY_PARENT, 1903 CLK_IOPLL, 1904 CLK_DPLL_TO_LPD, 1905 CLK_NA_PARENT 1906 }), 1907 .nodes = &generic_mux_div_div_gate_nodes, 1908 .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes), 1909 }, 1910 [CLK_IOPLL_TO_FPD] = { 1911 .name = "iopll_to_fpd", 1912 .control_reg = CRL_APB_IOPLL_TO_FPD_CTRL, 1913 .status_reg = 0, 1914 .parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}), 1915 .nodes = &generic_domain_crossing_nodes, 1916 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 1917 }, 1918 [CLK_RPLL_TO_FPD] = { 1919 .name = "rpll_to_fpd", 1920 .control_reg = CRL_APB_RPLL_TO_FPD_CTRL, 1921 .status_reg = 0, 1922 .parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}), 1923 .nodes = &rpll_to_fpd_nodes, 1924 .num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes), 1925 }, 1926 [CLK_APLL_TO_LPD] = { 1927 .name = "apll_to_lpd", 1928 .control_reg = CRF_APB_APLL_TO_LPD_CTRL, 1929 .status_reg = 0, 1930 .parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}), 1931 .nodes = &generic_domain_crossing_nodes, 1932 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 1933 }, 1934 [CLK_DPLL_TO_LPD] = { 1935 .name = "dpll_to_lpd", 1936 .control_reg = CRF_APB_DPLL_TO_LPD_CTRL, 1937 .status_reg = 0, 1938 .parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}), 1939 .nodes = &generic_domain_crossing_nodes, 1940 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 1941 }, 1942 [CLK_VPLL_TO_LPD] = { 1943 .name = "vpll_to_lpd", 1944 .control_reg = CRF_APB_VPLL_TO_LPD_CTRL, 1945 .status_reg = 0, 1946 .parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}), 1947 .nodes = &generic_domain_crossing_nodes, 1948 .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), 1949 }, 1950 /* 1951 * This clock control requires different registers for mux and gate. 1952 * Use control and status registers for the same. 1953 */ 1954 [CLK_GEM0_TX] = { 1955 .name = "gem0_tx", 1956 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1957 .status_reg = CRL_APB_GEM0_REF_CTRL, 1958 .parents = &((int32_t []) { 1959 CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1960 EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT, 1961 CLK_NA_PARENT 1962 }), 1963 .nodes = &gem0_tx_nodes, 1964 .num_nodes = ARRAY_SIZE(gem0_tx_nodes), 1965 }, 1966 /* 1967 * This clock control requires different registers for mux and gate. 1968 * Use control and status registers for the same. 1969 */ 1970 [CLK_GEM1_TX] = { 1971 .name = "gem1_tx", 1972 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1973 .status_reg = CRL_APB_GEM1_REF_CTRL, 1974 .parents = &((int32_t []) { 1975 CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1976 EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT, 1977 CLK_NA_PARENT 1978 }), 1979 .nodes = &gem1_tx_nodes, 1980 .num_nodes = ARRAY_SIZE(gem1_tx_nodes), 1981 }, 1982 /* 1983 * This clock control requires different registers for mux and gate. 1984 * Use control and status registers for the same. 1985 */ 1986 [CLK_GEM2_TX] = { 1987 .name = "gem2_tx", 1988 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 1989 .status_reg = CRL_APB_GEM2_REF_CTRL, 1990 .parents = &((int32_t []) { 1991 CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 1992 EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT, 1993 CLK_NA_PARENT 1994 }), 1995 .nodes = &gem2_tx_nodes, 1996 .num_nodes = ARRAY_SIZE(gem2_tx_nodes), 1997 }, 1998 /* 1999 * This clock control requires different registers for mux and gate. 2000 * Use control and status registers for the same. 2001 */ 2002 [CLK_GEM3_TX] = { 2003 .name = "gem3_tx", 2004 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 2005 .status_reg = CRL_APB_GEM3_REF_CTRL, 2006 .parents = &((int32_t []) { 2007 CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), 2008 EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT, 2009 CLK_NA_PARENT 2010 }), 2011 .nodes = &gem3_tx_nodes, 2012 .num_nodes = ARRAY_SIZE(gem3_tx_nodes), 2013 }, 2014 [CLK_ACPU_HALF] = { 2015 .name = "acpu_half", 2016 .control_reg = CRF_APB_ACPU_CTRL, 2017 .status_reg = 0, 2018 .parents = &((int32_t []) { 2019 CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2020 CLK_NA_PARENT 2021 }), 2022 .nodes = &acpu_half_nodes, 2023 .num_nodes = ARRAY_SIZE(acpu_half_nodes), 2024 }, 2025 [CLK_WDT] = { 2026 .name = "wdt", 2027 .control_reg = FPD_SLCR_WDT_CLK_SEL, 2028 .status_reg = 0, 2029 .parents = &((int32_t []) { 2030 CLK_TOPSW_LSBUS, 2031 EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT, 2032 CLK_NA_PARENT 2033 }), 2034 .nodes = &wdt_nodes, 2035 .num_nodes = ARRAY_SIZE(wdt_nodes), 2036 }, 2037 [CLK_GPU_PP0_REF] = { 2038 .name = "gpu_pp0_ref", 2039 .control_reg = CRF_APB_GPU_REF_CTRL, 2040 .status_reg = 0, 2041 .parents = &((int32_t []) { 2042 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2043 CLK_NA_PARENT 2044 }), 2045 .nodes = &gpu_pp0_nodes, 2046 .num_nodes = ARRAY_SIZE(gpu_pp0_nodes), 2047 }, 2048 [CLK_GPU_PP1_REF] = { 2049 .name = "gpu_pp1_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_pp1_nodes, 2057 .num_nodes = ARRAY_SIZE(gpu_pp1_nodes), 2058 }, 2059 [CLK_GEM_TSU] = { 2060 .name = "gem_tsu", 2061 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 2062 .status_reg = 0, 2063 .parents = &((int32_t []) { 2064 CLK_GEM_TSU_REF, 2065 CLK_GEM_TSU_REF, 2066 EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT, 2067 EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT, 2068 CLK_NA_PARENT 2069 }), 2070 .nodes = &gem_tsu_nodes, 2071 .num_nodes = ARRAY_SIZE(gem_tsu_nodes), 2072 }, 2073 [CLK_CPU_R5_CORE] = { 2074 .name = "cpu_r5_core", 2075 .control_reg = CRL_APB_CPU_R5_CTRL, 2076 .status_reg = 0, 2077 .parents = &((int32_t []) { 2078 CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2079 CLK_DUMMY_PARENT, 2080 CLK_NA_PARENT 2081 }), 2082 .nodes = &cpu_r5_core_nodes, 2083 .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes), 2084 }, 2085 [CLK_CAN0_MIO] = { 2086 .name = "can0_mio", 2087 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2088 .status_reg = 0, 2089 .parents = &can_mio_parents, 2090 .nodes = &can0_mio_nodes, 2091 .num_nodes = ARRAY_SIZE(can0_mio_nodes), 2092 }, 2093 [CLK_CAN1_MIO] = { 2094 .name = "can1_mio", 2095 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2096 .status_reg = 0, 2097 .parents = &can_mio_parents, 2098 .nodes = &can1_mio_nodes, 2099 .num_nodes = ARRAY_SIZE(can1_mio_nodes), 2100 }, 2101 [CLK_CAN0] = { 2102 .name = "can0", 2103 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2104 .status_reg = 0, 2105 .parents = &((int32_t []) { 2106 CLK_CAN0_REF, 2107 CLK_CAN0_MIO, 2108 CLK_NA_PARENT 2109 }), 2110 .nodes = &can0_nodes, 2111 .num_nodes = ARRAY_SIZE(can0_nodes), 2112 }, 2113 [CLK_CAN1] = { 2114 .name = "can1", 2115 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2116 .status_reg = 0, 2117 .parents = &((int32_t []) { 2118 CLK_CAN1_REF, 2119 CLK_CAN1_MIO, 2120 CLK_NA_PARENT 2121 }), 2122 .nodes = &can1_nodes, 2123 .num_nodes = ARRAY_SIZE(can1_nodes), 2124 }, 2125 }; 2126 2127 static struct pm_ext_clock ext_clocks[] = { 2128 [EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = { 2129 .name = "pss_ref_clk", 2130 }, 2131 [EXT_CLK_INDEX(EXT_CLK_VIDEO)] = { 2132 .name = "video_clk", 2133 }, 2134 [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = { 2135 .name = "pss_alt_ref_clk", 2136 }, 2137 [EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = { 2138 .name = "aux_ref_clk", 2139 }, 2140 [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = { 2141 .name = "video_clk", 2142 }, 2143 [EXT_CLK_INDEX(EXT_CLK_SWDT0)] = { 2144 .name = "swdt0_ext_clk", 2145 }, 2146 [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = { 2147 .name = "swdt1_ext_clk", 2148 }, 2149 [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = { 2150 .name = "gem0_emio_clk", 2151 }, 2152 [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = { 2153 .name = "gem1_emio_clk", 2154 }, 2155 [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = { 2156 .name = "gem2_emio_clk", 2157 }, 2158 [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = { 2159 .name = "gem3_emio_clk", 2160 }, 2161 [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = { 2162 .name = "mio_clk_50_51", 2163 }, 2164 EXT_CLK_MIO_DATA(0), 2165 EXT_CLK_MIO_DATA(1), 2166 EXT_CLK_MIO_DATA(2), 2167 EXT_CLK_MIO_DATA(3), 2168 EXT_CLK_MIO_DATA(4), 2169 EXT_CLK_MIO_DATA(5), 2170 EXT_CLK_MIO_DATA(6), 2171 EXT_CLK_MIO_DATA(7), 2172 EXT_CLK_MIO_DATA(8), 2173 EXT_CLK_MIO_DATA(9), 2174 EXT_CLK_MIO_DATA(10), 2175 EXT_CLK_MIO_DATA(11), 2176 EXT_CLK_MIO_DATA(12), 2177 EXT_CLK_MIO_DATA(13), 2178 EXT_CLK_MIO_DATA(14), 2179 EXT_CLK_MIO_DATA(15), 2180 EXT_CLK_MIO_DATA(16), 2181 EXT_CLK_MIO_DATA(17), 2182 EXT_CLK_MIO_DATA(18), 2183 EXT_CLK_MIO_DATA(19), 2184 EXT_CLK_MIO_DATA(20), 2185 EXT_CLK_MIO_DATA(21), 2186 EXT_CLK_MIO_DATA(22), 2187 EXT_CLK_MIO_DATA(23), 2188 EXT_CLK_MIO_DATA(24), 2189 EXT_CLK_MIO_DATA(25), 2190 EXT_CLK_MIO_DATA(26), 2191 EXT_CLK_MIO_DATA(27), 2192 EXT_CLK_MIO_DATA(28), 2193 EXT_CLK_MIO_DATA(29), 2194 EXT_CLK_MIO_DATA(30), 2195 EXT_CLK_MIO_DATA(31), 2196 EXT_CLK_MIO_DATA(32), 2197 EXT_CLK_MIO_DATA(33), 2198 EXT_CLK_MIO_DATA(34), 2199 EXT_CLK_MIO_DATA(35), 2200 EXT_CLK_MIO_DATA(36), 2201 EXT_CLK_MIO_DATA(37), 2202 EXT_CLK_MIO_DATA(38), 2203 EXT_CLK_MIO_DATA(39), 2204 EXT_CLK_MIO_DATA(40), 2205 EXT_CLK_MIO_DATA(41), 2206 EXT_CLK_MIO_DATA(42), 2207 EXT_CLK_MIO_DATA(43), 2208 EXT_CLK_MIO_DATA(44), 2209 EXT_CLK_MIO_DATA(45), 2210 EXT_CLK_MIO_DATA(46), 2211 EXT_CLK_MIO_DATA(47), 2212 EXT_CLK_MIO_DATA(48), 2213 EXT_CLK_MIO_DATA(49), 2214 EXT_CLK_MIO_DATA(50), 2215 EXT_CLK_MIO_DATA(51), 2216 EXT_CLK_MIO_DATA(52), 2217 EXT_CLK_MIO_DATA(53), 2218 EXT_CLK_MIO_DATA(54), 2219 EXT_CLK_MIO_DATA(55), 2220 EXT_CLK_MIO_DATA(56), 2221 EXT_CLK_MIO_DATA(57), 2222 EXT_CLK_MIO_DATA(58), 2223 EXT_CLK_MIO_DATA(59), 2224 EXT_CLK_MIO_DATA(60), 2225 EXT_CLK_MIO_DATA(61), 2226 EXT_CLK_MIO_DATA(62), 2227 EXT_CLK_MIO_DATA(63), 2228 EXT_CLK_MIO_DATA(64), 2229 EXT_CLK_MIO_DATA(65), 2230 EXT_CLK_MIO_DATA(66), 2231 EXT_CLK_MIO_DATA(67), 2232 EXT_CLK_MIO_DATA(68), 2233 EXT_CLK_MIO_DATA(69), 2234 EXT_CLK_MIO_DATA(70), 2235 EXT_CLK_MIO_DATA(71), 2236 EXT_CLK_MIO_DATA(72), 2237 EXT_CLK_MIO_DATA(73), 2238 EXT_CLK_MIO_DATA(74), 2239 EXT_CLK_MIO_DATA(75), 2240 EXT_CLK_MIO_DATA(76), 2241 EXT_CLK_MIO_DATA(77), 2242 }; 2243 2244 /* Array of clock which are invalid for this variant */ 2245 static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB}; 2246 2247 /** 2248 * pm_clock_valid - Check if clock is valid or not 2249 * @clock_id Id of the clock to be queried 2250 * 2251 * This function is used to check if given clock is valid 2252 * or not for the chip variant. 2253 * 2254 * List of invalid clocks are maintained in array list for 2255 * different variants. 2256 * 2257 * Return: Returns 1 if clock is valid else 0. 2258 */ 2259 static bool pm_clock_valid(unsigned int clock_id) 2260 { 2261 unsigned int i; 2262 2263 for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++) 2264 if (pm_clk_invalid_list[i] == clock_id) 2265 return 0; 2266 2267 return 1; 2268 } 2269 2270 /** 2271 * pm_clock_type - Get clock's type 2272 * @clock_id Id of the clock to be queried 2273 * 2274 * This function is used to check type of clock (OUTPUT/EXTERNAL). 2275 * 2276 * Return: Returns type of clock (OUTPUT/EXTERNAL). 2277 */ 2278 static unsigned int pm_clock_type(unsigned int clock_id) 2279 { 2280 return (clock_id < CLK_MAX_OUTPUT_CLK) ? 2281 CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL; 2282 } 2283 2284 /** 2285 * pm_api_clock_get_num_clocks() - PM call to request number of clocks 2286 * @nclocks Number of clocks 2287 * 2288 * This function is used by master to get number of clocks. 2289 * 2290 * @return Returns success. 2291 */ 2292 enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks) 2293 { 2294 *nclocks = CLK_MAX; 2295 2296 return PM_RET_SUCCESS; 2297 } 2298 2299 /** 2300 * pm_api_clock_get_name() - PM call to request a clock's name 2301 * @clock_id Clock ID 2302 * @name Name of clock (max 16 bytes) 2303 * 2304 * This function is used by master to get nmae of clock specified 2305 * by given clock ID. 2306 * 2307 * @return Returns success. In case of error, name data is 0. 2308 */ 2309 enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) 2310 { 2311 if (clock_id == CLK_MAX) 2312 memcpy(name, END_OF_CLK, CLK_NAME_LEN); 2313 else if (!pm_clock_valid(clock_id)) 2314 memset(name, 0, CLK_NAME_LEN); 2315 else if (clock_id < CLK_MAX_OUTPUT_CLK) 2316 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN); 2317 else 2318 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name, 2319 CLK_NAME_LEN); 2320 2321 return PM_RET_SUCCESS; 2322 } 2323 2324 /** 2325 * pm_api_clock_get_topology() - PM call to request a clock's topology 2326 * @clock_id Clock ID 2327 * @index Topology index for next toplogy node 2328 * @topology Buffer to store nodes in topology and flags 2329 * 2330 * This function is used by master to get topology information for the 2331 * clock specified by given clock ID. Each response would return 3 2332 * topology nodes. To get next nodes, caller needs to call this API with 2333 * index of next node. Index starts from 0. 2334 * 2335 * @return Returns status, either success or error+reason 2336 */ 2337 enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, 2338 unsigned int index, 2339 uint32_t *topology) 2340 { 2341 struct pm_clock_node *clock_nodes; 2342 uint8_t num_nodes; 2343 unsigned int i; 2344 2345 if (!pm_clock_valid(clock_id)) 2346 return PM_RET_ERROR_ARGS; 2347 2348 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2349 return PM_RET_ERROR_NOTSUPPORTED; 2350 2351 2352 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN); 2353 clock_nodes = *clocks[clock_id].nodes; 2354 num_nodes = clocks[clock_id].num_nodes; 2355 2356 /* Skip parent till index */ 2357 if (index >= num_nodes) 2358 return PM_RET_SUCCESS; 2359 2360 for (i = 0; i < 3U; i++) { 2361 if ((index + i) == num_nodes) 2362 break; 2363 topology[i] = clock_nodes[index + i].type; 2364 topology[i] |= clock_nodes[index + i].clkflags << 2365 CLK_CLKFLAGS_SHIFT; 2366 topology[i] |= clock_nodes[index + i].typeflags << 2367 CLK_TYPEFLAGS_SHIFT; 2368 } 2369 2370 return PM_RET_SUCCESS; 2371 } 2372 2373 /** 2374 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed 2375 * factor parameters for fixed clock 2376 * @clock_id Clock ID 2377 * @mul Multiplication value 2378 * @div Divisor value 2379 * 2380 * This function is used by master to get fixed factor parameers for the 2381 * fixed clock. This API is application only for the fixed clock. 2382 * 2383 * @return Returns status, either success or error+reason 2384 */ 2385 enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id, 2386 uint32_t *mul, 2387 uint32_t *div) 2388 { 2389 struct pm_clock_node *clock_nodes; 2390 uint8_t num_nodes; 2391 unsigned int type, i; 2392 2393 if (!pm_clock_valid(clock_id)) 2394 return PM_RET_ERROR_ARGS; 2395 2396 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2397 return PM_RET_ERROR_NOTSUPPORTED; 2398 2399 clock_nodes = *clocks[clock_id].nodes; 2400 num_nodes = clocks[clock_id].num_nodes; 2401 2402 for (i = 0; i < num_nodes; i++) { 2403 type = clock_nodes[i].type; 2404 if (type == TYPE_FIXEDFACTOR) { 2405 *mul = clock_nodes[i].mult; 2406 *div = clock_nodes[i].div; 2407 break; 2408 } 2409 } 2410 2411 /* Clock is not fixed clock */ 2412 if (i == num_nodes) 2413 return PM_RET_ERROR_ARGS; 2414 2415 return PM_RET_SUCCESS; 2416 } 2417 2418 /** 2419 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents 2420 * @clock_id Clock ID 2421 * @index Index of next parent 2422 * @parents Parents of the given clock 2423 * 2424 * This function is used by master to get clock's parents information. 2425 * This API will return 3 parents with a single response. To get other 2426 * parents, master should call same API in loop with new parent index 2427 * till error is returned. 2428 * 2429 * E.g First call should have index 0 which will return parents 0, 1 and 2430 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and 2431 * so on. 2432 * 2433 * @return Returns status, either success or error+reason 2434 */ 2435 enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, 2436 unsigned int index, 2437 uint32_t *parents) 2438 { 2439 unsigned int i; 2440 int32_t *clk_parents; 2441 2442 if (!pm_clock_valid(clock_id)) 2443 return PM_RET_ERROR_ARGS; 2444 2445 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2446 return PM_RET_ERROR_NOTSUPPORTED; 2447 2448 clk_parents = *clocks[clock_id].parents; 2449 if (clk_parents == NULL) 2450 return PM_RET_ERROR_ARGS; 2451 2452 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN); 2453 2454 /* Skip parent till index */ 2455 for (i = 0; i < index; i++) 2456 if (clk_parents[i] == CLK_NA_PARENT) 2457 return PM_RET_SUCCESS; 2458 2459 for (i = 0; i < 3; i++) { 2460 parents[i] = clk_parents[index + i]; 2461 if (clk_parents[index + i] == CLK_NA_PARENT) 2462 break; 2463 } 2464 2465 return PM_RET_SUCCESS; 2466 } 2467 2468 /** 2469 * pm_api_clock_get_attributes() - PM call to request a clock's attributes 2470 * @clock_id Clock ID 2471 * @attr Clock attributes 2472 * 2473 * This function is used by master to get clock's attributes 2474 * (e.g. valid, clock type, etc). 2475 * 2476 * @return Returns status, either success or error+reason 2477 */ 2478 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, 2479 uint32_t *attr) 2480 { 2481 if (clock_id >= CLK_MAX) 2482 return PM_RET_ERROR_ARGS; 2483 2484 /* Clock valid bit */ 2485 *attr = pm_clock_valid(clock_id); 2486 2487 /* Clock type (Output/External) */ 2488 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT); 2489 2490 return PM_RET_SUCCESS; 2491 } 2492 2493 /** 2494 * pll_get_lockbit() - Returns lockbit index for pll id 2495 * @pll_id: Id of the pll 2496 * 2497 * This function return the PLL_LOCKED bit index in 2498 * pll status register accosiated with given pll id. 2499 * 2500 * Return: Returns bit index 2501 */ 2502 static int pll_get_lockbit(unsigned int pll_id) 2503 { 2504 switch (pll_id) { 2505 case CLK_APLL_INT: 2506 case CLK_IOPLL_INT: 2507 return 0; 2508 case CLK_DPLL_INT: 2509 case CLK_RPLL_INT: 2510 return 1; 2511 case CLK_VPLL_INT: 2512 return 2; 2513 default: 2514 return -1; 2515 } 2516 } 2517 2518 /** 2519 * pm_api_pll_bypass_and_reset() - Bypass and reset PLL 2520 * @clock_id: Id of the PLL 2521 * 2522 * This function is to bypass and reset PLL. 2523 */ 2524 static inline enum pm_ret_status 2525 pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag) 2526 { 2527 enum pm_ret_status ret = PM_RET_SUCCESS; 2528 unsigned int reg, val; 2529 int lockbit; 2530 2531 reg = clocks[clock_id].control_reg; 2532 2533 if (flag & CLK_PLL_RESET_ASSERT) { 2534 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK); 2535 if (ret != PM_RET_SUCCESS) 2536 return ret; 2537 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK, 2538 PLLCTRL_RESET_MASK); 2539 if (ret != PM_RET_SUCCESS) 2540 return ret; 2541 } 2542 if (flag & CLK_PLL_RESET_RELEASE) { 2543 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK, 2544 ~PLLCTRL_RESET_MASK); 2545 if (ret != PM_RET_SUCCESS) 2546 return ret; 2547 2548 lockbit = pll_get_lockbit(clock_id); 2549 do { 2550 ret = pm_mmio_read(clocks[clock_id].status_reg, &val); 2551 if (ret != PM_RET_SUCCESS) 2552 return ret; 2553 } while ((lockbit >= 0) && !(val & (1 << lockbit))); 2554 2555 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, 2556 ~(unsigned int)PLLCTRL_BP_MASK); 2557 } 2558 return ret; 2559 } 2560 2561 /** 2562 * pm_api_clk_enable_disable() - Enable/Disable the clock for given id 2563 * @clock_id: Id of the clock to be enabled 2564 * @enable: Enable(1)/Disable(0) 2565 * 2566 * This function is to enable/disable the clock which is not PLL. 2567 * 2568 * Return: Returns status, either success or error+reason. 2569 */ 2570 static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id, 2571 unsigned int enable) 2572 { 2573 enum pm_ret_status ret = PM_RET_SUCCESS; 2574 struct pm_clock_node *nodes = *clocks[clock_id].nodes; 2575 uint8_t num_nodes = clocks[clock_id].num_nodes; 2576 unsigned int reg, val; 2577 uint8_t i = 0; 2578 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2579 2580 if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX || 2581 clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX) 2582 reg = clocks[clock_id].status_reg; 2583 else 2584 reg = clocks[clock_id].control_reg; 2585 2586 for (i = 0; i < num_nodes; i++) { 2587 if (nodes->type == TYPE_GATE) { 2588 offset = nodes->offset; 2589 width = nodes->width; 2590 break; 2591 } 2592 nodes++; 2593 } 2594 if (width == NA_WIDTH) 2595 return PM_RET_ERROR_NOTSUPPORTED; 2596 2597 ret = pm_mmio_read(reg, &val); 2598 if (ret != PM_RET_SUCCESS) 2599 return ret; 2600 if ((val & BIT_MASK(offset, width)) == enable) 2601 return PM_RET_SUCCESS; 2602 2603 if (enable == 0) 2604 val &= ~(BIT_MASK(offset, width)); 2605 else 2606 val |= BIT_MASK(offset, width); 2607 2608 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val); 2609 2610 return ret; 2611 } 2612 2613 /** 2614 * pm_api_clock_enable() - Enable the clock for given id 2615 * @clock_id: Id of the clock to be enabled 2616 * 2617 * This function is used by master to enable the clock 2618 * including peripherals and PLL clocks. 2619 * 2620 * Return: Returns status, either success or error+reason. 2621 */ 2622 enum pm_ret_status pm_api_clock_enable(unsigned int clock_id) 2623 { 2624 enum pm_ret_status ret = PM_RET_SUCCESS; 2625 2626 if (!pm_clock_valid(clock_id)) 2627 return PM_RET_ERROR_ARGS; 2628 2629 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2630 return PM_RET_ERROR_NOTSUPPORTED; 2631 2632 /* 2633 * PLL type clock should not enable explicitly. 2634 * It is done by FSBL on boot-up and by PMUFW whenever required. 2635 */ 2636 if (!ISPLL(clock_id)) 2637 ret = pm_api_clk_enable_disable(clock_id, 1); 2638 2639 return ret; 2640 } 2641 2642 /** 2643 * pm_api_clock_disable - Disable the clock for given id 2644 * @clock_id Id of the clock to be disable 2645 * 2646 * This function is used by master to disable the clock 2647 * including peripherals and PLL clocks. 2648 * 2649 * Return: Returns status, either success or error+reason. 2650 */ 2651 2652 enum pm_ret_status pm_api_clock_disable(unsigned int clock_id) 2653 { 2654 enum pm_ret_status ret = PM_RET_SUCCESS; 2655 2656 if (!pm_clock_valid(clock_id)) 2657 return PM_RET_ERROR_ARGS; 2658 2659 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2660 return PM_RET_ERROR_NOTSUPPORTED; 2661 2662 /* 2663 * PLL type clock should not be disabled explicitly. 2664 * It is done by PMUFW if required. 2665 */ 2666 if (!ISPLL(clock_id)) 2667 ret = pm_api_clk_enable_disable(clock_id, 0); 2668 2669 return ret; 2670 } 2671 2672 /** 2673 * pm_api_get_pll_state() - Get state of PLL 2674 * @clock_id Id of the PLL 2675 * @state State of PLL(1: Enable, 0: Reset) 2676 * 2677 * This function is to check state of PLL. 2678 */ 2679 static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id, 2680 unsigned int *state) 2681 { 2682 enum pm_ret_status ret = PM_RET_SUCCESS; 2683 unsigned int reg, val; 2684 2685 reg = clocks[clock_id].control_reg; 2686 2687 ret = pm_mmio_read(reg, &val); 2688 2689 /* state: 2690 * 1 - PLL is enabled 2691 * 0 - PLL is in reset state 2692 */ 2693 *state = !(val & PLLCTRL_RESET_MASK); 2694 return ret; 2695 } 2696 2697 /** 2698 * pm_api_get_clk_state() - Get the state of clock for given id 2699 * @clock_id: Id of the clock to be enabled 2700 * @state: Enable(1)/Disable(0) 2701 * 2702 * This function is to get state of the clock which is not PLL. 2703 * 2704 * Return: Returns status, either success or error+reason. 2705 */ 2706 static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id, 2707 unsigned int *state) 2708 { 2709 enum pm_ret_status ret = PM_RET_SUCCESS; 2710 struct pm_clock_node *nodes = *clocks[clock_id].nodes; 2711 uint8_t num_nodes = clocks[clock_id].num_nodes; 2712 unsigned int reg, val; 2713 uint8_t i = 0; 2714 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2715 2716 reg = clocks[clock_id].control_reg; 2717 2718 for (i = 0; i < num_nodes; i++) { 2719 if (nodes->type == TYPE_GATE) { 2720 offset = nodes->offset; 2721 width = nodes->width; 2722 } 2723 nodes++; 2724 } 2725 if (width == NA_WIDTH) 2726 return PM_RET_ERROR_NOTSUPPORTED; 2727 2728 ret = pm_mmio_read(reg, &val); 2729 *state = (val & BIT_MASK(offset, width)) >> offset; 2730 2731 return ret; 2732 } 2733 2734 /** 2735 * pm_api_clock_getstate - Get the clock state for given id 2736 * @clock_id Id of the clock to be queried 2737 * @state 1/0 (Enabled/Disabled) 2738 * 2739 * This function is used by master to get the state of clock 2740 * including peripherals and PLL clocks. 2741 * 2742 * Return: Returns status, either success or error+reason. 2743 */ 2744 enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id, 2745 unsigned int *state) 2746 { 2747 enum pm_ret_status ret = PM_RET_SUCCESS; 2748 2749 if (!pm_clock_valid(clock_id)) 2750 return PM_RET_ERROR_ARGS; 2751 2752 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2753 return PM_RET_ERROR_NOTSUPPORTED; 2754 2755 if (ISPLL(clock_id)) 2756 ret = pm_api_get_pll_state(clock_id, state); 2757 else 2758 ret = pm_api_get_clk_state(clock_id, state); 2759 2760 return ret; 2761 } 2762 2763 static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id, 2764 uint32_t divider) 2765 { 2766 enum pm_ret_status ret = PM_RET_SUCCESS; 2767 struct pm_clock_node *nodes; 2768 uint8_t num_nodes; 2769 uint16_t div1, div2; 2770 unsigned int reg, mask = 0, val = 0, i; 2771 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT; 2772 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT; 2773 2774 div1 = (uint16_t)(divider & 0xFFFFU); 2775 div2 = (uint16_t)((divider >> 16) & 0xFFFFU); 2776 2777 reg = clocks[clock_id].control_reg; 2778 2779 nodes = *clocks[clock_id].nodes; 2780 num_nodes = clocks[clock_id].num_nodes; 2781 for (i = 0; i < num_nodes; i++) { 2782 if (nodes->type == TYPE_DIV1) { 2783 div1_offset = nodes->offset; 2784 div1_width = nodes->width; 2785 } 2786 if (nodes->type == TYPE_DIV2) { 2787 div2_offset = nodes->offset; 2788 div2_width = nodes->width; 2789 } 2790 nodes++; 2791 } 2792 2793 if (div1 != (uint16_t)-1) { 2794 if (div1_width == NA_WIDTH) 2795 return PM_RET_ERROR_NOTSUPPORTED; 2796 val |= div1 << div1_offset; 2797 mask |= BIT_MASK(div1_offset, div1_width); 2798 } 2799 if (div2 != (uint16_t)-1) { 2800 if (div2_width == NA_WIDTH) 2801 return PM_RET_ERROR_NOTSUPPORTED; 2802 val |= div2 << div2_offset; 2803 mask |= BIT_MASK(div2_offset, div2_width); 2804 } 2805 ret = pm_mmio_write(reg, mask, val); 2806 2807 return ret; 2808 } 2809 2810 static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id, 2811 unsigned int divider) 2812 { 2813 unsigned int reg = clocks[clock_id].control_reg; 2814 enum pm_ret_status ret; 2815 2816 pm_api_pll_bypass_and_reset(clock_id, CLK_PLL_RESET_ASSERT); 2817 ret = pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT); 2818 pm_api_pll_bypass_and_reset(clock_id, CLK_PLL_RESET_RELEASE); 2819 2820 return ret; 2821 } 2822 2823 /** 2824 * pm_api_clock_setdivider - Set the clock divider for given id 2825 * @clock_id Id of the clock 2826 * @divider Divider value 2827 * 2828 * This function is used by master to set divider for any clock 2829 * to achieve desired rate. 2830 * 2831 * Return: Returns status, either success or error+reason. 2832 */ 2833 enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id, 2834 unsigned int divider) 2835 { 2836 enum pm_ret_status ret; 2837 2838 if (!pm_clock_valid(clock_id)) 2839 return PM_RET_ERROR_ARGS; 2840 2841 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2842 return PM_RET_ERROR_NOTSUPPORTED; 2843 2844 if (ISPLL(clock_id)) 2845 ret = pm_api_pll_set_divider(clock_id, divider); 2846 else 2847 ret = pm_api_clk_set_divider(clock_id, divider); 2848 2849 return ret; 2850 } 2851 2852 static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id, 2853 uint32_t *divider) 2854 { 2855 enum pm_ret_status ret = PM_RET_SUCCESS; 2856 struct pm_clock_node *nodes; 2857 uint8_t num_nodes; 2858 unsigned int reg, val, i, div1 = 0, div2 = 0; 2859 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT; 2860 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT; 2861 2862 reg = clocks[clock_id].control_reg; 2863 2864 nodes = *clocks[clock_id].nodes; 2865 num_nodes = clocks[clock_id].num_nodes; 2866 for (i = 0; i < num_nodes; i++) { 2867 if (nodes->type == TYPE_DIV1) { 2868 div1_offset = nodes->offset; 2869 div1_width = nodes->width; 2870 } 2871 if (nodes->type == TYPE_DIV2) { 2872 div2_offset = nodes->offset; 2873 div2_width = nodes->width; 2874 } 2875 nodes++; 2876 } 2877 2878 ret = pm_mmio_read(reg, &val); 2879 2880 if (div1_width == NA_WIDTH) 2881 return PM_RET_ERROR_ARGS; 2882 2883 div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset; 2884 2885 if (div2_width != NA_WIDTH) 2886 div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset; 2887 2888 *divider = div1 | (div2 << 16); 2889 2890 return ret; 2891 } 2892 2893 static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id, 2894 unsigned int *divider) 2895 { 2896 enum pm_ret_status ret = PM_RET_SUCCESS; 2897 unsigned int reg, val; 2898 2899 reg = clocks[clock_id].control_reg; 2900 2901 ret = pm_mmio_read(reg, &val); 2902 *divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; 2903 2904 return ret; 2905 } 2906 2907 /** 2908 * pm_api_clock_getdivider - Get the clock divider for given id 2909 * @clock_id Id of the clock 2910 * @divider Divider value 2911 * 2912 * This function is used by master to get divider values 2913 * for any clock. 2914 * 2915 * Return: Returns status, either success or error+reason. 2916 */ 2917 enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id, 2918 unsigned int *divider) 2919 { 2920 enum pm_ret_status ret; 2921 2922 if (!pm_clock_valid(clock_id)) 2923 return PM_RET_ERROR_ARGS; 2924 2925 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2926 return PM_RET_ERROR_NOTSUPPORTED; 2927 2928 if (ISPLL(clock_id)) 2929 ret = pm_api_pll_get_divider(clock_id, divider); 2930 else 2931 ret = pm_api_clk_get_divider(clock_id, divider); 2932 2933 return ret; 2934 } 2935 2936 /** 2937 * pm_api_clock_setrate - Set the clock rate for given id 2938 * @clock_id Id of the clock 2939 * @rate Rate value in hz 2940 * 2941 * This function is used by master to set rate for any clock. 2942 * 2943 * Return: Returns status, either success or error+reason. 2944 */ 2945 enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id, 2946 uint64_t rate) 2947 { 2948 return PM_RET_ERROR_NOTSUPPORTED; 2949 } 2950 2951 /** 2952 * pm_api_clock_getrate - Get the clock rate for given id 2953 * @clock_id Id of the clock 2954 * @rate rate value in hz 2955 * 2956 * This function is used by master to get rate 2957 * for any clock. 2958 * 2959 * Return: Returns status, either success or error+reason. 2960 */ 2961 enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id, 2962 uint64_t *rate) 2963 { 2964 return PM_RET_ERROR_NOTSUPPORTED; 2965 } 2966 2967 /** 2968 * pm_api_clock_setparent - Set the clock parent for given id 2969 * @clock_id Id of the clock 2970 * @parent_idx parent index 2971 * 2972 * This function is used by master to set parent for any clock. 2973 * 2974 * Return: Returns status, either success or error+reason. 2975 */ 2976 enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id, 2977 unsigned int parent_idx) 2978 { 2979 enum pm_ret_status ret = PM_RET_SUCCESS; 2980 struct pm_clock_node *nodes; 2981 uint8_t num_nodes; 2982 unsigned int reg, val; 2983 int32_t *clk_parents; 2984 unsigned int i = 0; 2985 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2986 2987 if (!pm_clock_valid(clock_id)) 2988 return PM_RET_ERROR_ARGS; 2989 2990 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2991 return PM_RET_ERROR_NOTSUPPORTED; 2992 2993 clk_parents = *clocks[clock_id].parents; 2994 2995 for (i = 0; i <= parent_idx; i++) 2996 if (clk_parents[i] == CLK_NA_PARENT) 2997 return PM_RET_ERROR_ARGS; 2998 2999 nodes = *clocks[clock_id].nodes; 3000 num_nodes = clocks[clock_id].num_nodes; 3001 for (i = 0; i < num_nodes; i++) { 3002 if (nodes->type == TYPE_MUX) { 3003 offset = nodes->offset; 3004 width = nodes->width; 3005 } 3006 nodes++; 3007 } 3008 if (width == NA_WIDTH) 3009 return PM_RET_ERROR_NOTSUPPORTED; 3010 3011 reg = clocks[clock_id].control_reg; 3012 val = parent_idx << offset; 3013 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val); 3014 3015 return ret; 3016 } 3017 3018 /** 3019 * pm_api_clock_getparent - Get the clock parent for given id 3020 * @clock_id Id of the clock 3021 * @parent_idx parent index 3022 * 3023 * This function is used by master to get parent index 3024 * for any clock. 3025 * 3026 * Return: Returns status, either success or error+reason. 3027 */ 3028 enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id, 3029 unsigned int *parent_idx) 3030 { 3031 enum pm_ret_status ret = PM_RET_SUCCESS; 3032 struct pm_clock_node *nodes; 3033 uint8_t num_nodes; 3034 unsigned int reg, val; 3035 uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH; 3036 3037 if (!pm_clock_valid(clock_id)) 3038 return PM_RET_ERROR_ARGS; 3039 3040 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 3041 return PM_RET_ERROR_NOTSUPPORTED; 3042 3043 nodes = *clocks[clock_id].nodes; 3044 num_nodes = clocks[clock_id].num_nodes; 3045 3046 for (i = 0; i < num_nodes; i++) { 3047 if (nodes->type == TYPE_MUX) { 3048 offset = nodes->offset; 3049 width = nodes->width; 3050 } 3051 nodes++; 3052 } 3053 if (width == NA_WIDTH) 3054 return PM_RET_ERROR_NOTSUPPORTED; 3055 3056 reg = clocks[clock_id].control_reg; 3057 ret = pm_mmio_read(reg, &val); 3058 val >>= offset; 3059 val &= ((1U << width) - 1); 3060 3061 *parent_idx = val; 3062 3063 return ret; 3064 } 3065 3066 /** 3067 * pm_api_clk_set_pll_mode() - Set PLL mode 3068 * @pll PLL id 3069 * @mode Mode fraction/integar 3070 * 3071 * This function sets PLL mode. 3072 * 3073 * @return Returns status, either success or error+reason 3074 */ 3075 enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll, 3076 unsigned int mode) 3077 { 3078 enum pm_ret_status ret = PM_RET_SUCCESS; 3079 unsigned int reg; 3080 3081 if (!pm_clock_valid(pll)) 3082 return PM_RET_ERROR_ARGS; 3083 3084 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3085 return PM_RET_ERROR_NOTSUPPORTED; 3086 3087 if (!ISPLL(pll)) 3088 return PM_RET_ERROR_NOTSUPPORTED; 3089 3090 if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE) 3091 return PM_RET_ERROR_ARGS; 3092 3093 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3094 3095 ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK, 3096 mode << PLL_FRAC_MODE_SHIFT); 3097 3098 return ret; 3099 } 3100 3101 /** 3102 * pm_ioctl_get_pll_mode() - Get PLL mode 3103 * @pll PLL id 3104 * @mode Mode fraction/integar 3105 * 3106 * This function returns current PLL mode. 3107 * 3108 * @return Returns status, either success or error+reason 3109 */ 3110 enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll, 3111 unsigned int *mode) 3112 { 3113 enum pm_ret_status ret = PM_RET_SUCCESS; 3114 unsigned int val, reg; 3115 3116 if (!pm_clock_valid(pll)) 3117 return PM_RET_ERROR_ARGS; 3118 3119 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3120 return PM_RET_ERROR_NOTSUPPORTED; 3121 3122 if (!ISPLL(pll)) 3123 return PM_RET_ERROR_NOTSUPPORTED; 3124 3125 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3126 3127 ret = pm_mmio_read(reg, &val); 3128 val = val & PLL_FRAC_MODE_MASK; 3129 if (val == 0) 3130 *mode = PLL_INT_MODE; 3131 else 3132 *mode = PLL_FRAC_MODE; 3133 3134 return ret; 3135 } 3136 3137 /** 3138 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data 3139 * @pll PLL id 3140 * @data fraction data 3141 * 3142 * This function sets fraction data. It is valid for fraction 3143 * mode only. 3144 * 3145 * @return Returns status, either success or error+reason 3146 */ 3147 enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll, 3148 unsigned int data) 3149 { 3150 enum pm_ret_status ret = PM_RET_SUCCESS; 3151 unsigned int val, reg, mode = 0; 3152 3153 if (!pm_clock_valid(pll)) 3154 return PM_RET_ERROR_ARGS; 3155 3156 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3157 return PM_RET_ERROR_NOTSUPPORTED; 3158 3159 if (!ISPLL(pll)) 3160 return PM_RET_ERROR_NOTSUPPORTED; 3161 3162 ret = pm_api_clk_get_pll_mode(pll, &mode); 3163 if (ret != PM_RET_SUCCESS) 3164 return ret; 3165 if (mode == PLL_FRAC_MODE) { 3166 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3167 val = data << PLL_FRAC_DATA_SHIFT; 3168 ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val); 3169 } else { 3170 return PM_RET_ERROR_ARGS; 3171 } 3172 3173 return ret; 3174 } 3175 3176 /** 3177 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data 3178 * @pll PLL id 3179 * @data fraction data 3180 * 3181 * This function returns fraction data value. 3182 * 3183 * @return Returns status, either success or error+reason 3184 */ 3185 enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll, 3186 unsigned int *data) 3187 { 3188 enum pm_ret_status ret = PM_RET_SUCCESS; 3189 unsigned int val, reg; 3190 3191 if (!pm_clock_valid(pll)) 3192 return PM_RET_ERROR_ARGS; 3193 3194 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3195 return PM_RET_ERROR_NOTSUPPORTED; 3196 3197 if (!ISPLL(pll)) 3198 return PM_RET_ERROR_NOTSUPPORTED; 3199 3200 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3201 3202 ret = pm_mmio_read(reg, &val); 3203 *data = (val & PLL_FRAC_DATA_MASK); 3204 3205 return ret; 3206 } 3207