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_INIT_ENABLE_SHIFT U(1) 29 #define CLK_TYPE_SHIFT U(2) 30 #define CLK_CLKFLAGS_SHIFT U(8) 31 #define CLK_TYPEFLAGS_SHIFT U(24) 32 33 #define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN) 34 35 #define NA_MULT U(0) 36 #define NA_DIV U(0) 37 #define NA_SHIFT U(0) 38 #define NA_WIDTH U(0) 39 #define NA_CLK_FLAGS U(0) 40 #define NA_TYPE_FLAGS U(0) 41 42 /* PLL nodes related definitions */ 43 #define PLL_PRESRC_MUX_SHIFT U(20) 44 #define PLL_PRESRC_MUX_WIDTH U(3) 45 #define PLL_POSTSRC_MUX_SHIFT U(24) 46 #define PLL_POSTSRC_MUX_WIDTH U(3) 47 #define PLL_DIV2_MUX_SHIFT U(16) 48 #define PLL_DIV2_MUX_WIDTH U(1) 49 #define PLL_BYPASS_MUX_SHIFT U(3) 50 #define PLL_BYPASS_MUX_WIDTH U(1) 51 52 /* Peripheral nodes related definitions */ 53 /* Peripheral Clocks */ 54 #define PERIPH_MUX_SHIFT U(0) 55 #define PERIPH_MUX_WIDTH U(3) 56 #define PERIPH_DIV1_SHIFT U(8) 57 #define PERIPH_DIV1_WIDTH U(6) 58 #define PERIPH_DIV2_SHIFT U(16) 59 #define PERIPH_DIV2_WIDTH U(6) 60 #define PERIPH_GATE_SHIFT U(24) 61 #define PERIPH_GATE_WIDTH U(1) 62 63 #define USB_GATE_SHIFT U(25) 64 65 /* External clock related definitions */ 66 67 #define EXT_CLK_MIO_DATA(mio) \ 68 [EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = { \ 69 .name = "mio_clk_"#mio, \ 70 } 71 72 #define EXT_CLK_INDEX(n) (n - CLK_MAX_OUTPUT_CLK) 73 74 /* Clock control related definitions */ 75 #define BIT_MASK(x, y) (((1U << (y)) - 1) << (x)) 76 77 #define ISPLL(id) (id == CLK_APLL_INT || \ 78 id == CLK_DPLL_INT || \ 79 id == CLK_VPLL_INT || \ 80 id == CLK_IOPLL_INT || \ 81 id == CLK_RPLL_INT) 82 83 84 #define PLLCTRL_BP_MASK BIT(3) 85 #define PLLCTRL_RESET_MASK U(1) 86 #define PLL_FRAC_OFFSET U(8) 87 #define PLL_FRAC_MODE U(1) 88 #define PLL_INT_MODE U(0) 89 #define PLL_FRAC_MODE_MASK U(0x80000000) 90 #define PLL_FRAC_MODE_SHIFT U(31) 91 #define PLL_FRAC_DATA_MASK U(0xFFFF) 92 #define PLL_FRAC_DATA_SHIFT U(0) 93 #define PLL_FBDIV_MASK U(0x7F00) 94 #define PLL_FBDIV_WIDTH U(7) 95 #define PLL_FBDIV_SHIFT U(8) 96 97 #define CLK_PLL_RESET_ASSERT U(1) 98 #define CLK_PLL_RESET_RELEASE U(2) 99 #define CLK_PLL_RESET_PULSE (CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE) 100 101 /* Common topology definitions */ 102 #define GENERIC_MUX \ 103 { \ 104 .type = TYPE_MUX, \ 105 .offset = PERIPH_MUX_SHIFT, \ 106 .width = PERIPH_MUX_WIDTH, \ 107 .clkflags = CLK_SET_RATE_NO_REPARENT | \ 108 CLK_IS_BASIC, \ 109 .typeflags = NA_TYPE_FLAGS, \ 110 .mult = NA_MULT, \ 111 .div = NA_DIV, \ 112 } 113 114 #define IGNORE_UNUSED_MUX \ 115 { \ 116 .type = TYPE_MUX, \ 117 .offset = PERIPH_MUX_SHIFT, \ 118 .width = PERIPH_MUX_WIDTH, \ 119 .clkflags = CLK_IGNORE_UNUSED | \ 120 CLK_SET_RATE_NO_REPARENT | \ 121 CLK_IS_BASIC, \ 122 .typeflags = NA_TYPE_FLAGS, \ 123 .mult = NA_MULT, \ 124 .div = NA_DIV, \ 125 } 126 127 #define GENERIC_DIV(id) \ 128 { \ 129 .type = TYPE_DIV##id, \ 130 .offset = PERIPH_DIV##id##_SHIFT, \ 131 .width = PERIPH_DIV##id##_WIDTH, \ 132 .clkflags = CLK_SET_RATE_NO_REPARENT | \ 133 CLK_IS_BASIC, \ 134 .typeflags = CLK_DIVIDER_ONE_BASED | \ 135 CLK_DIVIDER_ALLOW_ZERO, \ 136 .mult = NA_MULT, \ 137 .div = NA_DIV, \ 138 } 139 140 #define IGNORE_UNUSED_DIV(id) \ 141 { \ 142 .type = TYPE_DIV##id, \ 143 .offset = PERIPH_DIV##id##_SHIFT, \ 144 .width = PERIPH_DIV##id##_WIDTH, \ 145 .clkflags = CLK_IGNORE_UNUSED | \ 146 CLK_SET_RATE_NO_REPARENT | \ 147 CLK_IS_BASIC, \ 148 .typeflags = CLK_DIVIDER_ONE_BASED | \ 149 CLK_DIVIDER_ALLOW_ZERO, \ 150 .mult = NA_MULT, \ 151 .div = NA_DIV, \ 152 } 153 154 #define GENERIC_GATE \ 155 { \ 156 .type = TYPE_GATE, \ 157 .offset = PERIPH_GATE_SHIFT, \ 158 .width = PERIPH_GATE_WIDTH, \ 159 .clkflags = CLK_SET_RATE_PARENT | \ 160 CLK_SET_RATE_GATE | \ 161 CLK_IS_BASIC, \ 162 .typeflags = NA_TYPE_FLAGS, \ 163 .mult = NA_MULT, \ 164 .div = NA_DIV, \ 165 } 166 167 #define IGNORE_UNUSED_GATE \ 168 { \ 169 .type = TYPE_GATE, \ 170 .offset = PERIPH_GATE_SHIFT, \ 171 .width = PERIPH_GATE_WIDTH, \ 172 .clkflags = CLK_SET_RATE_PARENT | \ 173 CLK_IGNORE_UNUSED | \ 174 CLK_IS_BASIC, \ 175 .typeflags = NA_TYPE_FLAGS, \ 176 .mult = NA_MULT, \ 177 .div = NA_DIV, \ 178 } 179 180 /** 181 * struct pm_clock_node - Clock topology node information 182 * @type: Topology type (mux/div1/div2/gate/pll/fixed factor) 183 * @offset: Offset in control register 184 * @width: Width of the specific type in control register 185 * @clkflags: Clk specific flags 186 * @typeflags: Type specific flags 187 * @mult: Multiplier for fixed factor 188 * @div: Divisor for fixed factor 189 */ 190 struct pm_clock_node { 191 uint16_t clkflags; 192 uint16_t typeflags; 193 uint8_t type; 194 uint8_t offset; 195 uint8_t width; 196 uint8_t mult:4; 197 uint8_t div:4; 198 }; 199 200 /** 201 * struct pm_clock - Clock structure 202 * @name: Clock name 203 * @control_reg: Control register address 204 * @status_reg: Status register address 205 * @parents: Parents for first clock node. Lower byte indicates parent 206 * clock id and upper byte indicate flags for that id. 207 * pm_clock_node: Clock nodes 208 */ 209 struct pm_clock { 210 char name[CLK_NAME_LEN]; 211 uint8_t num_nodes; 212 unsigned int control_reg; 213 unsigned int status_reg; 214 int32_t (*parents)[]; 215 struct pm_clock_node(*nodes)[]; 216 }; 217 218 /** 219 * struct pm_clock - Clock structure 220 * @name: Clock name 221 */ 222 struct pm_ext_clock { 223 char name[CLK_NAME_LEN]; 224 }; 225 226 /* PLL Clocks */ 227 static struct pm_clock_node generic_pll_nodes[] = { 228 { 229 .type = TYPE_PLL, 230 .offset = NA_SHIFT, 231 .width = NA_WIDTH, 232 .clkflags = CLK_SET_RATE_NO_REPARENT, 233 .typeflags = NA_TYPE_FLAGS, 234 .mult = NA_MULT, 235 .div = NA_DIV, 236 }, 237 }; 238 239 static struct pm_clock_node ignore_unused_pll_nodes[] = { 240 { 241 .type = TYPE_PLL, 242 .offset = NA_SHIFT, 243 .width = NA_WIDTH, 244 .clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT, 245 .typeflags = NA_TYPE_FLAGS, 246 .mult = NA_MULT, 247 .div = NA_DIV, 248 }, 249 }; 250 251 static struct pm_clock_node generic_pll_pre_src_nodes[] = { 252 { 253 .type = TYPE_MUX, 254 .offset = PLL_PRESRC_MUX_SHIFT, 255 .width = PLL_PRESRC_MUX_WIDTH, 256 .clkflags = CLK_IS_BASIC, 257 .typeflags = NA_TYPE_FLAGS, 258 .mult = NA_MULT, 259 .div = NA_DIV, 260 }, 261 }; 262 263 static struct pm_clock_node generic_pll_half_nodes[] = { 264 { 265 .type = TYPE_FIXEDFACTOR, 266 .offset = NA_SHIFT, 267 .width = NA_WIDTH, 268 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, 269 .typeflags = NA_TYPE_FLAGS, 270 .mult = 1, 271 .div = 2, 272 }, 273 }; 274 275 static struct pm_clock_node generic_pll_int_nodes[] = { 276 { 277 .type = TYPE_MUX, 278 .offset = PLL_DIV2_MUX_SHIFT, 279 .width = PLL_DIV2_MUX_WIDTH, 280 .clkflags = CLK_SET_RATE_NO_REPARENT | 281 CLK_SET_RATE_PARENT | 282 CLK_IS_BASIC, 283 .typeflags = NA_TYPE_FLAGS, 284 .mult = NA_MULT, 285 .div = NA_DIV, 286 }, 287 }; 288 289 static struct pm_clock_node generic_pll_post_src_nodes[] = { 290 { 291 .type = TYPE_MUX, 292 .offset = PLL_POSTSRC_MUX_SHIFT, 293 .width = PLL_POSTSRC_MUX_WIDTH, 294 .clkflags = CLK_IS_BASIC, 295 .typeflags = NA_TYPE_FLAGS, 296 .mult = NA_MULT, 297 .div = NA_DIV, 298 }, 299 }; 300 301 static struct pm_clock_node generic_pll_system_nodes[] = { 302 { 303 .type = TYPE_MUX, 304 .offset = PLL_BYPASS_MUX_SHIFT, 305 .width = PLL_BYPASS_MUX_WIDTH, 306 .clkflags = CLK_SET_RATE_NO_REPARENT | 307 CLK_SET_RATE_PARENT | 308 CLK_IS_BASIC, 309 .typeflags = NA_TYPE_FLAGS, 310 .mult = NA_MULT, 311 .div = NA_DIV, 312 }, 313 }; 314 315 static struct pm_clock_node acpu_nodes[] = { 316 { 317 .type = TYPE_MUX, 318 .offset = PERIPH_MUX_SHIFT, 319 .width = PERIPH_MUX_WIDTH, 320 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, 321 .typeflags = NA_TYPE_FLAGS, 322 .mult = NA_MULT, 323 .div = NA_DIV, 324 }, 325 { 326 .type = TYPE_DIV1, 327 .offset = PERIPH_DIV1_SHIFT, 328 .width = PERIPH_DIV1_WIDTH, 329 .clkflags = CLK_IS_BASIC, 330 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 331 .mult = NA_MULT, 332 .div = NA_DIV, 333 }, 334 { 335 .type = TYPE_GATE, 336 .offset = PERIPH_GATE_SHIFT, 337 .width = PERIPH_GATE_WIDTH, 338 .clkflags = CLK_SET_RATE_PARENT | 339 CLK_IGNORE_UNUSED | 340 CLK_IS_BASIC, 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, 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 = IOU_SLCR_WDT_CLK_SEL, 2026 .status_reg = 0, 2027 .parents = &((int32_t []) { 2028 CLK_TOPSW_LSBUS, 2029 EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT, 2030 EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT, 2031 CLK_NA_PARENT 2032 }), 2033 .nodes = &wdt_nodes, 2034 .num_nodes = ARRAY_SIZE(wdt_nodes), 2035 }, 2036 [CLK_GPU_PP0_REF] = { 2037 .name = "gpu_pp0_ref", 2038 .control_reg = CRF_APB_GPU_REF_CTRL, 2039 .status_reg = 0, 2040 .parents = &((int32_t []) { 2041 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2042 CLK_NA_PARENT 2043 }), 2044 .nodes = &gpu_pp0_nodes, 2045 .num_nodes = ARRAY_SIZE(gpu_pp0_nodes), 2046 }, 2047 [CLK_GPU_PP1_REF] = { 2048 .name = "gpu_pp1_ref", 2049 .control_reg = CRF_APB_GPU_REF_CTRL, 2050 .status_reg = 0, 2051 .parents = &((int32_t []) { 2052 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2053 CLK_NA_PARENT 2054 }), 2055 .nodes = &gpu_pp1_nodes, 2056 .num_nodes = ARRAY_SIZE(gpu_pp1_nodes), 2057 }, 2058 [CLK_GEM_TSU] = { 2059 .name = "gem_tsu", 2060 .control_reg = IOU_SLCR_GEM_CLK_CTRL, 2061 .status_reg = 0, 2062 .parents = &((int32_t []) { 2063 CLK_GEM_TSU_REF, 2064 CLK_GEM_TSU_REF, 2065 EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT, 2066 EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT, 2067 CLK_NA_PARENT 2068 }), 2069 .nodes = &gem_tsu_nodes, 2070 .num_nodes = ARRAY_SIZE(gem_tsu_nodes), 2071 }, 2072 [CLK_CPU_R5_CORE] = { 2073 .name = "cpu_r5_core", 2074 .control_reg = CRL_APB_CPU_R5_CTRL, 2075 .status_reg = 0, 2076 .parents = &((int32_t []) { 2077 CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN, 2078 CLK_DUMMY_PARENT, 2079 CLK_NA_PARENT 2080 }), 2081 .nodes = &cpu_r5_core_nodes, 2082 .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes), 2083 }, 2084 [CLK_CAN0_MIO] = { 2085 .name = "can0_mio", 2086 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2087 .status_reg = 0, 2088 .parents = &can_mio_parents, 2089 .nodes = &can0_mio_nodes, 2090 .num_nodes = ARRAY_SIZE(can0_mio_nodes), 2091 }, 2092 [CLK_CAN1_MIO] = { 2093 .name = "can1_mio", 2094 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2095 .status_reg = 0, 2096 .parents = &can_mio_parents, 2097 .nodes = &can1_mio_nodes, 2098 .num_nodes = ARRAY_SIZE(can1_mio_nodes), 2099 }, 2100 [CLK_CAN0] = { 2101 .name = "can0", 2102 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2103 .status_reg = 0, 2104 .parents = &((int32_t []) { 2105 CLK_CAN0_REF, 2106 CLK_CAN0_MIO, 2107 CLK_NA_PARENT 2108 }), 2109 .nodes = &can0_nodes, 2110 .num_nodes = ARRAY_SIZE(can0_nodes), 2111 }, 2112 [CLK_CAN1] = { 2113 .name = "can1", 2114 .control_reg = IOU_SLCR_CAN_MIO_CTRL, 2115 .status_reg = 0, 2116 .parents = &((int32_t []) { 2117 CLK_CAN1_REF, 2118 CLK_CAN1_MIO, 2119 CLK_NA_PARENT 2120 }), 2121 .nodes = &can1_nodes, 2122 .num_nodes = ARRAY_SIZE(can1_nodes), 2123 }, 2124 }; 2125 2126 static struct pm_ext_clock ext_clocks[] = { 2127 [EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = { 2128 .name = "pss_ref_clk", 2129 }, 2130 [EXT_CLK_INDEX(EXT_CLK_VIDEO)] = { 2131 .name = "video_clk", 2132 }, 2133 [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = { 2134 .name = "pss_alt_ref_clk", 2135 }, 2136 [EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = { 2137 .name = "aux_ref_clk", 2138 }, 2139 [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = { 2140 .name = "video_clk", 2141 }, 2142 [EXT_CLK_INDEX(EXT_CLK_SWDT0)] = { 2143 .name = "swdt0_ext_clk", 2144 }, 2145 [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = { 2146 .name = "swdt1_ext_clk", 2147 }, 2148 [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = { 2149 .name = "gem0_emio_clk", 2150 }, 2151 [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = { 2152 .name = "gem1_emio_clk", 2153 }, 2154 [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = { 2155 .name = "gem2_emio_clk", 2156 }, 2157 [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = { 2158 .name = "gem3_emio_clk", 2159 }, 2160 [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = { 2161 .name = "mio_clk_50_51", 2162 }, 2163 EXT_CLK_MIO_DATA(0), 2164 EXT_CLK_MIO_DATA(1), 2165 EXT_CLK_MIO_DATA(2), 2166 EXT_CLK_MIO_DATA(3), 2167 EXT_CLK_MIO_DATA(4), 2168 EXT_CLK_MIO_DATA(5), 2169 EXT_CLK_MIO_DATA(6), 2170 EXT_CLK_MIO_DATA(7), 2171 EXT_CLK_MIO_DATA(8), 2172 EXT_CLK_MIO_DATA(9), 2173 EXT_CLK_MIO_DATA(10), 2174 EXT_CLK_MIO_DATA(11), 2175 EXT_CLK_MIO_DATA(12), 2176 EXT_CLK_MIO_DATA(13), 2177 EXT_CLK_MIO_DATA(14), 2178 EXT_CLK_MIO_DATA(15), 2179 EXT_CLK_MIO_DATA(16), 2180 EXT_CLK_MIO_DATA(17), 2181 EXT_CLK_MIO_DATA(18), 2182 EXT_CLK_MIO_DATA(19), 2183 EXT_CLK_MIO_DATA(20), 2184 EXT_CLK_MIO_DATA(21), 2185 EXT_CLK_MIO_DATA(22), 2186 EXT_CLK_MIO_DATA(23), 2187 EXT_CLK_MIO_DATA(24), 2188 EXT_CLK_MIO_DATA(25), 2189 EXT_CLK_MIO_DATA(26), 2190 EXT_CLK_MIO_DATA(27), 2191 EXT_CLK_MIO_DATA(28), 2192 EXT_CLK_MIO_DATA(29), 2193 EXT_CLK_MIO_DATA(30), 2194 EXT_CLK_MIO_DATA(31), 2195 EXT_CLK_MIO_DATA(32), 2196 EXT_CLK_MIO_DATA(33), 2197 EXT_CLK_MIO_DATA(34), 2198 EXT_CLK_MIO_DATA(35), 2199 EXT_CLK_MIO_DATA(36), 2200 EXT_CLK_MIO_DATA(37), 2201 EXT_CLK_MIO_DATA(38), 2202 EXT_CLK_MIO_DATA(39), 2203 EXT_CLK_MIO_DATA(40), 2204 EXT_CLK_MIO_DATA(41), 2205 EXT_CLK_MIO_DATA(42), 2206 EXT_CLK_MIO_DATA(43), 2207 EXT_CLK_MIO_DATA(44), 2208 EXT_CLK_MIO_DATA(45), 2209 EXT_CLK_MIO_DATA(46), 2210 EXT_CLK_MIO_DATA(47), 2211 EXT_CLK_MIO_DATA(48), 2212 EXT_CLK_MIO_DATA(49), 2213 EXT_CLK_MIO_DATA(50), 2214 EXT_CLK_MIO_DATA(51), 2215 EXT_CLK_MIO_DATA(52), 2216 EXT_CLK_MIO_DATA(53), 2217 EXT_CLK_MIO_DATA(54), 2218 EXT_CLK_MIO_DATA(55), 2219 EXT_CLK_MIO_DATA(56), 2220 EXT_CLK_MIO_DATA(57), 2221 EXT_CLK_MIO_DATA(58), 2222 EXT_CLK_MIO_DATA(59), 2223 EXT_CLK_MIO_DATA(60), 2224 EXT_CLK_MIO_DATA(61), 2225 EXT_CLK_MIO_DATA(62), 2226 EXT_CLK_MIO_DATA(63), 2227 EXT_CLK_MIO_DATA(64), 2228 EXT_CLK_MIO_DATA(65), 2229 EXT_CLK_MIO_DATA(66), 2230 EXT_CLK_MIO_DATA(67), 2231 EXT_CLK_MIO_DATA(68), 2232 EXT_CLK_MIO_DATA(69), 2233 EXT_CLK_MIO_DATA(70), 2234 EXT_CLK_MIO_DATA(71), 2235 EXT_CLK_MIO_DATA(72), 2236 EXT_CLK_MIO_DATA(73), 2237 EXT_CLK_MIO_DATA(74), 2238 EXT_CLK_MIO_DATA(75), 2239 EXT_CLK_MIO_DATA(76), 2240 EXT_CLK_MIO_DATA(77), 2241 }; 2242 2243 /* Array of clock which are invalid for this variant */ 2244 static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB}; 2245 2246 /* Array of clocks which needs to be enabled at init */ 2247 static uint32_t pm_clk_init_enable_list[] = { 2248 CLK_ACPU, 2249 CLK_DDR_REF, 2250 }; 2251 2252 /** 2253 * pm_clock_valid - Check if clock is valid or not 2254 * @clock_id Id of the clock to be queried 2255 * 2256 * This function is used to check if given clock is valid 2257 * or not for the chip variant. 2258 * 2259 * List of invalid clocks are maintained in array list for 2260 * different variants. 2261 * 2262 * Return: Returns 1 if clock is valid else 0. 2263 */ 2264 static bool pm_clock_valid(unsigned int clock_id) 2265 { 2266 unsigned int i; 2267 2268 for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++) 2269 if (pm_clk_invalid_list[i] == clock_id) 2270 return 0; 2271 2272 return 1; 2273 } 2274 2275 /** 2276 * pm_clock_init_enable - Check if clock needs to be enabled at init 2277 * @clock_id Id of the clock to be queried 2278 * 2279 * This function is used to check if given clock needs to be enabled 2280 * at boot up or not. Some clocks needs to be enabled at init. 2281 * 2282 * Return: Returns 1 if clock needs to be enabled at boot up else 0. 2283 */ 2284 static unsigned int pm_clock_init_enable(unsigned int clock_id) 2285 { 2286 unsigned int i; 2287 2288 for (i = 0; i < ARRAY_SIZE(pm_clk_init_enable_list); i++) 2289 if (pm_clk_init_enable_list[i] == clock_id) 2290 return 1; 2291 2292 return 0; 2293 } 2294 2295 /** 2296 * pm_clock_type - Get clock's type 2297 * @clock_id Id of the clock to be queried 2298 * 2299 * This function is used to check type of clock (OUTPUT/EXTERNAL). 2300 * 2301 * Return: Returns type of clock (OUTPUT/EXTERNAL). 2302 */ 2303 static unsigned int pm_clock_type(unsigned int clock_id) 2304 { 2305 return (clock_id < CLK_MAX_OUTPUT_CLK) ? 2306 CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL; 2307 } 2308 2309 /** 2310 * pm_api_clock_get_name() - PM call to request a clock's name 2311 * @clock_id Clock ID 2312 * @name Name of clock (max 16 bytes) 2313 * 2314 * This function is used by master to get nmae of clock specified 2315 * by given clock ID. 2316 * 2317 * @return Returns success. In case of error, name data is 0. 2318 */ 2319 enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) 2320 { 2321 if (clock_id == CLK_MAX) 2322 memcpy(name, END_OF_CLK, CLK_NAME_LEN); 2323 else if (!pm_clock_valid(clock_id)) 2324 memset(name, 0, CLK_NAME_LEN); 2325 else if (clock_id < CLK_MAX_OUTPUT_CLK) 2326 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN); 2327 else 2328 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name, 2329 CLK_NAME_LEN); 2330 2331 return PM_RET_SUCCESS; 2332 } 2333 2334 /** 2335 * pm_api_clock_get_topology() - PM call to request a clock's topology 2336 * @clock_id Clock ID 2337 * @index Topology index for next toplogy node 2338 * @topology Buffer to store nodes in topology and flags 2339 * 2340 * This function is used by master to get topology information for the 2341 * clock specified by given clock ID. Each response would return 3 2342 * topology nodes. To get next nodes, caller needs to call this API with 2343 * index of next node. Index starts from 0. 2344 * 2345 * @return Returns status, either success or error+reason 2346 */ 2347 enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, 2348 unsigned int index, 2349 uint32_t *topology) 2350 { 2351 struct pm_clock_node *clock_nodes; 2352 uint8_t num_nodes; 2353 unsigned int i; 2354 2355 if (!pm_clock_valid(clock_id)) 2356 return PM_RET_ERROR_ARGS; 2357 2358 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2359 return PM_RET_ERROR_NOTSUPPORTED; 2360 2361 2362 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN); 2363 clock_nodes = *clocks[clock_id].nodes; 2364 num_nodes = clocks[clock_id].num_nodes; 2365 2366 /* Skip parent till index */ 2367 if (index >= num_nodes) 2368 return PM_RET_SUCCESS; 2369 2370 for (i = 0; i < 3U; i++) { 2371 if ((index + i) == num_nodes) 2372 break; 2373 topology[i] = clock_nodes[index + i].type; 2374 topology[i] |= clock_nodes[index + i].clkflags << 2375 CLK_CLKFLAGS_SHIFT; 2376 topology[i] |= clock_nodes[index + i].typeflags << 2377 CLK_TYPEFLAGS_SHIFT; 2378 } 2379 2380 return PM_RET_SUCCESS; 2381 } 2382 2383 /** 2384 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed 2385 * factor parameters for fixed clock 2386 * @clock_id Clock ID 2387 * @mul Multiplication value 2388 * @div Divisor value 2389 * 2390 * This function is used by master to get fixed factor parameers for the 2391 * fixed clock. This API is application only for the fixed clock. 2392 * 2393 * @return Returns status, either success or error+reason 2394 */ 2395 enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id, 2396 uint32_t *mul, 2397 uint32_t *div) 2398 { 2399 struct pm_clock_node *clock_nodes; 2400 uint8_t num_nodes; 2401 unsigned int type, i; 2402 2403 if (!pm_clock_valid(clock_id)) 2404 return PM_RET_ERROR_ARGS; 2405 2406 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2407 return PM_RET_ERROR_NOTSUPPORTED; 2408 2409 clock_nodes = *clocks[clock_id].nodes; 2410 num_nodes = clocks[clock_id].num_nodes; 2411 2412 for (i = 0; i < num_nodes; i++) { 2413 type = clock_nodes[i].type; 2414 if (type == TYPE_FIXEDFACTOR) { 2415 *mul = clock_nodes[i].mult; 2416 *div = clock_nodes[i].div; 2417 break; 2418 } 2419 } 2420 2421 /* Clock is not fixed clock */ 2422 if (i == num_nodes) 2423 return PM_RET_ERROR_ARGS; 2424 2425 return PM_RET_SUCCESS; 2426 } 2427 2428 /** 2429 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents 2430 * @clock_id Clock ID 2431 * @index Index of next parent 2432 * @parents Parents of the given clock 2433 * 2434 * This function is used by master to get clock's parents information. 2435 * This API will return 3 parents with a single response. To get other 2436 * parents, master should call same API in loop with new parent index 2437 * till error is returned. 2438 * 2439 * E.g First call should have index 0 which will return parents 0, 1 and 2440 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and 2441 * so on. 2442 * 2443 * @return Returns status, either success or error+reason 2444 */ 2445 enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, 2446 unsigned int index, 2447 uint32_t *parents) 2448 { 2449 unsigned int i; 2450 int32_t *clk_parents; 2451 2452 if (!pm_clock_valid(clock_id)) 2453 return PM_RET_ERROR_ARGS; 2454 2455 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2456 return PM_RET_ERROR_NOTSUPPORTED; 2457 2458 clk_parents = *clocks[clock_id].parents; 2459 if (clk_parents == NULL) 2460 return PM_RET_ERROR_ARGS; 2461 2462 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN); 2463 2464 /* Skip parent till index */ 2465 for (i = 0; i < index; i++) 2466 if (clk_parents[i] == CLK_NA_PARENT) 2467 return PM_RET_SUCCESS; 2468 2469 for (i = 0; i < 3; i++) { 2470 parents[i] = clk_parents[index + i]; 2471 if (clk_parents[index + i] == CLK_NA_PARENT) 2472 break; 2473 } 2474 2475 return PM_RET_SUCCESS; 2476 } 2477 2478 /** 2479 * pm_api_clock_get_attributes() - PM call to request a clock's attributes 2480 * @clock_id Clock ID 2481 * @attr Clock attributes 2482 * 2483 * This function is used by master to get clock's attributes 2484 * (e.g. valid, clock type, etc). 2485 * 2486 * @return Returns status, either success or error+reason 2487 */ 2488 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, 2489 uint32_t *attr) 2490 { 2491 if (clock_id >= CLK_MAX) 2492 return PM_RET_ERROR_ARGS; 2493 2494 /* Clock valid bit */ 2495 *attr = pm_clock_valid(clock_id); 2496 2497 /* If clock needs to be enabled during init */ 2498 *attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT); 2499 2500 /* Clock type (Output/External) */ 2501 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT); 2502 2503 return PM_RET_SUCCESS; 2504 } 2505 2506 /** 2507 * pll_get_lockbit() - Returns lockbit index for pll id 2508 * @pll_id: Id of the pll 2509 * 2510 * This function return the PLL_LOCKED bit index in 2511 * pll status register accosiated with given pll id. 2512 * 2513 * Return: Returns bit index 2514 */ 2515 static int pll_get_lockbit(unsigned int pll_id) 2516 { 2517 switch (pll_id) { 2518 case CLK_APLL_INT: 2519 case CLK_IOPLL_INT: 2520 return 0; 2521 case CLK_DPLL_INT: 2522 case CLK_RPLL_INT: 2523 return 1; 2524 case CLK_VPLL_INT: 2525 return 2; 2526 default: 2527 return -1; 2528 } 2529 } 2530 2531 /** 2532 * pm_api_pll_bypass_and_reset() - Bypass and reset PLL 2533 * @clock_id: Id of the PLL 2534 * 2535 * This function is to bypass and reset PLL. 2536 */ 2537 static inline enum pm_ret_status 2538 pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag) 2539 { 2540 enum pm_ret_status ret = PM_RET_SUCCESS; 2541 unsigned int reg, val; 2542 int lockbit; 2543 2544 reg = clocks[clock_id].control_reg; 2545 2546 if (flag & CLK_PLL_RESET_ASSERT) { 2547 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK); 2548 if (ret != PM_RET_SUCCESS) 2549 return ret; 2550 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK, 2551 PLLCTRL_RESET_MASK); 2552 if (ret != PM_RET_SUCCESS) 2553 return ret; 2554 } 2555 if (flag & CLK_PLL_RESET_RELEASE) { 2556 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK, 2557 ~PLLCTRL_RESET_MASK); 2558 if (ret != PM_RET_SUCCESS) 2559 return ret; 2560 2561 lockbit = pll_get_lockbit(clock_id); 2562 do { 2563 ret = pm_mmio_read(clocks[clock_id].status_reg, &val); 2564 if (ret != PM_RET_SUCCESS) 2565 return ret; 2566 } while ((lockbit >= 0) && !(val & (1 << lockbit))); 2567 2568 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, 2569 ~(unsigned int)PLLCTRL_BP_MASK); 2570 } 2571 return ret; 2572 } 2573 2574 /** 2575 * pm_api_clk_enable_disable() - Enable/Disable the clock for given id 2576 * @clock_id: Id of the clock to be enabled 2577 * @enable: Enable(1)/Disable(0) 2578 * 2579 * This function is to enable/disable the clock which is not PLL. 2580 * 2581 * Return: Returns status, either success or error+reason. 2582 */ 2583 static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id, 2584 unsigned int enable) 2585 { 2586 enum pm_ret_status ret = PM_RET_SUCCESS; 2587 struct pm_clock_node *nodes = *clocks[clock_id].nodes; 2588 uint8_t num_nodes = clocks[clock_id].num_nodes; 2589 unsigned int reg, val; 2590 uint8_t i = 0; 2591 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2592 2593 if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX || 2594 clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX) 2595 reg = clocks[clock_id].status_reg; 2596 else 2597 reg = clocks[clock_id].control_reg; 2598 2599 for (i = 0; i < num_nodes; i++) { 2600 if (nodes->type == TYPE_GATE) { 2601 offset = nodes->offset; 2602 width = nodes->width; 2603 break; 2604 } 2605 nodes++; 2606 } 2607 if (width == NA_WIDTH) 2608 return PM_RET_ERROR_NOTSUPPORTED; 2609 2610 ret = pm_mmio_read(reg, &val); 2611 if (ret != PM_RET_SUCCESS) 2612 return ret; 2613 if ((val & BIT_MASK(offset, width)) == enable) 2614 return PM_RET_SUCCESS; 2615 2616 if (enable == 0) 2617 val &= ~(BIT_MASK(offset, width)); 2618 else 2619 val |= BIT_MASK(offset, width); 2620 2621 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val); 2622 2623 return ret; 2624 } 2625 2626 /** 2627 * pm_api_clock_enable() - Enable the clock for given id 2628 * @clock_id: Id of the clock to be enabled 2629 * 2630 * This function is used by master to enable the clock 2631 * including peripherals and PLL clocks. 2632 * 2633 * Return: Returns status, either success or error+reason. 2634 */ 2635 enum pm_ret_status pm_api_clock_enable(unsigned int clock_id) 2636 { 2637 enum pm_ret_status ret = PM_RET_SUCCESS; 2638 2639 if (!pm_clock_valid(clock_id)) 2640 return PM_RET_ERROR_ARGS; 2641 2642 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2643 return PM_RET_ERROR_NOTSUPPORTED; 2644 2645 if (ISPLL(clock_id)) 2646 ret = pm_api_pll_bypass_and_reset(clock_id, 2647 CLK_PLL_RESET_PULSE); 2648 else 2649 ret = pm_api_clk_enable_disable(clock_id, 1); 2650 2651 return ret; 2652 } 2653 2654 /** 2655 * pm_api_clock_disable - Disable the clock for given id 2656 * @clock_id Id of the clock to be disable 2657 * 2658 * This function is used by master to disable the clock 2659 * including peripherals and PLL clocks. 2660 * 2661 * Return: Returns status, either success or error+reason. 2662 */ 2663 2664 enum pm_ret_status pm_api_clock_disable(unsigned int clock_id) 2665 { 2666 enum pm_ret_status ret = PM_RET_SUCCESS; 2667 2668 if (!pm_clock_valid(clock_id)) 2669 return PM_RET_ERROR_ARGS; 2670 2671 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2672 return PM_RET_ERROR_NOTSUPPORTED; 2673 2674 if (ISPLL(clock_id)) 2675 ret = pm_api_pll_bypass_and_reset(clock_id, 2676 CLK_PLL_RESET_ASSERT); 2677 else 2678 ret = pm_api_clk_enable_disable(clock_id, 0); 2679 2680 return ret; 2681 } 2682 2683 /** 2684 * pm_api_get_pll_state() - Get state of PLL 2685 * @clock_id Id of the PLL 2686 * @state State of PLL(1: Enable, 0: Reset) 2687 * 2688 * This function is to check state of PLL. 2689 */ 2690 static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id, 2691 unsigned int *state) 2692 { 2693 enum pm_ret_status ret = PM_RET_SUCCESS; 2694 unsigned int reg, val; 2695 2696 reg = clocks[clock_id].control_reg; 2697 2698 ret = pm_mmio_read(reg, &val); 2699 2700 /* state: 2701 * 1 - PLL is enabled 2702 * 0 - PLL is in reset state 2703 */ 2704 *state = !(val & PLLCTRL_RESET_MASK); 2705 return ret; 2706 } 2707 2708 /** 2709 * pm_api_get_clk_state() - Get the state of clock for given id 2710 * @clock_id: Id of the clock to be enabled 2711 * @state: Enable(1)/Disable(0) 2712 * 2713 * This function is to get state of the clock which is not PLL. 2714 * 2715 * Return: Returns status, either success or error+reason. 2716 */ 2717 static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id, 2718 unsigned int *state) 2719 { 2720 enum pm_ret_status ret = PM_RET_SUCCESS; 2721 struct pm_clock_node *nodes = *clocks[clock_id].nodes; 2722 uint8_t num_nodes = clocks[clock_id].num_nodes; 2723 unsigned int reg, val; 2724 uint8_t i = 0; 2725 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2726 2727 reg = clocks[clock_id].control_reg; 2728 2729 for (i = 0; i < num_nodes; i++) { 2730 if (nodes->type == TYPE_GATE) { 2731 offset = nodes->offset; 2732 width = nodes->width; 2733 } 2734 nodes++; 2735 } 2736 if (width == NA_WIDTH) 2737 return PM_RET_ERROR_NOTSUPPORTED; 2738 2739 ret = pm_mmio_read(reg, &val); 2740 *state = (val & BIT_MASK(offset, width)) >> offset; 2741 2742 return ret; 2743 } 2744 2745 /** 2746 * pm_api_clock_getstate - Get the clock state for given id 2747 * @clock_id Id of the clock to be queried 2748 * @state 1/0 (Enabled/Disabled) 2749 * 2750 * This function is used by master to get the state of clock 2751 * including peripherals and PLL clocks. 2752 * 2753 * Return: Returns status, either success or error+reason. 2754 */ 2755 enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id, 2756 unsigned int *state) 2757 { 2758 enum pm_ret_status ret = PM_RET_SUCCESS; 2759 2760 if (!pm_clock_valid(clock_id)) 2761 return PM_RET_ERROR_ARGS; 2762 2763 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2764 return PM_RET_ERROR_NOTSUPPORTED; 2765 2766 if (ISPLL(clock_id)) 2767 ret = pm_api_get_pll_state(clock_id, state); 2768 else 2769 ret = pm_api_get_clk_state(clock_id, state); 2770 2771 return ret; 2772 } 2773 2774 static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id, 2775 uint32_t divider) 2776 { 2777 enum pm_ret_status ret = PM_RET_SUCCESS; 2778 struct pm_clock_node *nodes; 2779 uint8_t num_nodes; 2780 uint16_t div1, div2; 2781 unsigned int reg, mask = 0, val = 0, i; 2782 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT; 2783 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT; 2784 2785 div1 = (uint16_t)(divider & 0xFFFFU); 2786 div2 = (uint16_t)((divider >> 16) & 0xFFFFU); 2787 2788 reg = clocks[clock_id].control_reg; 2789 2790 nodes = *clocks[clock_id].nodes; 2791 num_nodes = clocks[clock_id].num_nodes; 2792 for (i = 0; i < num_nodes; i++) { 2793 if (nodes->type == TYPE_DIV1) { 2794 div1_offset = nodes->offset; 2795 div1_width = nodes->width; 2796 } 2797 if (nodes->type == TYPE_DIV2) { 2798 div2_offset = nodes->offset; 2799 div2_width = nodes->width; 2800 } 2801 nodes++; 2802 } 2803 2804 if (div1 != (uint16_t)-1) { 2805 if (div1_width == NA_WIDTH) 2806 return PM_RET_ERROR_NOTSUPPORTED; 2807 val |= div1 << div1_offset; 2808 mask |= BIT_MASK(div1_offset, div1_width); 2809 } 2810 if (div2 != (uint16_t)-1) { 2811 if (div2_width == NA_WIDTH) 2812 return PM_RET_ERROR_NOTSUPPORTED; 2813 val |= div2 << div2_offset; 2814 mask |= BIT_MASK(div2_offset, div2_width); 2815 } 2816 ret = pm_mmio_write(reg, mask, val); 2817 2818 return ret; 2819 } 2820 2821 static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id, 2822 unsigned int divider) 2823 { 2824 unsigned int reg = clocks[clock_id].control_reg; 2825 2826 return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT); 2827 } 2828 2829 /** 2830 * pm_api_clock_setdivider - Set the clock divider for given id 2831 * @clock_id Id of the clock 2832 * @divider Divider value 2833 * 2834 * This function is used by master to set divider for any clock 2835 * to achieve desired rate. 2836 * 2837 * Return: Returns status, either success or error+reason. 2838 */ 2839 enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id, 2840 unsigned int divider) 2841 { 2842 enum pm_ret_status ret; 2843 2844 if (!pm_clock_valid(clock_id)) 2845 return PM_RET_ERROR_ARGS; 2846 2847 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2848 return PM_RET_ERROR_NOTSUPPORTED; 2849 2850 if (ISPLL(clock_id)) 2851 ret = pm_api_pll_set_divider(clock_id, divider); 2852 else 2853 ret = pm_api_clk_set_divider(clock_id, divider); 2854 2855 return ret; 2856 } 2857 2858 static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id, 2859 uint32_t *divider) 2860 { 2861 enum pm_ret_status ret = PM_RET_SUCCESS; 2862 struct pm_clock_node *nodes; 2863 uint8_t num_nodes; 2864 unsigned int reg, val, i, div1 = 0, div2 = 0; 2865 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT; 2866 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT; 2867 2868 reg = clocks[clock_id].control_reg; 2869 2870 nodes = *clocks[clock_id].nodes; 2871 num_nodes = clocks[clock_id].num_nodes; 2872 for (i = 0; i < num_nodes; i++) { 2873 if (nodes->type == TYPE_DIV1) { 2874 div1_offset = nodes->offset; 2875 div1_width = nodes->width; 2876 } 2877 if (nodes->type == TYPE_DIV2) { 2878 div2_offset = nodes->offset; 2879 div2_width = nodes->width; 2880 } 2881 nodes++; 2882 } 2883 2884 ret = pm_mmio_read(reg, &val); 2885 2886 if (div1_width == NA_WIDTH) 2887 return PM_RET_ERROR_ARGS; 2888 2889 div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset; 2890 2891 if (div2_width != NA_WIDTH) 2892 div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset; 2893 2894 *divider = div1 | (div2 << 16); 2895 2896 return ret; 2897 } 2898 2899 static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id, 2900 unsigned int *divider) 2901 { 2902 enum pm_ret_status ret = PM_RET_SUCCESS; 2903 unsigned int reg, val; 2904 2905 reg = clocks[clock_id].control_reg; 2906 2907 ret = pm_mmio_read(reg, &val); 2908 *divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; 2909 2910 return ret; 2911 } 2912 2913 /** 2914 * pm_api_clock_getdivider - Get the clock divider for given id 2915 * @clock_id Id of the clock 2916 * @divider Divider value 2917 * 2918 * This function is used by master to get divider values 2919 * for any clock. 2920 * 2921 * Return: Returns status, either success or error+reason. 2922 */ 2923 enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id, 2924 unsigned int *divider) 2925 { 2926 enum pm_ret_status ret; 2927 2928 if (!pm_clock_valid(clock_id)) 2929 return PM_RET_ERROR_ARGS; 2930 2931 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2932 return PM_RET_ERROR_NOTSUPPORTED; 2933 2934 if (ISPLL(clock_id)) 2935 ret = pm_api_pll_get_divider(clock_id, divider); 2936 else 2937 ret = pm_api_clk_get_divider(clock_id, divider); 2938 2939 return ret; 2940 } 2941 2942 /** 2943 * pm_api_clock_setrate - Set the clock rate for given id 2944 * @clock_id Id of the clock 2945 * @rate Rate value in hz 2946 * 2947 * This function is used by master to set rate for any clock. 2948 * 2949 * Return: Returns status, either success or error+reason. 2950 */ 2951 enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id, 2952 uint64_t rate) 2953 { 2954 return PM_RET_ERROR_NOTSUPPORTED; 2955 } 2956 2957 /** 2958 * pm_api_clock_getrate - Get the clock rate for given id 2959 * @clock_id Id of the clock 2960 * @rate rate value in hz 2961 * 2962 * This function is used by master to get rate 2963 * for any clock. 2964 * 2965 * Return: Returns status, either success or error+reason. 2966 */ 2967 enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id, 2968 uint64_t *rate) 2969 { 2970 return PM_RET_ERROR_NOTSUPPORTED; 2971 } 2972 2973 /** 2974 * pm_api_clock_setparent - Set the clock parent for given id 2975 * @clock_id Id of the clock 2976 * @parent_id parent id 2977 * 2978 * This function is used by master to set parent for any clock. 2979 * 2980 * Return: Returns status, either success or error+reason. 2981 */ 2982 enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id, 2983 unsigned int parent_idx) 2984 { 2985 enum pm_ret_status ret = PM_RET_SUCCESS; 2986 struct pm_clock_node *nodes; 2987 uint8_t num_nodes; 2988 unsigned int reg, val; 2989 int32_t *clk_parents; 2990 unsigned int i = 0; 2991 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2992 2993 if (!pm_clock_valid(clock_id)) 2994 return PM_RET_ERROR_ARGS; 2995 2996 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2997 return PM_RET_ERROR_NOTSUPPORTED; 2998 2999 clk_parents = *clocks[clock_id].parents; 3000 3001 for (i = 0; i <= parent_idx; i++) 3002 if (clk_parents[i] == CLK_NA_PARENT) 3003 return PM_RET_ERROR_ARGS; 3004 3005 nodes = *clocks[clock_id].nodes; 3006 num_nodes = clocks[clock_id].num_nodes; 3007 for (i = 0; i < num_nodes; i++) { 3008 if (nodes->type == TYPE_MUX) { 3009 offset = nodes->offset; 3010 width = nodes->width; 3011 } 3012 nodes++; 3013 } 3014 if (width == NA_WIDTH) 3015 return PM_RET_ERROR_NOTSUPPORTED; 3016 3017 reg = clocks[clock_id].control_reg; 3018 val = parent_idx << offset; 3019 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val); 3020 3021 return ret; 3022 } 3023 3024 /** 3025 * pm_api_clock_getparent - Get the clock parent for given id 3026 * @clock_id Id of the clock 3027 * @parent_id parent id 3028 * 3029 * This function is used by master to get parent index 3030 * for any clock. 3031 * 3032 * Return: Returns status, either success or error+reason. 3033 */ 3034 enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id, 3035 unsigned int *parent_idx) 3036 { 3037 enum pm_ret_status ret = PM_RET_SUCCESS; 3038 struct pm_clock_node *nodes; 3039 uint8_t num_nodes; 3040 unsigned int reg, val; 3041 uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH; 3042 3043 if (!pm_clock_valid(clock_id)) 3044 return PM_RET_ERROR_ARGS; 3045 3046 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 3047 return PM_RET_ERROR_NOTSUPPORTED; 3048 3049 nodes = *clocks[clock_id].nodes; 3050 num_nodes = clocks[clock_id].num_nodes; 3051 3052 for (i = 0; i < num_nodes; i++) { 3053 if (nodes->type == TYPE_MUX) { 3054 offset = nodes->offset; 3055 width = nodes->width; 3056 } 3057 nodes++; 3058 } 3059 if (width == NA_WIDTH) 3060 return PM_RET_ERROR_NOTSUPPORTED; 3061 3062 reg = clocks[clock_id].control_reg; 3063 ret = pm_mmio_read(reg, &val); 3064 val >>= offset; 3065 val &= ((1U << width) - 1); 3066 3067 *parent_idx = val; 3068 3069 return ret; 3070 } 3071 3072 /** 3073 * pm_api_clk_set_pll_mode() - Set PLL mode 3074 * @pll PLL id 3075 * @mode Mode fraction/integar 3076 * 3077 * This function sets PLL mode. 3078 * 3079 * @return Returns status, either success or error+reason 3080 */ 3081 enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll, 3082 unsigned int mode) 3083 { 3084 enum pm_ret_status ret = PM_RET_SUCCESS; 3085 unsigned int reg; 3086 3087 if (!pm_clock_valid(pll)) 3088 return PM_RET_ERROR_ARGS; 3089 3090 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3091 return PM_RET_ERROR_NOTSUPPORTED; 3092 3093 if (!ISPLL(pll)) 3094 return PM_RET_ERROR_NOTSUPPORTED; 3095 3096 if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE) 3097 return PM_RET_ERROR_ARGS; 3098 3099 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3100 3101 ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK, 3102 mode << PLL_FRAC_MODE_SHIFT); 3103 3104 return ret; 3105 } 3106 3107 /** 3108 * pm_ioctl_get_pll_mode() - Get PLL mode 3109 * @pll PLL id 3110 * @mode Mode fraction/integar 3111 * 3112 * This function returns current PLL mode. 3113 * 3114 * @return Returns status, either success or error+reason 3115 */ 3116 enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll, 3117 unsigned int *mode) 3118 { 3119 enum pm_ret_status ret = PM_RET_SUCCESS; 3120 unsigned int val, reg; 3121 3122 if (!pm_clock_valid(pll)) 3123 return PM_RET_ERROR_ARGS; 3124 3125 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3126 return PM_RET_ERROR_NOTSUPPORTED; 3127 3128 if (!ISPLL(pll)) 3129 return PM_RET_ERROR_NOTSUPPORTED; 3130 3131 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3132 3133 ret = pm_mmio_read(reg, &val); 3134 val = val & PLL_FRAC_MODE_MASK; 3135 if (val == 0) 3136 *mode = PLL_INT_MODE; 3137 else 3138 *mode = PLL_FRAC_MODE; 3139 3140 return ret; 3141 } 3142 3143 /** 3144 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data 3145 * @pll PLL id 3146 * @data fraction data 3147 * 3148 * This function sets fraction data. It is valid for fraction 3149 * mode only. 3150 * 3151 * @return Returns status, either success or error+reason 3152 */ 3153 enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll, 3154 unsigned int data) 3155 { 3156 enum pm_ret_status ret = PM_RET_SUCCESS; 3157 unsigned int val, reg, mode = 0; 3158 3159 if (!pm_clock_valid(pll)) 3160 return PM_RET_ERROR_ARGS; 3161 3162 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3163 return PM_RET_ERROR_NOTSUPPORTED; 3164 3165 if (!ISPLL(pll)) 3166 return PM_RET_ERROR_NOTSUPPORTED; 3167 3168 ret = pm_api_clk_get_pll_mode(pll, &mode); 3169 if (ret != PM_RET_SUCCESS) 3170 return ret; 3171 if (mode == PLL_FRAC_MODE) { 3172 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3173 val = data << PLL_FRAC_DATA_SHIFT; 3174 ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val); 3175 } else { 3176 return PM_RET_ERROR_ARGS; 3177 } 3178 3179 return ret; 3180 } 3181 3182 /** 3183 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data 3184 * @pll PLL id 3185 * @data fraction data 3186 * 3187 * This function returns fraction data value. 3188 * 3189 * @return Returns status, either success or error+reason 3190 */ 3191 enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll, 3192 unsigned int *data) 3193 { 3194 enum pm_ret_status ret = PM_RET_SUCCESS; 3195 unsigned int val, reg; 3196 3197 if (!pm_clock_valid(pll)) 3198 return PM_RET_ERROR_ARGS; 3199 3200 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3201 return PM_RET_ERROR_NOTSUPPORTED; 3202 3203 if (!ISPLL(pll)) 3204 return PM_RET_ERROR_NOTSUPPORTED; 3205 3206 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3207 3208 ret = pm_mmio_read(reg, &val); 3209 *data = (val & PLL_FRAC_DATA_MASK); 3210 3211 return ret; 3212 } 3213