linux/drivers/clk/at91/dt-compat.c
<<
>>
Prefs
   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                                           CLK_SET_RATE_GATE, INT_MIN);
 397        if (IS_ERR(hw))
 398                goto out_free_characteristics;
 399
 400        hw = at91_clk_register_master_div(regmap, name, "masterck_pres",
 401                                          layout, characteristics,
 402                                          &mck_lock, CLK_SET_RATE_GATE);
 403        if (IS_ERR(hw))
 404                goto out_free_characteristics;
 405
 406        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 407        return;
 408
 409out_free_characteristics:
 410        kfree(characteristics);
 411}
 412
 413static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
 414{
 415        of_at91_clk_master_setup(np, &at91rm9200_master_layout);
 416}
 417CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
 418               of_at91rm9200_clk_master_setup);
 419
 420static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
 421{
 422        of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
 423}
 424CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
 425               of_at91sam9x5_clk_master_setup);
 426
 427static void __init
 428of_at91_clk_periph_setup(struct device_node *np, u8 type)
 429{
 430        int num;
 431        u32 id;
 432        struct clk_hw *hw;
 433        const char *parent_name;
 434        const char *name;
 435        struct device_node *periphclknp;
 436        struct regmap *regmap;
 437
 438        parent_name = of_clk_get_parent_name(np, 0);
 439        if (!parent_name)
 440                return;
 441
 442        num = of_get_child_count(np);
 443        if (!num || num > PERIPHERAL_MAX)
 444                return;
 445
 446        regmap = syscon_node_to_regmap(of_get_parent(np));
 447        if (IS_ERR(regmap))
 448                return;
 449
 450        for_each_child_of_node(np, periphclknp) {
 451                if (of_property_read_u32(periphclknp, "reg", &id))
 452                        continue;
 453
 454                if (id >= PERIPHERAL_MAX)
 455                        continue;
 456
 457                if (of_property_read_string(np, "clock-output-names", &name))
 458                        name = periphclknp->name;
 459
 460                if (type == PERIPHERAL_AT91RM9200) {
 461                        hw = at91_clk_register_peripheral(regmap, name,
 462                                                          parent_name, id);
 463                } else {
 464                        struct clk_range range = CLK_RANGE(0, 0);
 465
 466                        of_at91_get_clk_range(periphclknp,
 467                                              "atmel,clk-output-range",
 468                                              &range);
 469
 470                        hw = at91_clk_register_sam9x5_peripheral(regmap,
 471                                                                 &pmc_pcr_lock,
 472                                                                 &dt_pcr_layout,
 473                                                                 name,
 474                                                                 parent_name,
 475                                                                 id, &range,
 476                                                                 INT_MIN);
 477                }
 478
 479                if (IS_ERR(hw))
 480                        continue;
 481
 482                of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
 483        }
 484}
 485
 486static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
 487{
 488        of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
 489}
 490CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
 491               of_at91rm9200_clk_periph_setup);
 492
 493static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
 494{
 495        of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
 496}
 497CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
 498               of_at91sam9x5_clk_periph_setup);
 499
 500static struct clk_pll_characteristics * __init
 501of_at91_clk_pll_get_characteristics(struct device_node *np)
 502{
 503        int i;
 504        int offset;
 505        u32 tmp;
 506        int num_output;
 507        u32 num_cells;
 508        struct clk_range input;
 509        struct clk_range *output;
 510        u8 *out = NULL;
 511        u16 *icpll = NULL;
 512        struct clk_pll_characteristics *characteristics;
 513
 514        if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
 515                return NULL;
 516
 517        if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
 518                                 &num_cells))
 519                return NULL;
 520
 521        if (num_cells < 2 || num_cells > 4)
 522                return NULL;
 523
 524        if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
 525                return NULL;
 526        num_output = tmp / (sizeof(u32) * num_cells);
 527
 528        characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
 529        if (!characteristics)
 530                return NULL;
 531
 532        output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
 533        if (!output)
 534                goto out_free_characteristics;
 535
 536        if (num_cells > 2) {
 537                out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
 538                if (!out)
 539                        goto out_free_output;
 540        }
 541
 542        if (num_cells > 3) {
 543                icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
 544                if (!icpll)
 545                        goto out_free_output;
 546        }
 547
 548        for (i = 0; i < num_output; i++) {
 549                offset = i * num_cells;
 550                if (of_property_read_u32_index(np,
 551                                               "atmel,pll-clk-output-ranges",
 552                                               offset, &tmp))
 553                        goto out_free_output;
 554                output[i].min = tmp;
 555                if (of_property_read_u32_index(np,
 556                                               "atmel,pll-clk-output-ranges",
 557                                               offset + 1, &tmp))
 558                        goto out_free_output;
 559                output[i].max = tmp;
 560
 561                if (num_cells == 2)
 562                        continue;
 563
 564                if (of_property_read_u32_index(np,
 565                                               "atmel,pll-clk-output-ranges",
 566                                               offset + 2, &tmp))
 567                        goto out_free_output;
 568                out[i] = tmp;
 569
 570                if (num_cells == 3)
 571                        continue;
 572
 573                if (of_property_read_u32_index(np,
 574                                               "atmel,pll-clk-output-ranges",
 575                                               offset + 3, &tmp))
 576                        goto out_free_output;
 577                icpll[i] = tmp;
 578        }
 579
 580        characteristics->input = input;
 581        characteristics->num_output = num_output;
 582        characteristics->output = output;
 583        characteristics->out = out;
 584        characteristics->icpll = icpll;
 585        return characteristics;
 586
 587out_free_output:
 588        kfree(icpll);
 589        kfree(out);
 590        kfree(output);
 591out_free_characteristics:
 592        kfree(characteristics);
 593        return NULL;
 594}
 595
 596static void __init
 597of_at91_clk_pll_setup(struct device_node *np,
 598                      const struct clk_pll_layout *layout)
 599{
 600        u32 id;
 601        struct clk_hw *hw;
 602        struct regmap *regmap;
 603        const char *parent_name;
 604        const char *name = np->name;
 605        struct clk_pll_characteristics *characteristics;
 606
 607        if (of_property_read_u32(np, "reg", &id))
 608                return;
 609
 610        parent_name = of_clk_get_parent_name(np, 0);
 611
 612        of_property_read_string(np, "clock-output-names", &name);
 613
 614        regmap = syscon_node_to_regmap(of_get_parent(np));
 615        if (IS_ERR(regmap))
 616                return;
 617
 618        characteristics = of_at91_clk_pll_get_characteristics(np);
 619        if (!characteristics)
 620                return;
 621
 622        hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
 623                                   characteristics);
 624        if (IS_ERR(hw))
 625                goto out_free_characteristics;
 626
 627        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 628        return;
 629
 630out_free_characteristics:
 631        kfree(characteristics);
 632}
 633
 634static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
 635{
 636        of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
 637}
 638CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
 639               of_at91rm9200_clk_pll_setup);
 640
 641static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
 642{
 643        of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
 644}
 645CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
 646               of_at91sam9g45_clk_pll_setup);
 647
 648static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
 649{
 650        of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
 651}
 652CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
 653               of_at91sam9g20_clk_pllb_setup);
 654
 655static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
 656{
 657        of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
 658}
 659CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
 660               of_sama5d3_clk_pll_setup);
 661
 662static void __init
 663of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
 664{
 665        struct clk_hw *hw;
 666        const char *parent_name;
 667        const char *name = np->name;
 668        struct regmap *regmap;
 669
 670        parent_name = of_clk_get_parent_name(np, 0);
 671
 672        of_property_read_string(np, "clock-output-names", &name);
 673
 674        regmap = syscon_node_to_regmap(of_get_parent(np));
 675        if (IS_ERR(regmap))
 676                return;
 677
 678        hw = at91_clk_register_plldiv(regmap, name, parent_name);
 679        if (IS_ERR(hw))
 680                return;
 681
 682        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 683}
 684CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
 685               of_at91sam9x5_clk_plldiv_setup);
 686
 687static void __init
 688of_at91_clk_prog_setup(struct device_node *np,
 689                       const struct clk_programmable_layout *layout,
 690                       u32 *mux_table)
 691{
 692        int num;
 693        u32 id;
 694        struct clk_hw *hw;
 695        unsigned int num_parents;
 696        const char *parent_names[PROG_SOURCE_MAX];
 697        const char *name;
 698        struct device_node *progclknp;
 699        struct regmap *regmap;
 700
 701        num_parents = of_clk_get_parent_count(np);
 702        if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
 703                return;
 704
 705        of_clk_parent_fill(np, parent_names, num_parents);
 706
 707        num = of_get_child_count(np);
 708        if (!num || num > (PROG_ID_MAX + 1))
 709                return;
 710
 711        regmap = syscon_node_to_regmap(of_get_parent(np));
 712        if (IS_ERR(regmap))
 713                return;
 714
 715        for_each_child_of_node(np, progclknp) {
 716                if (of_property_read_u32(progclknp, "reg", &id))
 717                        continue;
 718
 719                if (of_property_read_string(np, "clock-output-names", &name))
 720                        name = progclknp->name;
 721
 722                hw = at91_clk_register_programmable(regmap, name,
 723                                                    parent_names, num_parents,
 724                                                    id, layout, mux_table);
 725                if (IS_ERR(hw))
 726                        continue;
 727
 728                of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
 729        }
 730}
 731
 732static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
 733{
 734        of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout, NULL);
 735}
 736CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
 737               of_at91rm9200_clk_prog_setup);
 738
 739static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
 740{
 741        of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout, NULL);
 742}
 743CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
 744               of_at91sam9g45_clk_prog_setup);
 745
 746static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
 747{
 748        of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout, NULL);
 749}
 750CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
 751               of_at91sam9x5_clk_prog_setup);
 752
 753static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
 754{
 755        struct clk_hw *hw;
 756        const char *parent_names[2];
 757        unsigned int num_parents;
 758        const char *name = np->name;
 759        struct regmap *regmap;
 760
 761        num_parents = of_clk_get_parent_count(np);
 762        if (num_parents != 2)
 763                return;
 764
 765        of_clk_parent_fill(np, parent_names, num_parents);
 766        regmap = syscon_node_to_regmap(of_get_parent(np));
 767        if (IS_ERR(regmap))
 768                return;
 769
 770        of_property_read_string(np, "clock-output-names", &name);
 771
 772        hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
 773                                            num_parents);
 774        if (IS_ERR(hw))
 775                return;
 776
 777        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 778}
 779CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
 780               of_at91sam9260_clk_slow_setup);
 781
 782#ifdef CONFIG_HAVE_AT91_SMD
 783#define SMD_SOURCE_MAX          2
 784
 785static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
 786{
 787        struct clk_hw *hw;
 788        unsigned int num_parents;
 789        const char *parent_names[SMD_SOURCE_MAX];
 790        const char *name = np->name;
 791        struct regmap *regmap;
 792
 793        num_parents = of_clk_get_parent_count(np);
 794        if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
 795                return;
 796
 797        of_clk_parent_fill(np, parent_names, num_parents);
 798
 799        of_property_read_string(np, "clock-output-names", &name);
 800
 801        regmap = syscon_node_to_regmap(of_get_parent(np));
 802        if (IS_ERR(regmap))
 803                return;
 804
 805        hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
 806                                         num_parents);
 807        if (IS_ERR(hw))
 808                return;
 809
 810        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 811}
 812CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
 813               of_at91sam9x5_clk_smd_setup);
 814#endif /* CONFIG_HAVE_AT91_SMD */
 815
 816static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
 817{
 818        int num;
 819        u32 id;
 820        struct clk_hw *hw;
 821        const char *name;
 822        struct device_node *sysclknp;
 823        const char *parent_name;
 824        struct regmap *regmap;
 825
 826        num = of_get_child_count(np);
 827        if (num > (SYSTEM_MAX_ID + 1))
 828                return;
 829
 830        regmap = syscon_node_to_regmap(of_get_parent(np));
 831        if (IS_ERR(regmap))
 832                return;
 833
 834        for_each_child_of_node(np, sysclknp) {
 835                if (of_property_read_u32(sysclknp, "reg", &id))
 836                        continue;
 837
 838                if (of_property_read_string(np, "clock-output-names", &name))
 839                        name = sysclknp->name;
 840
 841                parent_name = of_clk_get_parent_name(sysclknp, 0);
 842
 843                hw = at91_clk_register_system(regmap, name, parent_name, id);
 844                if (IS_ERR(hw))
 845                        continue;
 846
 847                of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
 848        }
 849}
 850CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
 851               of_at91rm9200_clk_sys_setup);
 852
 853#ifdef CONFIG_HAVE_AT91_USB_CLK
 854#define USB_SOURCE_MAX          2
 855
 856static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
 857{
 858        struct clk_hw *hw;
 859        unsigned int num_parents;
 860        const char *parent_names[USB_SOURCE_MAX];
 861        const char *name = np->name;
 862        struct regmap *regmap;
 863
 864        num_parents = of_clk_get_parent_count(np);
 865        if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
 866                return;
 867
 868        of_clk_parent_fill(np, parent_names, num_parents);
 869
 870        of_property_read_string(np, "clock-output-names", &name);
 871
 872        regmap = syscon_node_to_regmap(of_get_parent(np));
 873        if (IS_ERR(regmap))
 874                return;
 875
 876        hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
 877                                         num_parents);
 878        if (IS_ERR(hw))
 879                return;
 880
 881        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 882}
 883CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
 884               of_at91sam9x5_clk_usb_setup);
 885
 886static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
 887{
 888        struct clk_hw *hw;
 889        const char *parent_name;
 890        const char *name = np->name;
 891        struct regmap *regmap;
 892
 893        parent_name = of_clk_get_parent_name(np, 0);
 894        if (!parent_name)
 895                return;
 896
 897        of_property_read_string(np, "clock-output-names", &name);
 898
 899        regmap = syscon_node_to_regmap(of_get_parent(np));
 900        if (IS_ERR(regmap))
 901                return;
 902
 903        hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
 904        if (IS_ERR(hw))
 905                return;
 906
 907        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 908}
 909CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
 910               of_at91sam9n12_clk_usb_setup);
 911
 912static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
 913{
 914        struct clk_hw *hw;
 915        const char *parent_name;
 916        const char *name = np->name;
 917        u32 divisors[4] = {0, 0, 0, 0};
 918        struct regmap *regmap;
 919
 920        parent_name = of_clk_get_parent_name(np, 0);
 921        if (!parent_name)
 922                return;
 923
 924        of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
 925        if (!divisors[0])
 926                return;
 927
 928        of_property_read_string(np, "clock-output-names", &name);
 929
 930        regmap = syscon_node_to_regmap(of_get_parent(np));
 931        if (IS_ERR(regmap))
 932                return;
 933        hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
 934        if (IS_ERR(hw))
 935                return;
 936
 937        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 938}
 939CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
 940               of_at91rm9200_clk_usb_setup);
 941#endif /* CONFIG_HAVE_AT91_USB_CLK */
 942
 943#ifdef CONFIG_HAVE_AT91_UTMI
 944static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
 945{
 946        struct clk_hw *hw;
 947        const char *parent_name;
 948        const char *name = np->name;
 949        struct regmap *regmap_pmc, *regmap_sfr;
 950
 951        parent_name = of_clk_get_parent_name(np, 0);
 952
 953        of_property_read_string(np, "clock-output-names", &name);
 954
 955        regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
 956        if (IS_ERR(regmap_pmc))
 957                return;
 958
 959        /*
 960         * If the device supports different mainck rates, this value has to be
 961         * set in the UTMI Clock Trimming register.
 962         * - 9x5: mainck supports several rates but it is indicated that a
 963         *   12 MHz is needed in case of USB.
 964         * - sama5d3 and sama5d2: mainck supports several rates. Configuring
 965         *   the FREQ field of the UTMI Clock Trimming register is mandatory.
 966         * - sama5d4: mainck is at 12 MHz.
 967         *
 968         * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
 969         */
 970        regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
 971        if (IS_ERR(regmap_sfr)) {
 972                regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
 973                if (IS_ERR(regmap_sfr))
 974                        regmap_sfr = NULL;
 975        }
 976
 977        hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
 978        if (IS_ERR(hw))
 979                return;
 980
 981        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 982}
 983CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
 984               of_at91sam9x5_clk_utmi_setup);
 985#endif /* CONFIG_HAVE_AT91_UTMI */
 986