1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * SAM9X7 PMC code. 4 * 5 * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries 6 * 7 * Author: Varshini Rajendran <varshini.rajendran@microchip.com> 8 * 9 */ 10 #include <linux/clk.h> 11 #include <linux/clk-provider.h> 12 #include <linux/mfd/syscon.h> 13 #include <linux/slab.h> 14 15 #include <dt-bindings/clock/at91.h> 16 17 #include "pmc.h" 18 19 static DEFINE_SPINLOCK(pmc_pll_lock); 20 static DEFINE_SPINLOCK(mck_lock); 21 22 /** 23 * enum pll_ids - PLL clocks identifiers 24 * @PLL_ID_PLLA: PLLA identifier 25 * @PLL_ID_UPLL: UPLL identifier 26 * @PLL_ID_AUDIO: Audio PLL identifier 27 * @PLL_ID_LVDS: LVDS PLL identifier 28 * @PLL_ID_PLLA_DIV2: PLLA DIV2 identifier 29 * @PLL_ID_MAX: Max PLL Identifier 30 */ 31 enum pll_ids { 32 PLL_ID_PLLA, 33 PLL_ID_UPLL, 34 PLL_ID_AUDIO, 35 PLL_ID_LVDS, 36 PLL_ID_PLLA_DIV2, 37 PLL_ID_MAX, 38 }; 39 40 /** 41 * enum pll_type - PLL type identifiers 42 * @PLL_TYPE_FRAC: fractional PLL identifier 43 * @PLL_TYPE_DIV: divider PLL identifier 44 */ 45 enum pll_type { 46 PLL_TYPE_FRAC, 47 PLL_TYPE_DIV, 48 }; 49 50 static const struct clk_master_characteristics mck_characteristics = { 51 .output = { .min = 32000000, .max = 266666667 }, 52 .divisors = { 1, 2, 4, 3, 5}, 53 .have_div3_pres = 1, 54 }; 55 56 static const struct clk_master_layout sam9x7_master_layout = { 57 .mask = 0x373, 58 .pres_shift = 4, 59 .offset = 0x28, 60 }; 61 62 /* Fractional PLL core output range. */ 63 static const struct clk_range plla_core_outputs[] = { 64 { .min = 375000000, .max = 1600000000 }, 65 }; 66 67 static const struct clk_range upll_core_outputs[] = { 68 { .min = 600000000, .max = 1200000000 }, 69 }; 70 71 static const struct clk_range lvdspll_core_outputs[] = { 72 { .min = 400000000, .max = 800000000 }, 73 }; 74 75 static const struct clk_range audiopll_core_outputs[] = { 76 { .min = 400000000, .max = 800000000 }, 77 }; 78 79 static const struct clk_range plladiv2_core_outputs[] = { 80 { .min = 375000000, .max = 1600000000 }, 81 }; 82 83 /* Fractional PLL output range. */ 84 static const struct clk_range plla_outputs[] = { 85 { .min = 732421, .max = 800000000 }, 86 }; 87 88 static const struct clk_range upll_outputs[] = { 89 { .min = 300000000, .max = 600000000 }, 90 }; 91 92 static const struct clk_range lvdspll_outputs[] = { 93 { .min = 10000000, .max = 800000000 }, 94 }; 95 96 static const struct clk_range audiopll_outputs[] = { 97 { .min = 10000000, .max = 800000000 }, 98 }; 99 100 static const struct clk_range plladiv2_outputs[] = { 101 { .min = 366210, .max = 400000000 }, 102 }; 103 104 /* PLL characteristics. */ 105 static const struct clk_pll_characteristics plla_characteristics = { 106 .input = { .min = 20000000, .max = 50000000 }, 107 .num_output = ARRAY_SIZE(plla_outputs), 108 .output = plla_outputs, 109 .core_output = plla_core_outputs, 110 }; 111 112 static const struct clk_pll_characteristics upll_characteristics = { 113 .input = { .min = 20000000, .max = 50000000 }, 114 .num_output = ARRAY_SIZE(upll_outputs), 115 .output = upll_outputs, 116 .core_output = upll_core_outputs, 117 .upll = true, 118 }; 119 120 static const struct clk_pll_characteristics lvdspll_characteristics = { 121 .input = { .min = 20000000, .max = 50000000 }, 122 .num_output = ARRAY_SIZE(lvdspll_outputs), 123 .output = lvdspll_outputs, 124 .core_output = lvdspll_core_outputs, 125 }; 126 127 static const struct clk_pll_characteristics audiopll_characteristics = { 128 .input = { .min = 20000000, .max = 50000000 }, 129 .num_output = ARRAY_SIZE(audiopll_outputs), 130 .output = audiopll_outputs, 131 .core_output = audiopll_core_outputs, 132 }; 133 134 static const struct clk_pll_characteristics plladiv2_characteristics = { 135 .input = { .min = 20000000, .max = 50000000 }, 136 .num_output = ARRAY_SIZE(plladiv2_outputs), 137 .output = plladiv2_outputs, 138 .core_output = plladiv2_core_outputs, 139 }; 140 141 /* Layout for fractional PLL ID PLLA. */ 142 static const struct clk_pll_layout plla_frac_layout = { 143 .mul_mask = GENMASK(31, 24), 144 .frac_mask = GENMASK(21, 0), 145 .mul_shift = 24, 146 .frac_shift = 0, 147 .div2 = 1, 148 }; 149 150 /* Layout for fractional PLLs. */ 151 static const struct clk_pll_layout pll_frac_layout = { 152 .mul_mask = GENMASK(31, 24), 153 .frac_mask = GENMASK(21, 0), 154 .mul_shift = 24, 155 .frac_shift = 0, 156 }; 157 158 /* Layout for DIV PLLs. */ 159 static const struct clk_pll_layout pll_divpmc_layout = { 160 .div_mask = GENMASK(7, 0), 161 .endiv_mask = BIT(29), 162 .div_shift = 0, 163 .endiv_shift = 29, 164 }; 165 166 /* Layout for DIV PLL ID PLLADIV2. */ 167 static const struct clk_pll_layout plladiv2_divpmc_layout = { 168 .div_mask = GENMASK(7, 0), 169 .endiv_mask = BIT(29), 170 .div_shift = 0, 171 .endiv_shift = 29, 172 .div2 = 1, 173 }; 174 175 /* Layout for DIVIO dividers. */ 176 static const struct clk_pll_layout pll_divio_layout = { 177 .div_mask = GENMASK(19, 12), 178 .endiv_mask = BIT(30), 179 .div_shift = 12, 180 .endiv_shift = 30, 181 }; 182 183 /* 184 * PLL clocks description 185 * @n: clock name 186 * @p: clock parent 187 * @l: clock layout 188 * @t: clock type 189 * @c: pll characteristics 190 * @f: clock flags 191 * @eid: export index in sam9x7->chws[] array 192 */ 193 static const struct { 194 const char *n; 195 const char *p; 196 const struct clk_pll_layout *l; 197 u8 t; 198 const struct clk_pll_characteristics *c; 199 unsigned long f; 200 u8 eid; 201 } sam9x7_plls[][3] = { 202 [PLL_ID_PLLA] = { 203 { 204 .n = "plla_fracck", 205 .p = "mainck", 206 .l = &plla_frac_layout, 207 .t = PLL_TYPE_FRAC, 208 /* 209 * This feeds plla_divpmcck which feeds CPU. It should 210 * not be disabled. 211 */ 212 .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 213 .c = &plla_characteristics, 214 }, 215 216 { 217 .n = "plla_divpmcck", 218 .p = "plla_fracck", 219 .l = &pll_divpmc_layout, 220 .t = PLL_TYPE_DIV, 221 /* This feeds CPU. It should not be disabled */ 222 .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 223 .eid = PMC_PLLACK, 224 .c = &plla_characteristics, 225 }, 226 }, 227 228 [PLL_ID_UPLL] = { 229 { 230 .n = "upll_fracck", 231 .p = "main_osc", 232 .l = &pll_frac_layout, 233 .t = PLL_TYPE_FRAC, 234 .f = CLK_SET_RATE_GATE, 235 .c = &upll_characteristics, 236 }, 237 238 { 239 .n = "upll_divpmcck", 240 .p = "upll_fracck", 241 .l = &pll_divpmc_layout, 242 .t = PLL_TYPE_DIV, 243 .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 244 CLK_SET_RATE_PARENT, 245 .eid = PMC_UTMI, 246 .c = &upll_characteristics, 247 }, 248 }, 249 250 [PLL_ID_AUDIO] = { 251 { 252 .n = "audiopll_fracck", 253 .p = "main_osc", 254 .l = &pll_frac_layout, 255 .f = CLK_SET_RATE_GATE, 256 .c = &audiopll_characteristics, 257 .t = PLL_TYPE_FRAC, 258 }, 259 260 { 261 .n = "audiopll_divpmcck", 262 .p = "audiopll_fracck", 263 .l = &pll_divpmc_layout, 264 .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 265 CLK_SET_RATE_PARENT, 266 .c = &audiopll_characteristics, 267 .eid = PMC_AUDIOPMCPLL, 268 .t = PLL_TYPE_DIV, 269 }, 270 271 { 272 .n = "audiopll_diviock", 273 .p = "audiopll_fracck", 274 .l = &pll_divio_layout, 275 .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 276 CLK_SET_RATE_PARENT, 277 .c = &audiopll_characteristics, 278 .eid = PMC_AUDIOIOPLL, 279 .t = PLL_TYPE_DIV, 280 }, 281 }, 282 283 [PLL_ID_LVDS] = { 284 { 285 .n = "lvdspll_fracck", 286 .p = "main_osc", 287 .l = &pll_frac_layout, 288 .f = CLK_SET_RATE_GATE, 289 .c = &lvdspll_characteristics, 290 .t = PLL_TYPE_FRAC, 291 }, 292 293 { 294 .n = "lvdspll_divpmcck", 295 .p = "lvdspll_fracck", 296 .l = &pll_divpmc_layout, 297 .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 298 CLK_SET_RATE_PARENT, 299 .c = &lvdspll_characteristics, 300 .eid = PMC_LVDSPLL, 301 .t = PLL_TYPE_DIV, 302 }, 303 }, 304 305 [PLL_ID_PLLA_DIV2] = { 306 { 307 .n = "plla_div2pmcck", 308 .p = "plla_fracck", 309 .l = &plladiv2_divpmc_layout, 310 /* 311 * This may feed critical parts of the system like timers. 312 * It should not be disabled. 313 */ 314 .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 315 .c = &plladiv2_characteristics, 316 .eid = PMC_PLLADIV2, 317 .t = PLL_TYPE_DIV, 318 }, 319 }, 320 }; 321 322 static const struct clk_programmable_layout sam9x7_programmable_layout = { 323 .pres_mask = 0xff, 324 .pres_shift = 8, 325 .css_mask = 0x1f, 326 .have_slck_mck = 0, 327 .is_pres_direct = 1, 328 }; 329 330 static const struct clk_pcr_layout sam9x7_pcr_layout = { 331 .offset = 0x88, 332 .cmd = BIT(31), 333 .gckcss_mask = GENMASK(12, 8), 334 .pid_mask = GENMASK(6, 0), 335 }; 336 337 static const struct { 338 char *n; 339 char *p; 340 u8 id; 341 unsigned long flags; 342 } sam9x7_systemck[] = { 343 /* 344 * ddrck feeds DDR controller and is enabled by bootloader thus we need 345 * to keep it enabled in case there is no Linux consumer for it. 346 */ 347 { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL }, 348 { .n = "uhpck", .p = "usbck", .id = 6 }, 349 { .n = "pck0", .p = "prog0", .id = 8 }, 350 { .n = "pck1", .p = "prog1", .id = 9 }, 351 }; 352 353 /* 354 * Peripheral clocks description 355 * @n: clock name 356 * @f: clock flags 357 * @id: peripheral id 358 */ 359 static const struct { 360 char *n; 361 unsigned long f; 362 u8 id; 363 } sam9x7_periphck[] = { 364 { .n = "pioA_clk", .id = 2, }, 365 { .n = "pioB_clk", .id = 3, }, 366 { .n = "pioC_clk", .id = 4, }, 367 { .n = "flex0_clk", .id = 5, }, 368 { .n = "flex1_clk", .id = 6, }, 369 { .n = "flex2_clk", .id = 7, }, 370 { .n = "flex3_clk", .id = 8, }, 371 { .n = "flex6_clk", .id = 9, }, 372 { .n = "flex7_clk", .id = 10, }, 373 { .n = "flex8_clk", .id = 11, }, 374 { .n = "sdmmc0_clk", .id = 12, }, 375 { .n = "flex4_clk", .id = 13, }, 376 { .n = "flex5_clk", .id = 14, }, 377 { .n = "flex9_clk", .id = 15, }, 378 { .n = "flex10_clk", .id = 16, }, 379 { .n = "tcb0_clk", .id = 17, }, 380 { .n = "pwm_clk", .id = 18, }, 381 { .n = "adc_clk", .id = 19, }, 382 { .n = "dma0_clk", .id = 20, }, 383 { .n = "uhphs_clk", .id = 22, }, 384 { .n = "udphs_clk", .id = 23, }, 385 { .n = "macb0_clk", .id = 24, }, 386 { .n = "lcd_clk", .id = 25, }, 387 { .n = "sdmmc1_clk", .id = 26, }, 388 { .n = "ssc_clk", .id = 28, }, 389 { .n = "can0_clk", .id = 29, }, 390 { .n = "can1_clk", .id = 30, }, 391 { .n = "flex11_clk", .id = 32, }, 392 { .n = "flex12_clk", .id = 33, }, 393 { .n = "i2s_clk", .id = 34, }, 394 { .n = "qspi_clk", .id = 35, }, 395 { .n = "gfx2d_clk", .id = 36, }, 396 { .n = "pit64b0_clk", .id = 37, }, 397 { .n = "trng_clk", .id = 38, }, 398 { .n = "aes_clk", .id = 39, }, 399 { .n = "tdes_clk", .id = 40, }, 400 { .n = "sha_clk", .id = 41, }, 401 { .n = "classd_clk", .id = 42, }, 402 { .n = "isi_clk", .id = 43, }, 403 { .n = "pioD_clk", .id = 44, }, 404 { .n = "tcb1_clk", .id = 45, }, 405 { .n = "dbgu_clk", .id = 47, }, 406 /* 407 * mpddr_clk feeds DDR controller and is enabled by bootloader thus we 408 * need to keep it enabled in case there is no Linux consumer for it. 409 */ 410 { .n = "mpddr_clk", .id = 49, .f = CLK_IS_CRITICAL }, 411 { .n = "csi2dc_clk", .id = 52, }, 412 { .n = "csi4l_clk", .id = 53, }, 413 { .n = "dsi4l_clk", .id = 54, }, 414 { .n = "lvdsc_clk", .id = 56, }, 415 { .n = "pit64b1_clk", .id = 58, }, 416 { .n = "puf_clk", .id = 59, }, 417 { .n = "gmactsu_clk", .id = 67, }, 418 }; 419 420 /* 421 * Generic clock description 422 * @n: clock name 423 * @pp: PLL parents 424 * @pp_mux_table: PLL parents mux table 425 * @r: clock output range 426 * @pp_chg_id: id in parent array of changeable PLL parent 427 * @pp_count: PLL parents count 428 * @id: clock id 429 */ 430 static const struct { 431 const char *n; 432 const char *pp[8]; 433 const char pp_mux_table[8]; 434 struct clk_range r; 435 int pp_chg_id; 436 u8 pp_count; 437 u8 id; 438 } sam9x7_gck[] = { 439 { 440 .n = "flex0_gclk", 441 .id = 5, 442 .pp = { "plla_div2pmcck", }, 443 .pp_mux_table = { 8, }, 444 .pp_count = 1, 445 .pp_chg_id = INT_MIN, 446 }, 447 448 { 449 .n = "flex1_gclk", 450 .id = 6, 451 .pp = { "plla_div2pmcck", }, 452 .pp_mux_table = { 8, }, 453 .pp_count = 1, 454 .pp_chg_id = INT_MIN, 455 }, 456 457 { 458 .n = "flex2_gclk", 459 .id = 7, 460 .pp = { "plla_div2pmcck", }, 461 .pp_mux_table = { 8, }, 462 .pp_count = 1, 463 .pp_chg_id = INT_MIN, 464 }, 465 466 { 467 .n = "flex3_gclk", 468 .id = 8, 469 .pp = { "plla_div2pmcck", }, 470 .pp_mux_table = { 8, }, 471 .pp_count = 1, 472 .pp_chg_id = INT_MIN, 473 }, 474 475 { 476 .n = "flex6_gclk", 477 .id = 9, 478 .pp = { "plla_div2pmcck", }, 479 .pp_mux_table = { 8, }, 480 .pp_count = 1, 481 .pp_chg_id = INT_MIN, 482 }, 483 484 { 485 .n = "flex7_gclk", 486 .id = 10, 487 .pp = { "plla_div2pmcck", }, 488 .pp_mux_table = { 8, }, 489 .pp_count = 1, 490 .pp_chg_id = INT_MIN, 491 }, 492 493 { 494 .n = "flex8_gclk", 495 .id = 11, 496 .pp = { "plla_div2pmcck", }, 497 .pp_mux_table = { 8, }, 498 .pp_count = 1, 499 .pp_chg_id = INT_MIN, 500 }, 501 502 { 503 .n = "sdmmc0_gclk", 504 .id = 12, 505 .r = { .max = 105000000 }, 506 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 507 .pp_mux_table = { 6, 8, }, 508 .pp_count = 2, 509 .pp_chg_id = INT_MIN, 510 }, 511 512 { 513 .n = "flex4_gclk", 514 .id = 13, 515 .pp = { "plla_div2pmcck", }, 516 .pp_mux_table = { 8, }, 517 .pp_count = 1, 518 .pp_chg_id = INT_MIN, 519 }, 520 521 { 522 .n = "flex5_gclk", 523 .id = 14, 524 .pp = { "plla_div2pmcck", }, 525 .pp_mux_table = { 8, }, 526 .pp_count = 1, 527 .pp_chg_id = INT_MIN, 528 }, 529 530 { 531 .n = "flex9_gclk", 532 .id = 15, 533 .pp = { "plla_div2pmcck", }, 534 .pp_mux_table = { 8, }, 535 .pp_count = 1, 536 .pp_chg_id = INT_MIN, 537 }, 538 539 { 540 .n = "flex10_gclk", 541 .id = 16, 542 .pp = { "plla_div2pmcck", }, 543 .pp_mux_table = { 8, }, 544 .pp_count = 1, 545 .pp_chg_id = INT_MIN, 546 }, 547 548 { 549 .n = "tcb0_gclk", 550 .id = 17, 551 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 552 .pp_mux_table = { 6, 8, }, 553 .pp_count = 2, 554 .pp_chg_id = INT_MIN, 555 }, 556 557 { 558 .n = "adc_gclk", 559 .id = 19, 560 .pp = { "upll_divpmcck", "plla_div2pmcck", }, 561 .pp_mux_table = { 5, 8, }, 562 .pp_count = 2, 563 .pp_chg_id = INT_MIN, 564 }, 565 566 { 567 .n = "lcd_gclk", 568 .id = 25, 569 .r = { .max = 75000000 }, 570 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 571 .pp_mux_table = { 6, 8, }, 572 .pp_count = 2, 573 .pp_chg_id = INT_MIN, 574 }, 575 576 { 577 .n = "sdmmc1_gclk", 578 .id = 26, 579 .r = { .max = 105000000 }, 580 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 581 .pp_mux_table = { 6, 8, }, 582 .pp_count = 2, 583 .pp_chg_id = INT_MIN, 584 }, 585 586 { 587 .n = "mcan0_gclk", 588 .id = 29, 589 .r = { .max = 80000000 }, 590 .pp = { "upll_divpmcck", "plla_div2pmcck", }, 591 .pp_mux_table = { 5, 8, }, 592 .pp_count = 2, 593 .pp_chg_id = INT_MIN, 594 }, 595 596 { 597 .n = "mcan1_gclk", 598 .id = 30, 599 .r = { .max = 80000000 }, 600 .pp = { "upll_divpmcck", "plla_div2pmcck", }, 601 .pp_mux_table = { 5, 8, }, 602 .pp_count = 2, 603 .pp_chg_id = INT_MIN, 604 }, 605 606 { 607 .n = "flex11_gclk", 608 .id = 32, 609 .pp = { "plla_div2pmcck", }, 610 .pp_mux_table = { 8, }, 611 .pp_count = 1, 612 .pp_chg_id = INT_MIN, 613 }, 614 615 { 616 .n = "flex12_gclk", 617 .id = 33, 618 .pp = { "plla_div2pmcck", }, 619 .pp_mux_table = { 8, }, 620 .pp_count = 1, 621 .pp_chg_id = INT_MIN, 622 }, 623 624 { 625 .n = "i2s_gclk", 626 .id = 34, 627 .r = { .max = 100000000 }, 628 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 629 .pp_mux_table = { 6, 8, }, 630 .pp_count = 2, 631 .pp_chg_id = INT_MIN, 632 }, 633 634 { 635 .n = "qspi_gclk", 636 .id = 35, 637 .r = { .max = 200000000 }, 638 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 639 .pp_mux_table = { 6, 8, }, 640 .pp_count = 2, 641 .pp_chg_id = INT_MIN, 642 }, 643 644 { 645 .n = "pit64b0_gclk", 646 .id = 37, 647 .pp = { "plla_div2pmcck", }, 648 .pp_mux_table = { 8, }, 649 .pp_count = 1, 650 .pp_chg_id = INT_MIN, 651 }, 652 653 { 654 .n = "classd_gclk", 655 .id = 42, 656 .r = { .max = 100000000 }, 657 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 658 .pp_mux_table = { 6, 8, }, 659 .pp_count = 2, 660 .pp_chg_id = INT_MIN, 661 }, 662 663 { 664 .n = "tcb1_gclk", 665 .id = 45, 666 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 667 .pp_mux_table = { 6, 8, }, 668 .pp_count = 2, 669 .pp_chg_id = INT_MIN, 670 }, 671 672 { 673 .n = "dbgu_gclk", 674 .id = 47, 675 .pp = { "plla_div2pmcck", }, 676 .pp_mux_table = { 8, }, 677 .pp_count = 1, 678 .pp_chg_id = INT_MIN, 679 }, 680 681 { 682 .n = "mipiphy_gclk", 683 .id = 55, 684 .r = { .max = 27000000 }, 685 .pp = { "plla_div2pmcck", }, 686 .pp_mux_table = { 8, }, 687 .pp_count = 1, 688 .pp_chg_id = INT_MIN, 689 }, 690 691 { 692 .n = "pit64b1_gclk", 693 .id = 58, 694 .pp = { "plla_div2pmcck", }, 695 .pp_mux_table = { 8, }, 696 .pp_count = 1, 697 .pp_chg_id = INT_MIN, 698 }, 699 700 { 701 .n = "gmac_gclk", 702 .id = 67, 703 .pp = { "audiopll_divpmcck", "plla_div2pmcck", }, 704 .pp_mux_table = { 6, 8, }, 705 .pp_count = 2, 706 .pp_chg_id = INT_MIN, 707 }, 708 }; 709 710 static void __init sam9x7_pmc_setup(struct device_node *np) 711 { 712 struct clk_range range = CLK_RANGE(0, 0); 713 const char *td_slck_name, *md_slck_name, *mainxtal_name; 714 struct pmc_data *sam9x7_pmc; 715 const char *parent_names[9]; 716 void **clk_mux_buffer = NULL; 717 int clk_mux_buffer_size = 0; 718 struct clk_hw *main_osc_hw; 719 struct regmap *regmap; 720 struct clk_hw *hw; 721 int i, j; 722 723 i = of_property_match_string(np, "clock-names", "td_slck"); 724 if (i < 0) 725 return; 726 727 td_slck_name = of_clk_get_parent_name(np, i); 728 729 i = of_property_match_string(np, "clock-names", "md_slck"); 730 if (i < 0) 731 return; 732 733 md_slck_name = of_clk_get_parent_name(np, i); 734 735 i = of_property_match_string(np, "clock-names", "main_xtal"); 736 if (i < 0) 737 return; 738 mainxtal_name = of_clk_get_parent_name(np, i); 739 740 regmap = device_node_to_regmap(np); 741 if (IS_ERR(regmap)) 742 return; 743 744 sam9x7_pmc = pmc_data_allocate(PMC_LVDSPLL + 1, 745 nck(sam9x7_systemck), 746 nck(sam9x7_periphck), 747 nck(sam9x7_gck), 8); 748 if (!sam9x7_pmc) 749 return; 750 751 clk_mux_buffer = kmalloc(sizeof(void *) * 752 (ARRAY_SIZE(sam9x7_gck)), 753 GFP_KERNEL); 754 if (!clk_mux_buffer) 755 goto err_free; 756 757 hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, 758 50000000); 759 if (IS_ERR(hw)) 760 goto err_free; 761 762 hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0); 763 if (IS_ERR(hw)) 764 goto err_free; 765 main_osc_hw = hw; 766 767 parent_names[0] = "main_rc_osc"; 768 parent_names[1] = "main_osc"; 769 hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2); 770 if (IS_ERR(hw)) 771 goto err_free; 772 773 sam9x7_pmc->chws[PMC_MAIN] = hw; 774 775 for (i = 0; i < PLL_ID_MAX; i++) { 776 for (j = 0; j < 3; j++) { 777 struct clk_hw *parent_hw; 778 779 if (!sam9x7_plls[i][j].n) 780 continue; 781 782 switch (sam9x7_plls[i][j].t) { 783 case PLL_TYPE_FRAC: 784 if (!strcmp(sam9x7_plls[i][j].p, "mainck")) 785 parent_hw = sam9x7_pmc->chws[PMC_MAIN]; 786 else if (!strcmp(sam9x7_plls[i][j].p, "main_osc")) 787 parent_hw = main_osc_hw; 788 else 789 parent_hw = __clk_get_hw(of_clk_get_by_name 790 (np, sam9x7_plls[i][j].p)); 791 792 hw = sam9x60_clk_register_frac_pll(regmap, 793 &pmc_pll_lock, 794 sam9x7_plls[i][j].n, 795 sam9x7_plls[i][j].p, 796 parent_hw, i, 797 sam9x7_plls[i][j].c, 798 sam9x7_plls[i][j].l, 799 sam9x7_plls[i][j].f); 800 break; 801 802 case PLL_TYPE_DIV: 803 hw = sam9x60_clk_register_div_pll(regmap, 804 &pmc_pll_lock, 805 sam9x7_plls[i][j].n, 806 sam9x7_plls[i][j].p, NULL, i, 807 sam9x7_plls[i][j].c, 808 sam9x7_plls[i][j].l, 809 sam9x7_plls[i][j].f, 0); 810 break; 811 812 default: 813 continue; 814 } 815 816 if (IS_ERR(hw)) 817 goto err_free; 818 819 if (sam9x7_plls[i][j].eid) 820 sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw; 821 } 822 } 823 824 parent_names[0] = md_slck_name; 825 parent_names[1] = "mainck"; 826 parent_names[2] = "plla_divpmcck"; 827 parent_names[3] = "upll_divpmcck"; 828 hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 829 parent_names, NULL, &sam9x7_master_layout, 830 &mck_characteristics, &mck_lock); 831 if (IS_ERR(hw)) 832 goto err_free; 833 834 hw = at91_clk_register_master_div(regmap, "masterck_div", 835 "masterck_pres", NULL, &sam9x7_master_layout, 836 &mck_characteristics, &mck_lock, 837 CLK_SET_RATE_GATE, 0); 838 if (IS_ERR(hw)) 839 goto err_free; 840 841 sam9x7_pmc->chws[PMC_MCK] = hw; 842 843 parent_names[0] = "plla_divpmcck"; 844 parent_names[1] = "upll_divpmcck"; 845 parent_names[2] = "main_osc"; 846 hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3); 847 if (IS_ERR(hw)) 848 goto err_free; 849 850 parent_names[0] = md_slck_name; 851 parent_names[1] = td_slck_name; 852 parent_names[2] = "mainck"; 853 parent_names[3] = "masterck_div"; 854 parent_names[4] = "plla_divpmcck"; 855 parent_names[5] = "upll_divpmcck"; 856 parent_names[6] = "audiopll_divpmcck"; 857 for (i = 0; i < 2; i++) { 858 char name[6]; 859 860 snprintf(name, sizeof(name), "prog%d", i); 861 862 hw = at91_clk_register_programmable(regmap, name, 863 parent_names, NULL, 7, i, 864 &sam9x7_programmable_layout, 865 NULL); 866 if (IS_ERR(hw)) 867 goto err_free; 868 869 sam9x7_pmc->pchws[i] = hw; 870 } 871 872 for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) { 873 hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n, 874 sam9x7_systemck[i].p, NULL, 875 sam9x7_systemck[i].id, 876 sam9x7_systemck[i].flags); 877 if (IS_ERR(hw)) 878 goto err_free; 879 880 sam9x7_pmc->shws[sam9x7_systemck[i].id] = hw; 881 } 882 883 for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) { 884 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 885 &sam9x7_pcr_layout, 886 sam9x7_periphck[i].n, 887 "masterck_div", NULL, 888 sam9x7_periphck[i].id, 889 &range, INT_MIN, 890 sam9x7_periphck[i].f); 891 if (IS_ERR(hw)) 892 goto err_free; 893 894 sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw; 895 } 896 897 parent_names[0] = md_slck_name; 898 parent_names[1] = td_slck_name; 899 parent_names[2] = "mainck"; 900 parent_names[3] = "masterck_div"; 901 for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) { 902 u8 num_parents = 4 + sam9x7_gck[i].pp_count; 903 u32 *mux_table; 904 905 mux_table = kmalloc_array(num_parents, sizeof(*mux_table), 906 GFP_KERNEL); 907 if (!mux_table) 908 goto err_free; 909 910 PMC_INIT_TABLE(mux_table, 4); 911 PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table, 912 sam9x7_gck[i].pp_count); 913 PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp, 914 sam9x7_gck[i].pp_count); 915 916 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 917 &sam9x7_pcr_layout, 918 sam9x7_gck[i].n, 919 parent_names, NULL, mux_table, 920 num_parents, 921 sam9x7_gck[i].id, 922 &sam9x7_gck[i].r, 923 sam9x7_gck[i].pp_chg_id); 924 if (IS_ERR(hw)) 925 goto err_free; 926 927 sam9x7_pmc->ghws[sam9x7_gck[i].id] = hw; 928 clk_mux_buffer[clk_mux_buffer_size++] = mux_table; 929 } 930 931 of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc); 932 kfree(clk_mux_buffer); 933 934 return; 935 936 err_free: 937 if (clk_mux_buffer) { 938 for (i = 0; i < clk_mux_buffer_size; i++) 939 kfree(clk_mux_buffer[i]); 940 kfree(clk_mux_buffer); 941 } 942 kfree(sam9x7_pmc); 943 } 944 945 /* Some clks are used for a clocksource */ 946 CLK_OF_DECLARE(sam9x7_pmc, "microchip,sam9x7-pmc", sam9x7_pmc_setup); 947