Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/clk-provider.h>
0003 #include <linux/clk/at91_pmc.h>
0004 #include <linux/of.h>
0005 #include <linux/mfd/syscon.h>
0006 #include <linux/regmap.h>
0007 #include <linux/slab.h>
0008 
0009 #include "pmc.h"
0010 
0011 #define MASTER_SOURCE_MAX   4
0012 
0013 #define PERIPHERAL_AT91RM9200   0
0014 #define PERIPHERAL_AT91SAM9X5   1
0015 
0016 #define PERIPHERAL_MAX      64
0017 
0018 #define PERIPHERAL_ID_MIN   2
0019 
0020 #define PROG_SOURCE_MAX     5
0021 #define PROG_ID_MAX     7
0022 
0023 #define SYSTEM_MAX_ID       31
0024 
0025 #define GCK_INDEX_DT_AUDIO_PLL  5
0026 
0027 static DEFINE_SPINLOCK(mck_lock);
0028 
0029 #ifdef CONFIG_HAVE_AT91_AUDIO_PLL
0030 static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
0031 {
0032     struct clk_hw *hw;
0033     const char *name = np->name;
0034     const char *parent_name;
0035     struct regmap *regmap;
0036 
0037     regmap = syscon_node_to_regmap(of_get_parent(np));
0038     if (IS_ERR(regmap))
0039         return;
0040 
0041     parent_name = of_clk_get_parent_name(np, 0);
0042 
0043     hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name);
0044     if (IS_ERR(hw))
0045         return;
0046 
0047     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0048 }
0049 CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
0050            "atmel,sama5d2-clk-audio-pll-frac",
0051            of_sama5d2_clk_audio_pll_frac_setup);
0052 
0053 static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
0054 {
0055     struct clk_hw *hw;
0056     const char *name = np->name;
0057     const char *parent_name;
0058     struct regmap *regmap;
0059 
0060     regmap = syscon_node_to_regmap(of_get_parent(np));
0061     if (IS_ERR(regmap))
0062         return;
0063 
0064     parent_name = of_clk_get_parent_name(np, 0);
0065 
0066     hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name);
0067     if (IS_ERR(hw))
0068         return;
0069 
0070     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0071 }
0072 CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
0073            "atmel,sama5d2-clk-audio-pll-pad",
0074            of_sama5d2_clk_audio_pll_pad_setup);
0075 
0076 static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
0077 {
0078     struct clk_hw *hw;
0079     const char *name = np->name;
0080     const char *parent_name;
0081     struct regmap *regmap;
0082 
0083     regmap = syscon_node_to_regmap(of_get_parent(np));
0084     if (IS_ERR(regmap))
0085         return;
0086 
0087     parent_name = of_clk_get_parent_name(np, 0);
0088 
0089     hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name);
0090     if (IS_ERR(hw))
0091         return;
0092 
0093     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0094 }
0095 CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
0096            "atmel,sama5d2-clk-audio-pll-pmc",
0097            of_sama5d2_clk_audio_pll_pmc_setup);
0098 #endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
0099 
0100 static const struct clk_pcr_layout dt_pcr_layout = {
0101     .offset = 0x10c,
0102     .cmd = BIT(12),
0103     .pid_mask = GENMASK(5, 0),
0104     .div_mask = GENMASK(17, 16),
0105     .gckcss_mask = GENMASK(10, 8),
0106 };
0107 
0108 #ifdef CONFIG_HAVE_AT91_GENERATED_CLK
0109 #define GENERATED_SOURCE_MAX    6
0110 
0111 #define GCK_ID_I2S0     54
0112 #define GCK_ID_I2S1     55
0113 #define GCK_ID_CLASSD       59
0114 
0115 static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
0116 {
0117     int num;
0118     u32 id;
0119     const char *name;
0120     struct clk_hw *hw;
0121     unsigned int num_parents;
0122     const char *parent_names[GENERATED_SOURCE_MAX];
0123     struct device_node *gcknp;
0124     struct clk_range range = CLK_RANGE(0, 0);
0125     struct regmap *regmap;
0126 
0127     num_parents = of_clk_get_parent_count(np);
0128     if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
0129         return;
0130 
0131     of_clk_parent_fill(np, parent_names, num_parents);
0132 
0133     num = of_get_child_count(np);
0134     if (!num || num > PERIPHERAL_MAX)
0135         return;
0136 
0137     regmap = syscon_node_to_regmap(of_get_parent(np));
0138     if (IS_ERR(regmap))
0139         return;
0140 
0141     for_each_child_of_node(np, gcknp) {
0142         int chg_pid = INT_MIN;
0143 
0144         if (of_property_read_u32(gcknp, "reg", &id))
0145             continue;
0146 
0147         if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
0148             continue;
0149 
0150         if (of_property_read_string(np, "clock-output-names", &name))
0151             name = gcknp->name;
0152 
0153         of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
0154                       &range);
0155 
0156         if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") &&
0157             (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 ||
0158              id == GCK_ID_CLASSD))
0159             chg_pid = GCK_INDEX_DT_AUDIO_PLL;
0160 
0161         hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
0162                          &dt_pcr_layout, name,
0163                          parent_names, NULL,
0164                          num_parents, id, &range,
0165                          chg_pid);
0166         if (IS_ERR(hw))
0167             continue;
0168 
0169         of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
0170     }
0171 }
0172 CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
0173            of_sama5d2_clk_generated_setup);
0174 #endif /* CONFIG_HAVE_AT91_GENERATED_CLK */
0175 
0176 #ifdef CONFIG_HAVE_AT91_H32MX
0177 static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
0178 {
0179     struct clk_hw *hw;
0180     const char *name = np->name;
0181     const char *parent_name;
0182     struct regmap *regmap;
0183 
0184     regmap = syscon_node_to_regmap(of_get_parent(np));
0185     if (IS_ERR(regmap))
0186         return;
0187 
0188     parent_name = of_clk_get_parent_name(np, 0);
0189 
0190     hw = at91_clk_register_h32mx(regmap, name, parent_name);
0191     if (IS_ERR(hw))
0192         return;
0193 
0194     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0195 }
0196 CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
0197            of_sama5d4_clk_h32mx_setup);
0198 #endif /* CONFIG_HAVE_AT91_H32MX */
0199 
0200 #ifdef CONFIG_HAVE_AT91_I2S_MUX_CLK
0201 #define I2S_BUS_NR  2
0202 
0203 static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
0204 {
0205     struct regmap *regmap_sfr;
0206     u8 bus_id;
0207     const char *parent_names[2];
0208     struct device_node *i2s_mux_np;
0209     struct clk_hw *hw;
0210     int ret;
0211 
0212     regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
0213     if (IS_ERR(regmap_sfr))
0214         return;
0215 
0216     for_each_child_of_node(np, i2s_mux_np) {
0217         if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
0218             continue;
0219 
0220         if (bus_id > I2S_BUS_NR)
0221             continue;
0222 
0223         ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
0224         if (ret != 2)
0225             continue;
0226 
0227         hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
0228                            parent_names, 2, bus_id);
0229         if (IS_ERR(hw))
0230             continue;
0231 
0232         of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
0233     }
0234 }
0235 CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
0236            of_sama5d2_clk_i2s_mux_setup);
0237 #endif /* CONFIG_HAVE_AT91_I2S_MUX_CLK */
0238 
0239 static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
0240 {
0241     struct clk_hw *hw;
0242     const char *name = np->name;
0243     const char *parent_name;
0244     struct regmap *regmap;
0245     bool bypass;
0246 
0247     of_property_read_string(np, "clock-output-names", &name);
0248     bypass = of_property_read_bool(np, "atmel,osc-bypass");
0249     parent_name = of_clk_get_parent_name(np, 0);
0250 
0251     regmap = syscon_node_to_regmap(of_get_parent(np));
0252     if (IS_ERR(regmap))
0253         return;
0254 
0255     hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
0256     if (IS_ERR(hw))
0257         return;
0258 
0259     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0260 }
0261 CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
0262            of_at91rm9200_clk_main_osc_setup);
0263 
0264 static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
0265 {
0266     struct clk_hw *hw;
0267     u32 frequency = 0;
0268     u32 accuracy = 0;
0269     const char *name = np->name;
0270     struct regmap *regmap;
0271 
0272     of_property_read_string(np, "clock-output-names", &name);
0273     of_property_read_u32(np, "clock-frequency", &frequency);
0274     of_property_read_u32(np, "clock-accuracy", &accuracy);
0275 
0276     regmap = syscon_node_to_regmap(of_get_parent(np));
0277     if (IS_ERR(regmap))
0278         return;
0279 
0280     hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
0281     if (IS_ERR(hw))
0282         return;
0283 
0284     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0285 }
0286 CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
0287            of_at91sam9x5_clk_main_rc_osc_setup);
0288 
0289 static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
0290 {
0291     struct clk_hw *hw;
0292     const char *parent_name;
0293     const char *name = np->name;
0294     struct regmap *regmap;
0295 
0296     parent_name = of_clk_get_parent_name(np, 0);
0297     of_property_read_string(np, "clock-output-names", &name);
0298 
0299     regmap = syscon_node_to_regmap(of_get_parent(np));
0300     if (IS_ERR(regmap))
0301         return;
0302 
0303     hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
0304     if (IS_ERR(hw))
0305         return;
0306 
0307     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0308 }
0309 CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
0310            of_at91rm9200_clk_main_setup);
0311 
0312 static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
0313 {
0314     struct clk_hw *hw;
0315     const char *parent_names[2];
0316     unsigned int num_parents;
0317     const char *name = np->name;
0318     struct regmap *regmap;
0319 
0320     num_parents = of_clk_get_parent_count(np);
0321     if (num_parents == 0 || num_parents > 2)
0322         return;
0323 
0324     of_clk_parent_fill(np, parent_names, num_parents);
0325     regmap = syscon_node_to_regmap(of_get_parent(np));
0326     if (IS_ERR(regmap))
0327         return;
0328 
0329     of_property_read_string(np, "clock-output-names", &name);
0330 
0331     hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
0332                        num_parents);
0333     if (IS_ERR(hw))
0334         return;
0335 
0336     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0337 }
0338 CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
0339            of_at91sam9x5_clk_main_setup);
0340 
0341 static struct clk_master_characteristics * __init
0342 of_at91_clk_master_get_characteristics(struct device_node *np)
0343 {
0344     struct clk_master_characteristics *characteristics;
0345 
0346     characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
0347     if (!characteristics)
0348         return NULL;
0349 
0350     if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
0351         goto out_free_characteristics;
0352 
0353     of_property_read_u32_array(np, "atmel,clk-divisors",
0354                    characteristics->divisors, 4);
0355 
0356     characteristics->have_div3_pres =
0357         of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
0358 
0359     return characteristics;
0360 
0361 out_free_characteristics:
0362     kfree(characteristics);
0363     return NULL;
0364 }
0365 
0366 static void __init
0367 of_at91_clk_master_setup(struct device_node *np,
0368              const struct clk_master_layout *layout)
0369 {
0370     struct clk_hw *hw;
0371     unsigned int num_parents;
0372     const char *parent_names[MASTER_SOURCE_MAX];
0373     const char *name = np->name;
0374     struct clk_master_characteristics *characteristics;
0375     struct regmap *regmap;
0376 
0377     num_parents = of_clk_get_parent_count(np);
0378     if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
0379         return;
0380 
0381     of_clk_parent_fill(np, parent_names, num_parents);
0382 
0383     of_property_read_string(np, "clock-output-names", &name);
0384 
0385     characteristics = of_at91_clk_master_get_characteristics(np);
0386     if (!characteristics)
0387         return;
0388 
0389     regmap = syscon_node_to_regmap(of_get_parent(np));
0390     if (IS_ERR(regmap))
0391         return;
0392 
0393     hw = at91_clk_register_master_pres(regmap, "masterck_pres", num_parents,
0394                        parent_names, layout,
0395                        characteristics, &mck_lock);
0396     if (IS_ERR(hw))
0397         goto out_free_characteristics;
0398 
0399     hw = at91_clk_register_master_div(regmap, name, "masterck_pres",
0400                       layout, characteristics,
0401                       &mck_lock, CLK_SET_RATE_GATE, 0);
0402     if (IS_ERR(hw))
0403         goto out_free_characteristics;
0404 
0405     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0406     return;
0407 
0408 out_free_characteristics:
0409     kfree(characteristics);
0410 }
0411 
0412 static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
0413 {
0414     of_at91_clk_master_setup(np, &at91rm9200_master_layout);
0415 }
0416 CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
0417            of_at91rm9200_clk_master_setup);
0418 
0419 static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
0420 {
0421     of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
0422 }
0423 CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
0424            of_at91sam9x5_clk_master_setup);
0425 
0426 static void __init
0427 of_at91_clk_periph_setup(struct device_node *np, u8 type)
0428 {
0429     int num;
0430     u32 id;
0431     struct clk_hw *hw;
0432     const char *parent_name;
0433     const char *name;
0434     struct device_node *periphclknp;
0435     struct regmap *regmap;
0436 
0437     parent_name = of_clk_get_parent_name(np, 0);
0438     if (!parent_name)
0439         return;
0440 
0441     num = of_get_child_count(np);
0442     if (!num || num > PERIPHERAL_MAX)
0443         return;
0444 
0445     regmap = syscon_node_to_regmap(of_get_parent(np));
0446     if (IS_ERR(regmap))
0447         return;
0448 
0449     for_each_child_of_node(np, periphclknp) {
0450         if (of_property_read_u32(periphclknp, "reg", &id))
0451             continue;
0452 
0453         if (id >= PERIPHERAL_MAX)
0454             continue;
0455 
0456         if (of_property_read_string(np, "clock-output-names", &name))
0457             name = periphclknp->name;
0458 
0459         if (type == PERIPHERAL_AT91RM9200) {
0460             hw = at91_clk_register_peripheral(regmap, name,
0461                               parent_name, id);
0462         } else {
0463             struct clk_range range = CLK_RANGE(0, 0);
0464 
0465             of_at91_get_clk_range(periphclknp,
0466                           "atmel,clk-output-range",
0467                           &range);
0468 
0469             hw = at91_clk_register_sam9x5_peripheral(regmap,
0470                                  &pmc_pcr_lock,
0471                                  &dt_pcr_layout,
0472                                  name,
0473                                  parent_name,
0474                                  id, &range,
0475                                  INT_MIN);
0476         }
0477 
0478         if (IS_ERR(hw))
0479             continue;
0480 
0481         of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
0482     }
0483 }
0484 
0485 static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
0486 {
0487     of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
0488 }
0489 CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
0490            of_at91rm9200_clk_periph_setup);
0491 
0492 static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
0493 {
0494     of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
0495 }
0496 CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
0497            of_at91sam9x5_clk_periph_setup);
0498 
0499 static struct clk_pll_characteristics * __init
0500 of_at91_clk_pll_get_characteristics(struct device_node *np)
0501 {
0502     int i;
0503     int offset;
0504     u32 tmp;
0505     int num_output;
0506     u32 num_cells;
0507     struct clk_range input;
0508     struct clk_range *output;
0509     u8 *out = NULL;
0510     u16 *icpll = NULL;
0511     struct clk_pll_characteristics *characteristics;
0512 
0513     if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
0514         return NULL;
0515 
0516     if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
0517                  &num_cells))
0518         return NULL;
0519 
0520     if (num_cells < 2 || num_cells > 4)
0521         return NULL;
0522 
0523     if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
0524         return NULL;
0525     num_output = tmp / (sizeof(u32) * num_cells);
0526 
0527     characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
0528     if (!characteristics)
0529         return NULL;
0530 
0531     output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
0532     if (!output)
0533         goto out_free_characteristics;
0534 
0535     if (num_cells > 2) {
0536         out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
0537         if (!out)
0538             goto out_free_output;
0539     }
0540 
0541     if (num_cells > 3) {
0542         icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
0543         if (!icpll)
0544             goto out_free_output;
0545     }
0546 
0547     for (i = 0; i < num_output; i++) {
0548         offset = i * num_cells;
0549         if (of_property_read_u32_index(np,
0550                            "atmel,pll-clk-output-ranges",
0551                            offset, &tmp))
0552             goto out_free_output;
0553         output[i].min = tmp;
0554         if (of_property_read_u32_index(np,
0555                            "atmel,pll-clk-output-ranges",
0556                            offset + 1, &tmp))
0557             goto out_free_output;
0558         output[i].max = tmp;
0559 
0560         if (num_cells == 2)
0561             continue;
0562 
0563         if (of_property_read_u32_index(np,
0564                            "atmel,pll-clk-output-ranges",
0565                            offset + 2, &tmp))
0566             goto out_free_output;
0567         out[i] = tmp;
0568 
0569         if (num_cells == 3)
0570             continue;
0571 
0572         if (of_property_read_u32_index(np,
0573                            "atmel,pll-clk-output-ranges",
0574                            offset + 3, &tmp))
0575             goto out_free_output;
0576         icpll[i] = tmp;
0577     }
0578 
0579     characteristics->input = input;
0580     characteristics->num_output = num_output;
0581     characteristics->output = output;
0582     characteristics->out = out;
0583     characteristics->icpll = icpll;
0584     return characteristics;
0585 
0586 out_free_output:
0587     kfree(icpll);
0588     kfree(out);
0589     kfree(output);
0590 out_free_characteristics:
0591     kfree(characteristics);
0592     return NULL;
0593 }
0594 
0595 static void __init
0596 of_at91_clk_pll_setup(struct device_node *np,
0597               const struct clk_pll_layout *layout)
0598 {
0599     u32 id;
0600     struct clk_hw *hw;
0601     struct regmap *regmap;
0602     const char *parent_name;
0603     const char *name = np->name;
0604     struct clk_pll_characteristics *characteristics;
0605 
0606     if (of_property_read_u32(np, "reg", &id))
0607         return;
0608 
0609     parent_name = of_clk_get_parent_name(np, 0);
0610 
0611     of_property_read_string(np, "clock-output-names", &name);
0612 
0613     regmap = syscon_node_to_regmap(of_get_parent(np));
0614     if (IS_ERR(regmap))
0615         return;
0616 
0617     characteristics = of_at91_clk_pll_get_characteristics(np);
0618     if (!characteristics)
0619         return;
0620 
0621     hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
0622                    characteristics);
0623     if (IS_ERR(hw))
0624         goto out_free_characteristics;
0625 
0626     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0627     return;
0628 
0629 out_free_characteristics:
0630     kfree(characteristics);
0631 }
0632 
0633 static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
0634 {
0635     of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
0636 }
0637 CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
0638            of_at91rm9200_clk_pll_setup);
0639 
0640 static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
0641 {
0642     of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
0643 }
0644 CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
0645            of_at91sam9g45_clk_pll_setup);
0646 
0647 static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
0648 {
0649     of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
0650 }
0651 CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
0652            of_at91sam9g20_clk_pllb_setup);
0653 
0654 static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
0655 {
0656     of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
0657 }
0658 CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
0659            of_sama5d3_clk_pll_setup);
0660 
0661 static void __init
0662 of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
0663 {
0664     struct clk_hw *hw;
0665     const char *parent_name;
0666     const char *name = np->name;
0667     struct regmap *regmap;
0668 
0669     parent_name = of_clk_get_parent_name(np, 0);
0670 
0671     of_property_read_string(np, "clock-output-names", &name);
0672 
0673     regmap = syscon_node_to_regmap(of_get_parent(np));
0674     if (IS_ERR(regmap))
0675         return;
0676 
0677     hw = at91_clk_register_plldiv(regmap, name, parent_name);
0678     if (IS_ERR(hw))
0679         return;
0680 
0681     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0682 }
0683 CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
0684            of_at91sam9x5_clk_plldiv_setup);
0685 
0686 static void __init
0687 of_at91_clk_prog_setup(struct device_node *np,
0688                const struct clk_programmable_layout *layout,
0689                u32 *mux_table)
0690 {
0691     int num;
0692     u32 id;
0693     struct clk_hw *hw;
0694     unsigned int num_parents;
0695     const char *parent_names[PROG_SOURCE_MAX];
0696     const char *name;
0697     struct device_node *progclknp;
0698     struct regmap *regmap;
0699 
0700     num_parents = of_clk_get_parent_count(np);
0701     if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
0702         return;
0703 
0704     of_clk_parent_fill(np, parent_names, num_parents);
0705 
0706     num = of_get_child_count(np);
0707     if (!num || num > (PROG_ID_MAX + 1))
0708         return;
0709 
0710     regmap = syscon_node_to_regmap(of_get_parent(np));
0711     if (IS_ERR(regmap))
0712         return;
0713 
0714     for_each_child_of_node(np, progclknp) {
0715         if (of_property_read_u32(progclknp, "reg", &id))
0716             continue;
0717 
0718         if (of_property_read_string(np, "clock-output-names", &name))
0719             name = progclknp->name;
0720 
0721         hw = at91_clk_register_programmable(regmap, name,
0722                             parent_names, num_parents,
0723                             id, layout, mux_table);
0724         if (IS_ERR(hw))
0725             continue;
0726 
0727         of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
0728     }
0729 }
0730 
0731 static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
0732 {
0733     of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout, NULL);
0734 }
0735 CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
0736            of_at91rm9200_clk_prog_setup);
0737 
0738 static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
0739 {
0740     of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout, NULL);
0741 }
0742 CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
0743            of_at91sam9g45_clk_prog_setup);
0744 
0745 static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
0746 {
0747     of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout, NULL);
0748 }
0749 CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
0750            of_at91sam9x5_clk_prog_setup);
0751 
0752 static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
0753 {
0754     struct clk_hw *hw;
0755     const char *parent_names[2];
0756     unsigned int num_parents;
0757     const char *name = np->name;
0758     struct regmap *regmap;
0759 
0760     num_parents = of_clk_get_parent_count(np);
0761     if (num_parents != 2)
0762         return;
0763 
0764     of_clk_parent_fill(np, parent_names, num_parents);
0765     regmap = syscon_node_to_regmap(of_get_parent(np));
0766     if (IS_ERR(regmap))
0767         return;
0768 
0769     of_property_read_string(np, "clock-output-names", &name);
0770 
0771     hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
0772                         num_parents);
0773     if (IS_ERR(hw))
0774         return;
0775 
0776     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0777 }
0778 CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
0779            of_at91sam9260_clk_slow_setup);
0780 
0781 #ifdef CONFIG_HAVE_AT91_SMD
0782 #define SMD_SOURCE_MAX      2
0783 
0784 static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
0785 {
0786     struct clk_hw *hw;
0787     unsigned int num_parents;
0788     const char *parent_names[SMD_SOURCE_MAX];
0789     const char *name = np->name;
0790     struct regmap *regmap;
0791 
0792     num_parents = of_clk_get_parent_count(np);
0793     if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
0794         return;
0795 
0796     of_clk_parent_fill(np, parent_names, num_parents);
0797 
0798     of_property_read_string(np, "clock-output-names", &name);
0799 
0800     regmap = syscon_node_to_regmap(of_get_parent(np));
0801     if (IS_ERR(regmap))
0802         return;
0803 
0804     hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
0805                      num_parents);
0806     if (IS_ERR(hw))
0807         return;
0808 
0809     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0810 }
0811 CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
0812            of_at91sam9x5_clk_smd_setup);
0813 #endif /* CONFIG_HAVE_AT91_SMD */
0814 
0815 static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
0816 {
0817     int num;
0818     u32 id;
0819     struct clk_hw *hw;
0820     const char *name;
0821     struct device_node *sysclknp;
0822     const char *parent_name;
0823     struct regmap *regmap;
0824 
0825     num = of_get_child_count(np);
0826     if (num > (SYSTEM_MAX_ID + 1))
0827         return;
0828 
0829     regmap = syscon_node_to_regmap(of_get_parent(np));
0830     if (IS_ERR(regmap))
0831         return;
0832 
0833     for_each_child_of_node(np, sysclknp) {
0834         if (of_property_read_u32(sysclknp, "reg", &id))
0835             continue;
0836 
0837         if (of_property_read_string(np, "clock-output-names", &name))
0838             name = sysclknp->name;
0839 
0840         parent_name = of_clk_get_parent_name(sysclknp, 0);
0841 
0842         hw = at91_clk_register_system(regmap, name, parent_name, id);
0843         if (IS_ERR(hw))
0844             continue;
0845 
0846         of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
0847     }
0848 }
0849 CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
0850            of_at91rm9200_clk_sys_setup);
0851 
0852 #ifdef CONFIG_HAVE_AT91_USB_CLK
0853 #define USB_SOURCE_MAX      2
0854 
0855 static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
0856 {
0857     struct clk_hw *hw;
0858     unsigned int num_parents;
0859     const char *parent_names[USB_SOURCE_MAX];
0860     const char *name = np->name;
0861     struct regmap *regmap;
0862 
0863     num_parents = of_clk_get_parent_count(np);
0864     if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
0865         return;
0866 
0867     of_clk_parent_fill(np, parent_names, num_parents);
0868 
0869     of_property_read_string(np, "clock-output-names", &name);
0870 
0871     regmap = syscon_node_to_regmap(of_get_parent(np));
0872     if (IS_ERR(regmap))
0873         return;
0874 
0875     hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
0876                      num_parents);
0877     if (IS_ERR(hw))
0878         return;
0879 
0880     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0881 }
0882 CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
0883            of_at91sam9x5_clk_usb_setup);
0884 
0885 static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
0886 {
0887     struct clk_hw *hw;
0888     const char *parent_name;
0889     const char *name = np->name;
0890     struct regmap *regmap;
0891 
0892     parent_name = of_clk_get_parent_name(np, 0);
0893     if (!parent_name)
0894         return;
0895 
0896     of_property_read_string(np, "clock-output-names", &name);
0897 
0898     regmap = syscon_node_to_regmap(of_get_parent(np));
0899     if (IS_ERR(regmap))
0900         return;
0901 
0902     hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
0903     if (IS_ERR(hw))
0904         return;
0905 
0906     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0907 }
0908 CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
0909            of_at91sam9n12_clk_usb_setup);
0910 
0911 static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
0912 {
0913     struct clk_hw *hw;
0914     const char *parent_name;
0915     const char *name = np->name;
0916     u32 divisors[4] = {0, 0, 0, 0};
0917     struct regmap *regmap;
0918 
0919     parent_name = of_clk_get_parent_name(np, 0);
0920     if (!parent_name)
0921         return;
0922 
0923     of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
0924     if (!divisors[0])
0925         return;
0926 
0927     of_property_read_string(np, "clock-output-names", &name);
0928 
0929     regmap = syscon_node_to_regmap(of_get_parent(np));
0930     if (IS_ERR(regmap))
0931         return;
0932     hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
0933     if (IS_ERR(hw))
0934         return;
0935 
0936     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0937 }
0938 CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
0939            of_at91rm9200_clk_usb_setup);
0940 #endif /* CONFIG_HAVE_AT91_USB_CLK */
0941 
0942 #ifdef CONFIG_HAVE_AT91_UTMI
0943 static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
0944 {
0945     struct clk_hw *hw;
0946     const char *parent_name;
0947     const char *name = np->name;
0948     struct regmap *regmap_pmc, *regmap_sfr;
0949 
0950     parent_name = of_clk_get_parent_name(np, 0);
0951 
0952     of_property_read_string(np, "clock-output-names", &name);
0953 
0954     regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
0955     if (IS_ERR(regmap_pmc))
0956         return;
0957 
0958     /*
0959      * If the device supports different mainck rates, this value has to be
0960      * set in the UTMI Clock Trimming register.
0961      * - 9x5: mainck supports several rates but it is indicated that a
0962      *   12 MHz is needed in case of USB.
0963      * - sama5d3 and sama5d2: mainck supports several rates. Configuring
0964      *   the FREQ field of the UTMI Clock Trimming register is mandatory.
0965      * - sama5d4: mainck is at 12 MHz.
0966      *
0967      * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
0968      */
0969     regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
0970     if (IS_ERR(regmap_sfr)) {
0971         regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
0972         if (IS_ERR(regmap_sfr))
0973             regmap_sfr = NULL;
0974     }
0975 
0976     hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
0977     if (IS_ERR(hw))
0978         return;
0979 
0980     of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
0981 }
0982 CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
0983            of_at91sam9x5_clk_utmi_setup);
0984 #endif /* CONFIG_HAVE_AT91_UTMI */