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