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