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_num_clocks() - PM call to request number of clocks 2311 * @nclocks Number of clocks 2312 * 2313 * This function is used by master to get number of clocks. 2314 * 2315 * @return Returns success. 2316 */ 2317 enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks) 2318 { 2319 *nclocks = CLK_MAX; 2320 2321 return PM_RET_SUCCESS; 2322 } 2323 2324 /** 2325 * pm_api_clock_get_name() - PM call to request a clock's name 2326 * @clock_id Clock ID 2327 * @name Name of clock (max 16 bytes) 2328 * 2329 * This function is used by master to get nmae of clock specified 2330 * by given clock ID. 2331 * 2332 * @return Returns success. In case of error, name data is 0. 2333 */ 2334 enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) 2335 { 2336 if (clock_id == CLK_MAX) 2337 memcpy(name, END_OF_CLK, CLK_NAME_LEN); 2338 else if (!pm_clock_valid(clock_id)) 2339 memset(name, 0, CLK_NAME_LEN); 2340 else if (clock_id < CLK_MAX_OUTPUT_CLK) 2341 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN); 2342 else 2343 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name, 2344 CLK_NAME_LEN); 2345 2346 return PM_RET_SUCCESS; 2347 } 2348 2349 /** 2350 * pm_api_clock_get_topology() - PM call to request a clock's topology 2351 * @clock_id Clock ID 2352 * @index Topology index for next toplogy node 2353 * @topology Buffer to store nodes in topology and flags 2354 * 2355 * This function is used by master to get topology information for the 2356 * clock specified by given clock ID. Each response would return 3 2357 * topology nodes. To get next nodes, caller needs to call this API with 2358 * index of next node. Index starts from 0. 2359 * 2360 * @return Returns status, either success or error+reason 2361 */ 2362 enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, 2363 unsigned int index, 2364 uint32_t *topology) 2365 { 2366 struct pm_clock_node *clock_nodes; 2367 uint8_t num_nodes; 2368 unsigned int i; 2369 2370 if (!pm_clock_valid(clock_id)) 2371 return PM_RET_ERROR_ARGS; 2372 2373 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2374 return PM_RET_ERROR_NOTSUPPORTED; 2375 2376 2377 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN); 2378 clock_nodes = *clocks[clock_id].nodes; 2379 num_nodes = clocks[clock_id].num_nodes; 2380 2381 /* Skip parent till index */ 2382 if (index >= num_nodes) 2383 return PM_RET_SUCCESS; 2384 2385 for (i = 0; i < 3U; i++) { 2386 if ((index + i) == num_nodes) 2387 break; 2388 topology[i] = clock_nodes[index + i].type; 2389 topology[i] |= clock_nodes[index + i].clkflags << 2390 CLK_CLKFLAGS_SHIFT; 2391 topology[i] |= clock_nodes[index + i].typeflags << 2392 CLK_TYPEFLAGS_SHIFT; 2393 } 2394 2395 return PM_RET_SUCCESS; 2396 } 2397 2398 /** 2399 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed 2400 * factor parameters for fixed clock 2401 * @clock_id Clock ID 2402 * @mul Multiplication value 2403 * @div Divisor value 2404 * 2405 * This function is used by master to get fixed factor parameers for the 2406 * fixed clock. This API is application only for the fixed clock. 2407 * 2408 * @return Returns status, either success or error+reason 2409 */ 2410 enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id, 2411 uint32_t *mul, 2412 uint32_t *div) 2413 { 2414 struct pm_clock_node *clock_nodes; 2415 uint8_t num_nodes; 2416 unsigned int type, i; 2417 2418 if (!pm_clock_valid(clock_id)) 2419 return PM_RET_ERROR_ARGS; 2420 2421 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2422 return PM_RET_ERROR_NOTSUPPORTED; 2423 2424 clock_nodes = *clocks[clock_id].nodes; 2425 num_nodes = clocks[clock_id].num_nodes; 2426 2427 for (i = 0; i < num_nodes; i++) { 2428 type = clock_nodes[i].type; 2429 if (type == TYPE_FIXEDFACTOR) { 2430 *mul = clock_nodes[i].mult; 2431 *div = clock_nodes[i].div; 2432 break; 2433 } 2434 } 2435 2436 /* Clock is not fixed clock */ 2437 if (i == num_nodes) 2438 return PM_RET_ERROR_ARGS; 2439 2440 return PM_RET_SUCCESS; 2441 } 2442 2443 /** 2444 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents 2445 * @clock_id Clock ID 2446 * @index Index of next parent 2447 * @parents Parents of the given clock 2448 * 2449 * This function is used by master to get clock's parents information. 2450 * This API will return 3 parents with a single response. To get other 2451 * parents, master should call same API in loop with new parent index 2452 * till error is returned. 2453 * 2454 * E.g First call should have index 0 which will return parents 0, 1 and 2455 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and 2456 * so on. 2457 * 2458 * @return Returns status, either success or error+reason 2459 */ 2460 enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, 2461 unsigned int index, 2462 uint32_t *parents) 2463 { 2464 unsigned int i; 2465 int32_t *clk_parents; 2466 2467 if (!pm_clock_valid(clock_id)) 2468 return PM_RET_ERROR_ARGS; 2469 2470 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2471 return PM_RET_ERROR_NOTSUPPORTED; 2472 2473 clk_parents = *clocks[clock_id].parents; 2474 if (clk_parents == NULL) 2475 return PM_RET_ERROR_ARGS; 2476 2477 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN); 2478 2479 /* Skip parent till index */ 2480 for (i = 0; i < index; i++) 2481 if (clk_parents[i] == CLK_NA_PARENT) 2482 return PM_RET_SUCCESS; 2483 2484 for (i = 0; i < 3; i++) { 2485 parents[i] = clk_parents[index + i]; 2486 if (clk_parents[index + i] == CLK_NA_PARENT) 2487 break; 2488 } 2489 2490 return PM_RET_SUCCESS; 2491 } 2492 2493 /** 2494 * pm_api_clock_get_attributes() - PM call to request a clock's attributes 2495 * @clock_id Clock ID 2496 * @attr Clock attributes 2497 * 2498 * This function is used by master to get clock's attributes 2499 * (e.g. valid, clock type, etc). 2500 * 2501 * @return Returns status, either success or error+reason 2502 */ 2503 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, 2504 uint32_t *attr) 2505 { 2506 if (clock_id >= CLK_MAX) 2507 return PM_RET_ERROR_ARGS; 2508 2509 /* Clock valid bit */ 2510 *attr = pm_clock_valid(clock_id); 2511 2512 /* If clock needs to be enabled during init */ 2513 *attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT); 2514 2515 /* Clock type (Output/External) */ 2516 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT); 2517 2518 return PM_RET_SUCCESS; 2519 } 2520 2521 /** 2522 * pll_get_lockbit() - Returns lockbit index for pll id 2523 * @pll_id: Id of the pll 2524 * 2525 * This function return the PLL_LOCKED bit index in 2526 * pll status register accosiated with given pll id. 2527 * 2528 * Return: Returns bit index 2529 */ 2530 static int pll_get_lockbit(unsigned int pll_id) 2531 { 2532 switch (pll_id) { 2533 case CLK_APLL_INT: 2534 case CLK_IOPLL_INT: 2535 return 0; 2536 case CLK_DPLL_INT: 2537 case CLK_RPLL_INT: 2538 return 1; 2539 case CLK_VPLL_INT: 2540 return 2; 2541 default: 2542 return -1; 2543 } 2544 } 2545 2546 /** 2547 * pm_api_pll_bypass_and_reset() - Bypass and reset PLL 2548 * @clock_id: Id of the PLL 2549 * 2550 * This function is to bypass and reset PLL. 2551 */ 2552 static inline enum pm_ret_status 2553 pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag) 2554 { 2555 enum pm_ret_status ret = PM_RET_SUCCESS; 2556 unsigned int reg, val; 2557 int lockbit; 2558 2559 reg = clocks[clock_id].control_reg; 2560 2561 if (flag & CLK_PLL_RESET_ASSERT) { 2562 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK); 2563 if (ret != PM_RET_SUCCESS) 2564 return ret; 2565 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK, 2566 PLLCTRL_RESET_MASK); 2567 if (ret != PM_RET_SUCCESS) 2568 return ret; 2569 } 2570 if (flag & CLK_PLL_RESET_RELEASE) { 2571 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK, 2572 ~PLLCTRL_RESET_MASK); 2573 if (ret != PM_RET_SUCCESS) 2574 return ret; 2575 2576 lockbit = pll_get_lockbit(clock_id); 2577 do { 2578 ret = pm_mmio_read(clocks[clock_id].status_reg, &val); 2579 if (ret != PM_RET_SUCCESS) 2580 return ret; 2581 } while ((lockbit >= 0) && !(val & (1 << lockbit))); 2582 2583 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, 2584 ~(unsigned int)PLLCTRL_BP_MASK); 2585 } 2586 return ret; 2587 } 2588 2589 /** 2590 * pm_api_clk_enable_disable() - Enable/Disable the clock for given id 2591 * @clock_id: Id of the clock to be enabled 2592 * @enable: Enable(1)/Disable(0) 2593 * 2594 * This function is to enable/disable the clock which is not PLL. 2595 * 2596 * Return: Returns status, either success or error+reason. 2597 */ 2598 static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id, 2599 unsigned int enable) 2600 { 2601 enum pm_ret_status ret = PM_RET_SUCCESS; 2602 struct pm_clock_node *nodes = *clocks[clock_id].nodes; 2603 uint8_t num_nodes = clocks[clock_id].num_nodes; 2604 unsigned int reg, val; 2605 uint8_t i = 0; 2606 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2607 2608 if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX || 2609 clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX) 2610 reg = clocks[clock_id].status_reg; 2611 else 2612 reg = clocks[clock_id].control_reg; 2613 2614 for (i = 0; i < num_nodes; i++) { 2615 if (nodes->type == TYPE_GATE) { 2616 offset = nodes->offset; 2617 width = nodes->width; 2618 break; 2619 } 2620 nodes++; 2621 } 2622 if (width == NA_WIDTH) 2623 return PM_RET_ERROR_NOTSUPPORTED; 2624 2625 ret = pm_mmio_read(reg, &val); 2626 if (ret != PM_RET_SUCCESS) 2627 return ret; 2628 if ((val & BIT_MASK(offset, width)) == enable) 2629 return PM_RET_SUCCESS; 2630 2631 if (enable == 0) 2632 val &= ~(BIT_MASK(offset, width)); 2633 else 2634 val |= BIT_MASK(offset, width); 2635 2636 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val); 2637 2638 return ret; 2639 } 2640 2641 /** 2642 * pm_api_clock_enable() - Enable the clock for given id 2643 * @clock_id: Id of the clock to be enabled 2644 * 2645 * This function is used by master to enable the clock 2646 * including peripherals and PLL clocks. 2647 * 2648 * Return: Returns status, either success or error+reason. 2649 */ 2650 enum pm_ret_status pm_api_clock_enable(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 if (ISPLL(clock_id)) 2661 ret = pm_api_pll_bypass_and_reset(clock_id, 2662 CLK_PLL_RESET_PULSE); 2663 else 2664 ret = pm_api_clk_enable_disable(clock_id, 1); 2665 2666 return ret; 2667 } 2668 2669 /** 2670 * pm_api_clock_disable - Disable the clock for given id 2671 * @clock_id Id of the clock to be disable 2672 * 2673 * This function is used by master to disable the clock 2674 * including peripherals and PLL clocks. 2675 * 2676 * Return: Returns status, either success or error+reason. 2677 */ 2678 2679 enum pm_ret_status pm_api_clock_disable(unsigned int clock_id) 2680 { 2681 enum pm_ret_status ret = PM_RET_SUCCESS; 2682 2683 if (!pm_clock_valid(clock_id)) 2684 return PM_RET_ERROR_ARGS; 2685 2686 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2687 return PM_RET_ERROR_NOTSUPPORTED; 2688 2689 if (ISPLL(clock_id)) 2690 ret = pm_api_pll_bypass_and_reset(clock_id, 2691 CLK_PLL_RESET_ASSERT); 2692 else 2693 ret = pm_api_clk_enable_disable(clock_id, 0); 2694 2695 return ret; 2696 } 2697 2698 /** 2699 * pm_api_get_pll_state() - Get state of PLL 2700 * @clock_id Id of the PLL 2701 * @state State of PLL(1: Enable, 0: Reset) 2702 * 2703 * This function is to check state of PLL. 2704 */ 2705 static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id, 2706 unsigned int *state) 2707 { 2708 enum pm_ret_status ret = PM_RET_SUCCESS; 2709 unsigned int reg, val; 2710 2711 reg = clocks[clock_id].control_reg; 2712 2713 ret = pm_mmio_read(reg, &val); 2714 2715 /* state: 2716 * 1 - PLL is enabled 2717 * 0 - PLL is in reset state 2718 */ 2719 *state = !(val & PLLCTRL_RESET_MASK); 2720 return ret; 2721 } 2722 2723 /** 2724 * pm_api_get_clk_state() - Get the state of clock for given id 2725 * @clock_id: Id of the clock to be enabled 2726 * @state: Enable(1)/Disable(0) 2727 * 2728 * This function is to get state of the clock which is not PLL. 2729 * 2730 * Return: Returns status, either success or error+reason. 2731 */ 2732 static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id, 2733 unsigned int *state) 2734 { 2735 enum pm_ret_status ret = PM_RET_SUCCESS; 2736 struct pm_clock_node *nodes = *clocks[clock_id].nodes; 2737 uint8_t num_nodes = clocks[clock_id].num_nodes; 2738 unsigned int reg, val; 2739 uint8_t i = 0; 2740 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 2741 2742 reg = clocks[clock_id].control_reg; 2743 2744 for (i = 0; i < num_nodes; i++) { 2745 if (nodes->type == TYPE_GATE) { 2746 offset = nodes->offset; 2747 width = nodes->width; 2748 } 2749 nodes++; 2750 } 2751 if (width == NA_WIDTH) 2752 return PM_RET_ERROR_NOTSUPPORTED; 2753 2754 ret = pm_mmio_read(reg, &val); 2755 *state = (val & BIT_MASK(offset, width)) >> offset; 2756 2757 return ret; 2758 } 2759 2760 /** 2761 * pm_api_clock_getstate - Get the clock state for given id 2762 * @clock_id Id of the clock to be queried 2763 * @state 1/0 (Enabled/Disabled) 2764 * 2765 * This function is used by master to get the state of clock 2766 * including peripherals and PLL clocks. 2767 * 2768 * Return: Returns status, either success or error+reason. 2769 */ 2770 enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id, 2771 unsigned int *state) 2772 { 2773 enum pm_ret_status ret = PM_RET_SUCCESS; 2774 2775 if (!pm_clock_valid(clock_id)) 2776 return PM_RET_ERROR_ARGS; 2777 2778 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2779 return PM_RET_ERROR_NOTSUPPORTED; 2780 2781 if (ISPLL(clock_id)) 2782 ret = pm_api_get_pll_state(clock_id, state); 2783 else 2784 ret = pm_api_get_clk_state(clock_id, state); 2785 2786 return ret; 2787 } 2788 2789 static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id, 2790 uint32_t divider) 2791 { 2792 enum pm_ret_status ret = PM_RET_SUCCESS; 2793 struct pm_clock_node *nodes; 2794 uint8_t num_nodes; 2795 uint16_t div1, div2; 2796 unsigned int reg, mask = 0, val = 0, i; 2797 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT; 2798 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT; 2799 2800 div1 = (uint16_t)(divider & 0xFFFFU); 2801 div2 = (uint16_t)((divider >> 16) & 0xFFFFU); 2802 2803 reg = clocks[clock_id].control_reg; 2804 2805 nodes = *clocks[clock_id].nodes; 2806 num_nodes = clocks[clock_id].num_nodes; 2807 for (i = 0; i < num_nodes; i++) { 2808 if (nodes->type == TYPE_DIV1) { 2809 div1_offset = nodes->offset; 2810 div1_width = nodes->width; 2811 } 2812 if (nodes->type == TYPE_DIV2) { 2813 div2_offset = nodes->offset; 2814 div2_width = nodes->width; 2815 } 2816 nodes++; 2817 } 2818 2819 if (div1 != (uint16_t)-1) { 2820 if (div1_width == NA_WIDTH) 2821 return PM_RET_ERROR_NOTSUPPORTED; 2822 val |= div1 << div1_offset; 2823 mask |= BIT_MASK(div1_offset, div1_width); 2824 } 2825 if (div2 != (uint16_t)-1) { 2826 if (div2_width == NA_WIDTH) 2827 return PM_RET_ERROR_NOTSUPPORTED; 2828 val |= div2 << div2_offset; 2829 mask |= BIT_MASK(div2_offset, div2_width); 2830 } 2831 ret = pm_mmio_write(reg, mask, val); 2832 2833 return ret; 2834 } 2835 2836 static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id, 2837 unsigned int divider) 2838 { 2839 unsigned int reg = clocks[clock_id].control_reg; 2840 2841 return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT); 2842 } 2843 2844 /** 2845 * pm_api_clock_setdivider - Set the clock divider for given id 2846 * @clock_id Id of the clock 2847 * @divider Divider value 2848 * 2849 * This function is used by master to set divider for any clock 2850 * to achieve desired rate. 2851 * 2852 * Return: Returns status, either success or error+reason. 2853 */ 2854 enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id, 2855 unsigned int divider) 2856 { 2857 enum pm_ret_status ret; 2858 2859 if (!pm_clock_valid(clock_id)) 2860 return PM_RET_ERROR_ARGS; 2861 2862 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2863 return PM_RET_ERROR_NOTSUPPORTED; 2864 2865 if (ISPLL(clock_id)) 2866 ret = pm_api_pll_set_divider(clock_id, divider); 2867 else 2868 ret = pm_api_clk_set_divider(clock_id, divider); 2869 2870 return ret; 2871 } 2872 2873 static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id, 2874 uint32_t *divider) 2875 { 2876 enum pm_ret_status ret = PM_RET_SUCCESS; 2877 struct pm_clock_node *nodes; 2878 uint8_t num_nodes; 2879 unsigned int reg, val, i, div1 = 0, div2 = 0; 2880 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT; 2881 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT; 2882 2883 reg = clocks[clock_id].control_reg; 2884 2885 nodes = *clocks[clock_id].nodes; 2886 num_nodes = clocks[clock_id].num_nodes; 2887 for (i = 0; i < num_nodes; i++) { 2888 if (nodes->type == TYPE_DIV1) { 2889 div1_offset = nodes->offset; 2890 div1_width = nodes->width; 2891 } 2892 if (nodes->type == TYPE_DIV2) { 2893 div2_offset = nodes->offset; 2894 div2_width = nodes->width; 2895 } 2896 nodes++; 2897 } 2898 2899 ret = pm_mmio_read(reg, &val); 2900 2901 if (div1_width == NA_WIDTH) 2902 return PM_RET_ERROR_ARGS; 2903 2904 div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset; 2905 2906 if (div2_width != NA_WIDTH) 2907 div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset; 2908 2909 *divider = div1 | (div2 << 16); 2910 2911 return ret; 2912 } 2913 2914 static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id, 2915 unsigned int *divider) 2916 { 2917 enum pm_ret_status ret = PM_RET_SUCCESS; 2918 unsigned int reg, val; 2919 2920 reg = clocks[clock_id].control_reg; 2921 2922 ret = pm_mmio_read(reg, &val); 2923 *divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; 2924 2925 return ret; 2926 } 2927 2928 /** 2929 * pm_api_clock_getdivider - Get the clock divider for given id 2930 * @clock_id Id of the clock 2931 * @divider Divider value 2932 * 2933 * This function is used by master to get divider values 2934 * for any clock. 2935 * 2936 * Return: Returns status, either success or error+reason. 2937 */ 2938 enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id, 2939 unsigned int *divider) 2940 { 2941 enum pm_ret_status ret; 2942 2943 if (!pm_clock_valid(clock_id)) 2944 return PM_RET_ERROR_ARGS; 2945 2946 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 2947 return PM_RET_ERROR_NOTSUPPORTED; 2948 2949 if (ISPLL(clock_id)) 2950 ret = pm_api_pll_get_divider(clock_id, divider); 2951 else 2952 ret = pm_api_clk_get_divider(clock_id, divider); 2953 2954 return ret; 2955 } 2956 2957 /** 2958 * pm_api_clock_setrate - Set 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 set rate for any clock. 2963 * 2964 * Return: Returns status, either success or error+reason. 2965 */ 2966 enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id, 2967 uint64_t rate) 2968 { 2969 return PM_RET_ERROR_NOTSUPPORTED; 2970 } 2971 2972 /** 2973 * pm_api_clock_getrate - Get the clock rate for given id 2974 * @clock_id Id of the clock 2975 * @rate rate value in hz 2976 * 2977 * This function is used by master to get rate 2978 * for any clock. 2979 * 2980 * Return: Returns status, either success or error+reason. 2981 */ 2982 enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id, 2983 uint64_t *rate) 2984 { 2985 return PM_RET_ERROR_NOTSUPPORTED; 2986 } 2987 2988 /** 2989 * pm_api_clock_setparent - Set the clock parent for given id 2990 * @clock_id Id of the clock 2991 * @parent_id parent id 2992 * 2993 * This function is used by master to set parent for any clock. 2994 * 2995 * Return: Returns status, either success or error+reason. 2996 */ 2997 enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id, 2998 unsigned int parent_idx) 2999 { 3000 enum pm_ret_status ret = PM_RET_SUCCESS; 3001 struct pm_clock_node *nodes; 3002 uint8_t num_nodes; 3003 unsigned int reg, val; 3004 int32_t *clk_parents; 3005 unsigned int i = 0; 3006 uint8_t offset = NA_SHIFT, width = NA_WIDTH; 3007 3008 if (!pm_clock_valid(clock_id)) 3009 return PM_RET_ERROR_ARGS; 3010 3011 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 3012 return PM_RET_ERROR_NOTSUPPORTED; 3013 3014 clk_parents = *clocks[clock_id].parents; 3015 3016 for (i = 0; i <= parent_idx; i++) 3017 if (clk_parents[i] == CLK_NA_PARENT) 3018 return PM_RET_ERROR_ARGS; 3019 3020 nodes = *clocks[clock_id].nodes; 3021 num_nodes = clocks[clock_id].num_nodes; 3022 for (i = 0; i < num_nodes; i++) { 3023 if (nodes->type == TYPE_MUX) { 3024 offset = nodes->offset; 3025 width = nodes->width; 3026 } 3027 nodes++; 3028 } 3029 if (width == NA_WIDTH) 3030 return PM_RET_ERROR_NOTSUPPORTED; 3031 3032 reg = clocks[clock_id].control_reg; 3033 val = parent_idx << offset; 3034 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val); 3035 3036 return ret; 3037 } 3038 3039 /** 3040 * pm_api_clock_getparent - Get the clock parent for given id 3041 * @clock_id Id of the clock 3042 * @parent_id parent id 3043 * 3044 * This function is used by master to get parent index 3045 * for any clock. 3046 * 3047 * Return: Returns status, either success or error+reason. 3048 */ 3049 enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id, 3050 unsigned int *parent_idx) 3051 { 3052 enum pm_ret_status ret = PM_RET_SUCCESS; 3053 struct pm_clock_node *nodes; 3054 uint8_t num_nodes; 3055 unsigned int reg, val; 3056 uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH; 3057 3058 if (!pm_clock_valid(clock_id)) 3059 return PM_RET_ERROR_ARGS; 3060 3061 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) 3062 return PM_RET_ERROR_NOTSUPPORTED; 3063 3064 nodes = *clocks[clock_id].nodes; 3065 num_nodes = clocks[clock_id].num_nodes; 3066 3067 for (i = 0; i < num_nodes; i++) { 3068 if (nodes->type == TYPE_MUX) { 3069 offset = nodes->offset; 3070 width = nodes->width; 3071 } 3072 nodes++; 3073 } 3074 if (width == NA_WIDTH) 3075 return PM_RET_ERROR_NOTSUPPORTED; 3076 3077 reg = clocks[clock_id].control_reg; 3078 ret = pm_mmio_read(reg, &val); 3079 val >>= offset; 3080 val &= ((1U << width) - 1); 3081 3082 *parent_idx = val; 3083 3084 return ret; 3085 } 3086 3087 /** 3088 * pm_api_clk_set_pll_mode() - Set PLL mode 3089 * @pll PLL id 3090 * @mode Mode fraction/integar 3091 * 3092 * This function sets PLL mode. 3093 * 3094 * @return Returns status, either success or error+reason 3095 */ 3096 enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll, 3097 unsigned int mode) 3098 { 3099 enum pm_ret_status ret = PM_RET_SUCCESS; 3100 unsigned int reg; 3101 3102 if (!pm_clock_valid(pll)) 3103 return PM_RET_ERROR_ARGS; 3104 3105 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3106 return PM_RET_ERROR_NOTSUPPORTED; 3107 3108 if (!ISPLL(pll)) 3109 return PM_RET_ERROR_NOTSUPPORTED; 3110 3111 if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE) 3112 return PM_RET_ERROR_ARGS; 3113 3114 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3115 3116 ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK, 3117 mode << PLL_FRAC_MODE_SHIFT); 3118 3119 return ret; 3120 } 3121 3122 /** 3123 * pm_ioctl_get_pll_mode() - Get PLL mode 3124 * @pll PLL id 3125 * @mode Mode fraction/integar 3126 * 3127 * This function returns current PLL mode. 3128 * 3129 * @return Returns status, either success or error+reason 3130 */ 3131 enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll, 3132 unsigned int *mode) 3133 { 3134 enum pm_ret_status ret = PM_RET_SUCCESS; 3135 unsigned int val, reg; 3136 3137 if (!pm_clock_valid(pll)) 3138 return PM_RET_ERROR_ARGS; 3139 3140 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3141 return PM_RET_ERROR_NOTSUPPORTED; 3142 3143 if (!ISPLL(pll)) 3144 return PM_RET_ERROR_NOTSUPPORTED; 3145 3146 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3147 3148 ret = pm_mmio_read(reg, &val); 3149 val = val & PLL_FRAC_MODE_MASK; 3150 if (val == 0) 3151 *mode = PLL_INT_MODE; 3152 else 3153 *mode = PLL_FRAC_MODE; 3154 3155 return ret; 3156 } 3157 3158 /** 3159 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data 3160 * @pll PLL id 3161 * @data fraction data 3162 * 3163 * This function sets fraction data. It is valid for fraction 3164 * mode only. 3165 * 3166 * @return Returns status, either success or error+reason 3167 */ 3168 enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll, 3169 unsigned int data) 3170 { 3171 enum pm_ret_status ret = PM_RET_SUCCESS; 3172 unsigned int val, reg, mode = 0; 3173 3174 if (!pm_clock_valid(pll)) 3175 return PM_RET_ERROR_ARGS; 3176 3177 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3178 return PM_RET_ERROR_NOTSUPPORTED; 3179 3180 if (!ISPLL(pll)) 3181 return PM_RET_ERROR_NOTSUPPORTED; 3182 3183 ret = pm_api_clk_get_pll_mode(pll, &mode); 3184 if (ret != PM_RET_SUCCESS) 3185 return ret; 3186 if (mode == PLL_FRAC_MODE) { 3187 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3188 val = data << PLL_FRAC_DATA_SHIFT; 3189 ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val); 3190 } else { 3191 return PM_RET_ERROR_ARGS; 3192 } 3193 3194 return ret; 3195 } 3196 3197 /** 3198 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data 3199 * @pll PLL id 3200 * @data fraction data 3201 * 3202 * This function returns fraction data value. 3203 * 3204 * @return Returns status, either success or error+reason 3205 */ 3206 enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll, 3207 unsigned int *data) 3208 { 3209 enum pm_ret_status ret = PM_RET_SUCCESS; 3210 unsigned int val, reg; 3211 3212 if (!pm_clock_valid(pll)) 3213 return PM_RET_ERROR_ARGS; 3214 3215 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) 3216 return PM_RET_ERROR_NOTSUPPORTED; 3217 3218 if (!ISPLL(pll)) 3219 return PM_RET_ERROR_NOTSUPPORTED; 3220 3221 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; 3222 3223 ret = pm_mmio_read(reg, &val); 3224 *data = (val & PLL_FRAC_DATA_MASK); 3225 3226 return ret; 3227 } 3228