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