dt-compat.c (25666B)
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/clk-provider.h> 3#include <linux/clk/at91_pmc.h> 4#include <linux/of.h> 5#include <linux/mfd/syscon.h> 6#include <linux/regmap.h> 7#include <linux/slab.h> 8 9#include "pmc.h" 10 11#define MASTER_SOURCE_MAX 4 12 13#define PERIPHERAL_AT91RM9200 0 14#define PERIPHERAL_AT91SAM9X5 1 15 16#define PERIPHERAL_MAX 64 17 18#define PERIPHERAL_ID_MIN 2 19 20#define PROG_SOURCE_MAX 5 21#define PROG_ID_MAX 7 22 23#define SYSTEM_MAX_ID 31 24 25#define GCK_INDEX_DT_AUDIO_PLL 5 26 27static DEFINE_SPINLOCK(mck_lock); 28 29#ifdef CONFIG_HAVE_AT91_AUDIO_PLL 30static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) 31{ 32 struct clk_hw *hw; 33 const char *name = np->name; 34 const char *parent_name; 35 struct regmap *regmap; 36 37 regmap = syscon_node_to_regmap(of_get_parent(np)); 38 if (IS_ERR(regmap)) 39 return; 40 41 parent_name = of_clk_get_parent_name(np, 0); 42 43 hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name); 44 if (IS_ERR(hw)) 45 return; 46 47 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 48} 49CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup, 50 "atmel,sama5d2-clk-audio-pll-frac", 51 of_sama5d2_clk_audio_pll_frac_setup); 52 53static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np) 54{ 55 struct clk_hw *hw; 56 const char *name = np->name; 57 const char *parent_name; 58 struct regmap *regmap; 59 60 regmap = syscon_node_to_regmap(of_get_parent(np)); 61 if (IS_ERR(regmap)) 62 return; 63 64 parent_name = of_clk_get_parent_name(np, 0); 65 66 hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name); 67 if (IS_ERR(hw)) 68 return; 69 70 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 71} 72CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup, 73 "atmel,sama5d2-clk-audio-pll-pad", 74 of_sama5d2_clk_audio_pll_pad_setup); 75 76static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np) 77{ 78 struct clk_hw *hw; 79 const char *name = np->name; 80 const char *parent_name; 81 struct regmap *regmap; 82 83 regmap = syscon_node_to_regmap(of_get_parent(np)); 84 if (IS_ERR(regmap)) 85 return; 86 87 parent_name = of_clk_get_parent_name(np, 0); 88 89 hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name); 90 if (IS_ERR(hw)) 91 return; 92 93 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 94} 95CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup, 96 "atmel,sama5d2-clk-audio-pll-pmc", 97 of_sama5d2_clk_audio_pll_pmc_setup); 98#endif /* CONFIG_HAVE_AT91_AUDIO_PLL */ 99 100static const struct clk_pcr_layout dt_pcr_layout = { 101 .offset = 0x10c, 102 .cmd = BIT(12), 103 .pid_mask = GENMASK(5, 0), 104 .div_mask = GENMASK(17, 16), 105 .gckcss_mask = GENMASK(10, 8), 106}; 107 108#ifdef CONFIG_HAVE_AT91_GENERATED_CLK 109#define GENERATED_SOURCE_MAX 6 110 111#define GCK_ID_I2S0 54 112#define GCK_ID_I2S1 55 113#define GCK_ID_CLASSD 59 114 115static void __init of_sama5d2_clk_generated_setup(struct device_node *np) 116{ 117 int num; 118 u32 id; 119 const char *name; 120 struct clk_hw *hw; 121 unsigned int num_parents; 122 const char *parent_names[GENERATED_SOURCE_MAX]; 123 struct device_node *gcknp; 124 struct clk_range range = CLK_RANGE(0, 0); 125 struct regmap *regmap; 126 127 num_parents = of_clk_get_parent_count(np); 128 if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) 129 return; 130 131 of_clk_parent_fill(np, parent_names, num_parents); 132 133 num = of_get_child_count(np); 134 if (!num || num > PERIPHERAL_MAX) 135 return; 136 137 regmap = syscon_node_to_regmap(of_get_parent(np)); 138 if (IS_ERR(regmap)) 139 return; 140 141 for_each_child_of_node(np, gcknp) { 142 int chg_pid = INT_MIN; 143 144 if (of_property_read_u32(gcknp, "reg", &id)) 145 continue; 146 147 if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX) 148 continue; 149 150 if (of_property_read_string(np, "clock-output-names", &name)) 151 name = gcknp->name; 152 153 of_at91_get_clk_range(gcknp, "atmel,clk-output-range", 154 &range); 155 156 if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") && 157 (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 || 158 id == GCK_ID_CLASSD)) 159 chg_pid = GCK_INDEX_DT_AUDIO_PLL; 160 161 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 162 &dt_pcr_layout, name, 163 parent_names, NULL, 164 num_parents, id, &range, 165 chg_pid); 166 if (IS_ERR(hw)) 167 continue; 168 169 of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw); 170 } 171} 172CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated", 173 of_sama5d2_clk_generated_setup); 174#endif /* CONFIG_HAVE_AT91_GENERATED_CLK */ 175 176#ifdef CONFIG_HAVE_AT91_H32MX 177static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np) 178{ 179 struct clk_hw *hw; 180 const char *name = np->name; 181 const char *parent_name; 182 struct regmap *regmap; 183 184 regmap = syscon_node_to_regmap(of_get_parent(np)); 185 if (IS_ERR(regmap)) 186 return; 187 188 parent_name = of_clk_get_parent_name(np, 0); 189 190 hw = at91_clk_register_h32mx(regmap, name, parent_name); 191 if (IS_ERR(hw)) 192 return; 193 194 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 195} 196CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx", 197 of_sama5d4_clk_h32mx_setup); 198#endif /* CONFIG_HAVE_AT91_H32MX */ 199 200#ifdef CONFIG_HAVE_AT91_I2S_MUX_CLK 201#define I2S_BUS_NR 2 202 203static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np) 204{ 205 struct regmap *regmap_sfr; 206 u8 bus_id; 207 const char *parent_names[2]; 208 struct device_node *i2s_mux_np; 209 struct clk_hw *hw; 210 int ret; 211 212 regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); 213 if (IS_ERR(regmap_sfr)) 214 return; 215 216 for_each_child_of_node(np, i2s_mux_np) { 217 if (of_property_read_u8(i2s_mux_np, "reg", &bus_id)) 218 continue; 219 220 if (bus_id > I2S_BUS_NR) 221 continue; 222 223 ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2); 224 if (ret != 2) 225 continue; 226 227 hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name, 228 parent_names, 2, bus_id); 229 if (IS_ERR(hw)) 230 continue; 231 232 of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw); 233 } 234} 235CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux", 236 of_sama5d2_clk_i2s_mux_setup); 237#endif /* CONFIG_HAVE_AT91_I2S_MUX_CLK */ 238 239static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np) 240{ 241 struct clk_hw *hw; 242 const char *name = np->name; 243 const char *parent_name; 244 struct regmap *regmap; 245 bool bypass; 246 247 of_property_read_string(np, "clock-output-names", &name); 248 bypass = of_property_read_bool(np, "atmel,osc-bypass"); 249 parent_name = of_clk_get_parent_name(np, 0); 250 251 regmap = syscon_node_to_regmap(of_get_parent(np)); 252 if (IS_ERR(regmap)) 253 return; 254 255 hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass); 256 if (IS_ERR(hw)) 257 return; 258 259 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 260} 261CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc", 262 of_at91rm9200_clk_main_osc_setup); 263 264static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np) 265{ 266 struct clk_hw *hw; 267 u32 frequency = 0; 268 u32 accuracy = 0; 269 const char *name = np->name; 270 struct regmap *regmap; 271 272 of_property_read_string(np, "clock-output-names", &name); 273 of_property_read_u32(np, "clock-frequency", &frequency); 274 of_property_read_u32(np, "clock-accuracy", &accuracy); 275 276 regmap = syscon_node_to_regmap(of_get_parent(np)); 277 if (IS_ERR(regmap)) 278 return; 279 280 hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy); 281 if (IS_ERR(hw)) 282 return; 283 284 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 285} 286CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc", 287 of_at91sam9x5_clk_main_rc_osc_setup); 288 289static void __init of_at91rm9200_clk_main_setup(struct device_node *np) 290{ 291 struct clk_hw *hw; 292 const char *parent_name; 293 const char *name = np->name; 294 struct regmap *regmap; 295 296 parent_name = of_clk_get_parent_name(np, 0); 297 of_property_read_string(np, "clock-output-names", &name); 298 299 regmap = syscon_node_to_regmap(of_get_parent(np)); 300 if (IS_ERR(regmap)) 301 return; 302 303 hw = at91_clk_register_rm9200_main(regmap, name, parent_name); 304 if (IS_ERR(hw)) 305 return; 306 307 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 308} 309CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main", 310 of_at91rm9200_clk_main_setup); 311 312static void __init of_at91sam9x5_clk_main_setup(struct device_node *np) 313{ 314 struct clk_hw *hw; 315 const char *parent_names[2]; 316 unsigned int num_parents; 317 const char *name = np->name; 318 struct regmap *regmap; 319 320 num_parents = of_clk_get_parent_count(np); 321 if (num_parents == 0 || num_parents > 2) 322 return; 323 324 of_clk_parent_fill(np, parent_names, num_parents); 325 regmap = syscon_node_to_regmap(of_get_parent(np)); 326 if (IS_ERR(regmap)) 327 return; 328 329 of_property_read_string(np, "clock-output-names", &name); 330 331 hw = at91_clk_register_sam9x5_main(regmap, name, parent_names, 332 num_parents); 333 if (IS_ERR(hw)) 334 return; 335 336 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 337} 338CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main", 339 of_at91sam9x5_clk_main_setup); 340 341static struct clk_master_characteristics * __init 342of_at91_clk_master_get_characteristics(struct device_node *np) 343{ 344 struct clk_master_characteristics *characteristics; 345 346 characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); 347 if (!characteristics) 348 return NULL; 349 350 if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output)) 351 goto out_free_characteristics; 352 353 of_property_read_u32_array(np, "atmel,clk-divisors", 354 characteristics->divisors, 4); 355 356 characteristics->have_div3_pres = 357 of_property_read_bool(np, "atmel,master-clk-have-div3-pres"); 358 359 return characteristics; 360 361out_free_characteristics: 362 kfree(characteristics); 363 return NULL; 364} 365 366static void __init 367of_at91_clk_master_setup(struct device_node *np, 368 const struct clk_master_layout *layout) 369{ 370 struct clk_hw *hw; 371 unsigned int num_parents; 372 const char *parent_names[MASTER_SOURCE_MAX]; 373 const char *name = np->name; 374 struct clk_master_characteristics *characteristics; 375 struct regmap *regmap; 376 377 num_parents = of_clk_get_parent_count(np); 378 if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX) 379 return; 380 381 of_clk_parent_fill(np, parent_names, num_parents); 382 383 of_property_read_string(np, "clock-output-names", &name); 384 385 characteristics = of_at91_clk_master_get_characteristics(np); 386 if (!characteristics) 387 return; 388 389 regmap = syscon_node_to_regmap(of_get_parent(np)); 390 if (IS_ERR(regmap)) 391 return; 392 393 hw = at91_clk_register_master_pres(regmap, "masterck_pres", num_parents, 394 parent_names, layout, 395 characteristics, &mck_lock); 396 if (IS_ERR(hw)) 397 goto out_free_characteristics; 398 399 hw = at91_clk_register_master_div(regmap, name, "masterck_pres", 400 layout, characteristics, 401 &mck_lock, CLK_SET_RATE_GATE, 0); 402 if (IS_ERR(hw)) 403 goto out_free_characteristics; 404 405 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 406 return; 407 408out_free_characteristics: 409 kfree(characteristics); 410} 411 412static void __init of_at91rm9200_clk_master_setup(struct device_node *np) 413{ 414 of_at91_clk_master_setup(np, &at91rm9200_master_layout); 415} 416CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master", 417 of_at91rm9200_clk_master_setup); 418 419static void __init of_at91sam9x5_clk_master_setup(struct device_node *np) 420{ 421 of_at91_clk_master_setup(np, &at91sam9x5_master_layout); 422} 423CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master", 424 of_at91sam9x5_clk_master_setup); 425 426static void __init 427of_at91_clk_periph_setup(struct device_node *np, u8 type) 428{ 429 int num; 430 u32 id; 431 struct clk_hw *hw; 432 const char *parent_name; 433 const char *name; 434 struct device_node *periphclknp; 435 struct regmap *regmap; 436 437 parent_name = of_clk_get_parent_name(np, 0); 438 if (!parent_name) 439 return; 440 441 num = of_get_child_count(np); 442 if (!num || num > PERIPHERAL_MAX) 443 return; 444 445 regmap = syscon_node_to_regmap(of_get_parent(np)); 446 if (IS_ERR(regmap)) 447 return; 448 449 for_each_child_of_node(np, periphclknp) { 450 if (of_property_read_u32(periphclknp, "reg", &id)) 451 continue; 452 453 if (id >= PERIPHERAL_MAX) 454 continue; 455 456 if (of_property_read_string(np, "clock-output-names", &name)) 457 name = periphclknp->name; 458 459 if (type == PERIPHERAL_AT91RM9200) { 460 hw = at91_clk_register_peripheral(regmap, name, 461 parent_name, id); 462 } else { 463 struct clk_range range = CLK_RANGE(0, 0); 464 465 of_at91_get_clk_range(periphclknp, 466 "atmel,clk-output-range", 467 &range); 468 469 hw = at91_clk_register_sam9x5_peripheral(regmap, 470 &pmc_pcr_lock, 471 &dt_pcr_layout, 472 name, 473 parent_name, 474 id, &range, 475 INT_MIN); 476 } 477 478 if (IS_ERR(hw)) 479 continue; 480 481 of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw); 482 } 483} 484 485static void __init of_at91rm9200_clk_periph_setup(struct device_node *np) 486{ 487 of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200); 488} 489CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral", 490 of_at91rm9200_clk_periph_setup); 491 492static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np) 493{ 494 of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5); 495} 496CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral", 497 of_at91sam9x5_clk_periph_setup); 498 499static struct clk_pll_characteristics * __init 500of_at91_clk_pll_get_characteristics(struct device_node *np) 501{ 502 int i; 503 int offset; 504 u32 tmp; 505 int num_output; 506 u32 num_cells; 507 struct clk_range input; 508 struct clk_range *output; 509 u8 *out = NULL; 510 u16 *icpll = NULL; 511 struct clk_pll_characteristics *characteristics; 512 513 if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input)) 514 return NULL; 515 516 if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells", 517 &num_cells)) 518 return NULL; 519 520 if (num_cells < 2 || num_cells > 4) 521 return NULL; 522 523 if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp)) 524 return NULL; 525 num_output = tmp / (sizeof(u32) * num_cells); 526 527 characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); 528 if (!characteristics) 529 return NULL; 530 531 output = kcalloc(num_output, sizeof(*output), GFP_KERNEL); 532 if (!output) 533 goto out_free_characteristics; 534 535 if (num_cells > 2) { 536 out = kcalloc(num_output, sizeof(*out), GFP_KERNEL); 537 if (!out) 538 goto out_free_output; 539 } 540 541 if (num_cells > 3) { 542 icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL); 543 if (!icpll) 544 goto out_free_output; 545 } 546 547 for (i = 0; i < num_output; i++) { 548 offset = i * num_cells; 549 if (of_property_read_u32_index(np, 550 "atmel,pll-clk-output-ranges", 551 offset, &tmp)) 552 goto out_free_output; 553 output[i].min = tmp; 554 if (of_property_read_u32_index(np, 555 "atmel,pll-clk-output-ranges", 556 offset + 1, &tmp)) 557 goto out_free_output; 558 output[i].max = tmp; 559 560 if (num_cells == 2) 561 continue; 562 563 if (of_property_read_u32_index(np, 564 "atmel,pll-clk-output-ranges", 565 offset + 2, &tmp)) 566 goto out_free_output; 567 out[i] = tmp; 568 569 if (num_cells == 3) 570 continue; 571 572 if (of_property_read_u32_index(np, 573 "atmel,pll-clk-output-ranges", 574 offset + 3, &tmp)) 575 goto out_free_output; 576 icpll[i] = tmp; 577 } 578 579 characteristics->input = input; 580 characteristics->num_output = num_output; 581 characteristics->output = output; 582 characteristics->out = out; 583 characteristics->icpll = icpll; 584 return characteristics; 585 586out_free_output: 587 kfree(icpll); 588 kfree(out); 589 kfree(output); 590out_free_characteristics: 591 kfree(characteristics); 592 return NULL; 593} 594 595static void __init 596of_at91_clk_pll_setup(struct device_node *np, 597 const struct clk_pll_layout *layout) 598{ 599 u32 id; 600 struct clk_hw *hw; 601 struct regmap *regmap; 602 const char *parent_name; 603 const char *name = np->name; 604 struct clk_pll_characteristics *characteristics; 605 606 if (of_property_read_u32(np, "reg", &id)) 607 return; 608 609 parent_name = of_clk_get_parent_name(np, 0); 610 611 of_property_read_string(np, "clock-output-names", &name); 612 613 regmap = syscon_node_to_regmap(of_get_parent(np)); 614 if (IS_ERR(regmap)) 615 return; 616 617 characteristics = of_at91_clk_pll_get_characteristics(np); 618 if (!characteristics) 619 return; 620 621 hw = at91_clk_register_pll(regmap, name, parent_name, id, layout, 622 characteristics); 623 if (IS_ERR(hw)) 624 goto out_free_characteristics; 625 626 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 627 return; 628 629out_free_characteristics: 630 kfree(characteristics); 631} 632 633static void __init of_at91rm9200_clk_pll_setup(struct device_node *np) 634{ 635 of_at91_clk_pll_setup(np, &at91rm9200_pll_layout); 636} 637CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll", 638 of_at91rm9200_clk_pll_setup); 639 640static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np) 641{ 642 of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout); 643} 644CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll", 645 of_at91sam9g45_clk_pll_setup); 646 647static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np) 648{ 649 of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout); 650} 651CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb", 652 of_at91sam9g20_clk_pllb_setup); 653 654static void __init of_sama5d3_clk_pll_setup(struct device_node *np) 655{ 656 of_at91_clk_pll_setup(np, &sama5d3_pll_layout); 657} 658CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll", 659 of_sama5d3_clk_pll_setup); 660 661static void __init 662of_at91sam9x5_clk_plldiv_setup(struct device_node *np) 663{ 664 struct clk_hw *hw; 665 const char *parent_name; 666 const char *name = np->name; 667 struct regmap *regmap; 668 669 parent_name = of_clk_get_parent_name(np, 0); 670 671 of_property_read_string(np, "clock-output-names", &name); 672 673 regmap = syscon_node_to_regmap(of_get_parent(np)); 674 if (IS_ERR(regmap)) 675 return; 676 677 hw = at91_clk_register_plldiv(regmap, name, parent_name); 678 if (IS_ERR(hw)) 679 return; 680 681 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 682} 683CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv", 684 of_at91sam9x5_clk_plldiv_setup); 685 686static void __init 687of_at91_clk_prog_setup(struct device_node *np, 688 const struct clk_programmable_layout *layout, 689 u32 *mux_table) 690{ 691 int num; 692 u32 id; 693 struct clk_hw *hw; 694 unsigned int num_parents; 695 const char *parent_names[PROG_SOURCE_MAX]; 696 const char *name; 697 struct device_node *progclknp; 698 struct regmap *regmap; 699 700 num_parents = of_clk_get_parent_count(np); 701 if (num_parents == 0 || num_parents > PROG_SOURCE_MAX) 702 return; 703 704 of_clk_parent_fill(np, parent_names, num_parents); 705 706 num = of_get_child_count(np); 707 if (!num || num > (PROG_ID_MAX + 1)) 708 return; 709 710 regmap = syscon_node_to_regmap(of_get_parent(np)); 711 if (IS_ERR(regmap)) 712 return; 713 714 for_each_child_of_node(np, progclknp) { 715 if (of_property_read_u32(progclknp, "reg", &id)) 716 continue; 717 718 if (of_property_read_string(np, "clock-output-names", &name)) 719 name = progclknp->name; 720 721 hw = at91_clk_register_programmable(regmap, name, 722 parent_names, num_parents, 723 id, layout, mux_table); 724 if (IS_ERR(hw)) 725 continue; 726 727 of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw); 728 } 729} 730 731static void __init of_at91rm9200_clk_prog_setup(struct device_node *np) 732{ 733 of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout, NULL); 734} 735CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable", 736 of_at91rm9200_clk_prog_setup); 737 738static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np) 739{ 740 of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout, NULL); 741} 742CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable", 743 of_at91sam9g45_clk_prog_setup); 744 745static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np) 746{ 747 of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout, NULL); 748} 749CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable", 750 of_at91sam9x5_clk_prog_setup); 751 752static void __init of_at91sam9260_clk_slow_setup(struct device_node *np) 753{ 754 struct clk_hw *hw; 755 const char *parent_names[2]; 756 unsigned int num_parents; 757 const char *name = np->name; 758 struct regmap *regmap; 759 760 num_parents = of_clk_get_parent_count(np); 761 if (num_parents != 2) 762 return; 763 764 of_clk_parent_fill(np, parent_names, num_parents); 765 regmap = syscon_node_to_regmap(of_get_parent(np)); 766 if (IS_ERR(regmap)) 767 return; 768 769 of_property_read_string(np, "clock-output-names", &name); 770 771 hw = at91_clk_register_sam9260_slow(regmap, name, parent_names, 772 num_parents); 773 if (IS_ERR(hw)) 774 return; 775 776 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 777} 778CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow", 779 of_at91sam9260_clk_slow_setup); 780 781#ifdef CONFIG_HAVE_AT91_SMD 782#define SMD_SOURCE_MAX 2 783 784static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np) 785{ 786 struct clk_hw *hw; 787 unsigned int num_parents; 788 const char *parent_names[SMD_SOURCE_MAX]; 789 const char *name = np->name; 790 struct regmap *regmap; 791 792 num_parents = of_clk_get_parent_count(np); 793 if (num_parents == 0 || num_parents > SMD_SOURCE_MAX) 794 return; 795 796 of_clk_parent_fill(np, parent_names, num_parents); 797 798 of_property_read_string(np, "clock-output-names", &name); 799 800 regmap = syscon_node_to_regmap(of_get_parent(np)); 801 if (IS_ERR(regmap)) 802 return; 803 804 hw = at91sam9x5_clk_register_smd(regmap, name, parent_names, 805 num_parents); 806 if (IS_ERR(hw)) 807 return; 808 809 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 810} 811CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd", 812 of_at91sam9x5_clk_smd_setup); 813#endif /* CONFIG_HAVE_AT91_SMD */ 814 815static void __init of_at91rm9200_clk_sys_setup(struct device_node *np) 816{ 817 int num; 818 u32 id; 819 struct clk_hw *hw; 820 const char *name; 821 struct device_node *sysclknp; 822 const char *parent_name; 823 struct regmap *regmap; 824 825 num = of_get_child_count(np); 826 if (num > (SYSTEM_MAX_ID + 1)) 827 return; 828 829 regmap = syscon_node_to_regmap(of_get_parent(np)); 830 if (IS_ERR(regmap)) 831 return; 832 833 for_each_child_of_node(np, sysclknp) { 834 if (of_property_read_u32(sysclknp, "reg", &id)) 835 continue; 836 837 if (of_property_read_string(np, "clock-output-names", &name)) 838 name = sysclknp->name; 839 840 parent_name = of_clk_get_parent_name(sysclknp, 0); 841 842 hw = at91_clk_register_system(regmap, name, parent_name, id); 843 if (IS_ERR(hw)) 844 continue; 845 846 of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw); 847 } 848} 849CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system", 850 of_at91rm9200_clk_sys_setup); 851 852#ifdef CONFIG_HAVE_AT91_USB_CLK 853#define USB_SOURCE_MAX 2 854 855static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np) 856{ 857 struct clk_hw *hw; 858 unsigned int num_parents; 859 const char *parent_names[USB_SOURCE_MAX]; 860 const char *name = np->name; 861 struct regmap *regmap; 862 863 num_parents = of_clk_get_parent_count(np); 864 if (num_parents == 0 || num_parents > USB_SOURCE_MAX) 865 return; 866 867 of_clk_parent_fill(np, parent_names, num_parents); 868 869 of_property_read_string(np, "clock-output-names", &name); 870 871 regmap = syscon_node_to_regmap(of_get_parent(np)); 872 if (IS_ERR(regmap)) 873 return; 874 875 hw = at91sam9x5_clk_register_usb(regmap, name, parent_names, 876 num_parents); 877 if (IS_ERR(hw)) 878 return; 879 880 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 881} 882CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb", 883 of_at91sam9x5_clk_usb_setup); 884 885static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np) 886{ 887 struct clk_hw *hw; 888 const char *parent_name; 889 const char *name = np->name; 890 struct regmap *regmap; 891 892 parent_name = of_clk_get_parent_name(np, 0); 893 if (!parent_name) 894 return; 895 896 of_property_read_string(np, "clock-output-names", &name); 897 898 regmap = syscon_node_to_regmap(of_get_parent(np)); 899 if (IS_ERR(regmap)) 900 return; 901 902 hw = at91sam9n12_clk_register_usb(regmap, name, parent_name); 903 if (IS_ERR(hw)) 904 return; 905 906 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 907} 908CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb", 909 of_at91sam9n12_clk_usb_setup); 910 911static void __init of_at91rm9200_clk_usb_setup(struct device_node *np) 912{ 913 struct clk_hw *hw; 914 const char *parent_name; 915 const char *name = np->name; 916 u32 divisors[4] = {0, 0, 0, 0}; 917 struct regmap *regmap; 918 919 parent_name = of_clk_get_parent_name(np, 0); 920 if (!parent_name) 921 return; 922 923 of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4); 924 if (!divisors[0]) 925 return; 926 927 of_property_read_string(np, "clock-output-names", &name); 928 929 regmap = syscon_node_to_regmap(of_get_parent(np)); 930 if (IS_ERR(regmap)) 931 return; 932 hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors); 933 if (IS_ERR(hw)) 934 return; 935 936 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 937} 938CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb", 939 of_at91rm9200_clk_usb_setup); 940#endif /* CONFIG_HAVE_AT91_USB_CLK */ 941 942#ifdef CONFIG_HAVE_AT91_UTMI 943static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np) 944{ 945 struct clk_hw *hw; 946 const char *parent_name; 947 const char *name = np->name; 948 struct regmap *regmap_pmc, *regmap_sfr; 949 950 parent_name = of_clk_get_parent_name(np, 0); 951 952 of_property_read_string(np, "clock-output-names", &name); 953 954 regmap_pmc = syscon_node_to_regmap(of_get_parent(np)); 955 if (IS_ERR(regmap_pmc)) 956 return; 957 958 /* 959 * If the device supports different mainck rates, this value has to be 960 * set in the UTMI Clock Trimming register. 961 * - 9x5: mainck supports several rates but it is indicated that a 962 * 12 MHz is needed in case of USB. 963 * - sama5d3 and sama5d2: mainck supports several rates. Configuring 964 * the FREQ field of the UTMI Clock Trimming register is mandatory. 965 * - sama5d4: mainck is at 12 MHz. 966 * 967 * We only need to retrieve sama5d3 or sama5d2 sfr regmap. 968 */ 969 regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr"); 970 if (IS_ERR(regmap_sfr)) { 971 regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); 972 if (IS_ERR(regmap_sfr)) 973 regmap_sfr = NULL; 974 } 975 976 hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name); 977 if (IS_ERR(hw)) 978 return; 979 980 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 981} 982CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi", 983 of_at91sam9x5_clk_utmi_setup); 984#endif /* CONFIG_HAVE_AT91_UTMI */