0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/bitops.h>
0011 #include <linux/clk.h>
0012 #include <linux/clk-provider.h>
0013 #include <linux/clkdev.h>
0014 #include <linux/device.h>
0015 #include <linux/errno.h>
0016 #include <linux/io.h>
0017 #include <linux/of.h>
0018 #include <linux/of_address.h>
0019
0020 #include <asm/mpc5121.h>
0021 #include <dt-bindings/clock/mpc512x-clock.h>
0022
0023 #include "mpc512x.h" /* our public mpc5121_clk_init() API */
0024
0025
0026 enum {
0027 MCLK_IDX_MUX0,
0028 MCLK_IDX_EN0,
0029 MCLK_IDX_DIV0,
0030 MCLK_MAX_IDX,
0031 };
0032
0033 #define NR_PSCS 12
0034 #define NR_MSCANS 4
0035 #define NR_SPDIFS 1
0036 #define NR_OUTCLK 4
0037 #define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS + NR_OUTCLK)
0038
0039
0040 enum {
0041
0042 MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC,
0043
0044 MPC512x_CLK_DDR,
0045 MPC512x_CLK_MEM,
0046 MPC512x_CLK_IIM,
0047
0048 MPC512x_CLK_DDR_UG,
0049 MPC512x_CLK_SDHC_x4,
0050 MPC512x_CLK_SDHC_UG,
0051 MPC512x_CLK_SDHC2_UG,
0052 MPC512x_CLK_DIU_x4,
0053 MPC512x_CLK_DIU_UG,
0054 MPC512x_CLK_MBX_BUS_UG,
0055 MPC512x_CLK_MBX_UG,
0056 MPC512x_CLK_MBX_3D_UG,
0057 MPC512x_CLK_PCI_UG,
0058 MPC512x_CLK_NFC_UG,
0059 MPC512x_CLK_LPC_UG,
0060 MPC512x_CLK_SPDIF_TX_IN,
0061
0062 MPC512x_CLK_MCLKS_FIRST,
0063 MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST
0064 + NR_MCLKS * MCLK_MAX_IDX,
0065
0066 MPC512x_CLK_LAST_PRIVATE,
0067 };
0068
0069
0070 static struct clk *clks[MPC512x_CLK_LAST_PRIVATE];
0071 static struct clk_onecell_data clk_data;
0072
0073
0074 static struct mpc512x_ccm __iomem *clkregs;
0075 static DEFINE_SPINLOCK(clklock);
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 static enum soc_type {
0095 MPC512x_SOC_MPC5121,
0096 MPC512x_SOC_MPC5123,
0097 MPC512x_SOC_MPC5125,
0098 } soc;
0099
0100 static void __init mpc512x_clk_determine_soc(void)
0101 {
0102 if (of_machine_is_compatible("fsl,mpc5121")) {
0103 soc = MPC512x_SOC_MPC5121;
0104 return;
0105 }
0106 if (of_machine_is_compatible("fsl,mpc5123")) {
0107 soc = MPC512x_SOC_MPC5123;
0108 return;
0109 }
0110 if (of_machine_is_compatible("fsl,mpc5125")) {
0111 soc = MPC512x_SOC_MPC5125;
0112 return;
0113 }
0114 }
0115
0116 static bool __init soc_has_mbx(void)
0117 {
0118 if (soc == MPC512x_SOC_MPC5121)
0119 return true;
0120 return false;
0121 }
0122
0123 static bool __init soc_has_axe(void)
0124 {
0125 if (soc == MPC512x_SOC_MPC5125)
0126 return false;
0127 return true;
0128 }
0129
0130 static bool __init soc_has_viu(void)
0131 {
0132 if (soc == MPC512x_SOC_MPC5125)
0133 return false;
0134 return true;
0135 }
0136
0137 static bool __init soc_has_spdif(void)
0138 {
0139 if (soc == MPC512x_SOC_MPC5125)
0140 return false;
0141 return true;
0142 }
0143
0144 static bool __init soc_has_pata(void)
0145 {
0146 if (soc == MPC512x_SOC_MPC5125)
0147 return false;
0148 return true;
0149 }
0150
0151 static bool __init soc_has_sata(void)
0152 {
0153 if (soc == MPC512x_SOC_MPC5125)
0154 return false;
0155 return true;
0156 }
0157
0158 static bool __init soc_has_pci(void)
0159 {
0160 if (soc == MPC512x_SOC_MPC5125)
0161 return false;
0162 return true;
0163 }
0164
0165 static bool __init soc_has_fec2(void)
0166 {
0167 if (soc == MPC512x_SOC_MPC5125)
0168 return true;
0169 return false;
0170 }
0171
0172 static int __init soc_max_pscnum(void)
0173 {
0174 if (soc == MPC512x_SOC_MPC5125)
0175 return 10;
0176 return 12;
0177 }
0178
0179 static bool __init soc_has_sdhc2(void)
0180 {
0181 if (soc == MPC512x_SOC_MPC5125)
0182 return true;
0183 return false;
0184 }
0185
0186 static bool __init soc_has_nfc_5125(void)
0187 {
0188 if (soc == MPC512x_SOC_MPC5125)
0189 return true;
0190 return false;
0191 }
0192
0193 static bool __init soc_has_outclk(void)
0194 {
0195 if (soc == MPC512x_SOC_MPC5125)
0196 return true;
0197 return false;
0198 }
0199
0200 static bool __init soc_has_cpmf_0_bypass(void)
0201 {
0202 if (soc == MPC512x_SOC_MPC5125)
0203 return true;
0204 return false;
0205 }
0206
0207 static bool __init soc_has_mclk_mux0_canin(void)
0208 {
0209 if (soc == MPC512x_SOC_MPC5125)
0210 return true;
0211 return false;
0212 }
0213
0214
0215
0216
0217
0218 static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)
0219 {
0220 return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
0221 }
0222
0223 static inline struct clk *mpc512x_clk_factor(
0224 const char *name, const char *parent_name,
0225 int mul, int div)
0226 {
0227 int clkflags;
0228
0229 clkflags = CLK_SET_RATE_PARENT;
0230 return clk_register_fixed_factor(NULL, name, parent_name, clkflags,
0231 mul, div);
0232 }
0233
0234 static inline struct clk *mpc512x_clk_divider(
0235 const char *name, const char *parent_name, u8 clkflags,
0236 u32 __iomem *reg, u8 pos, u8 len, int divflags)
0237 {
0238 divflags |= CLK_DIVIDER_BIG_ENDIAN;
0239 return clk_register_divider(NULL, name, parent_name, clkflags,
0240 reg, pos, len, divflags, &clklock);
0241 }
0242
0243 static inline struct clk *mpc512x_clk_divtable(
0244 const char *name, const char *parent_name,
0245 u32 __iomem *reg, u8 pos, u8 len,
0246 const struct clk_div_table *divtab)
0247 {
0248 u8 divflags;
0249
0250 divflags = CLK_DIVIDER_BIG_ENDIAN;
0251 return clk_register_divider_table(NULL, name, parent_name, 0,
0252 reg, pos, len, divflags,
0253 divtab, &clklock);
0254 }
0255
0256 static inline struct clk *mpc512x_clk_gated(
0257 const char *name, const char *parent_name,
0258 u32 __iomem *reg, u8 pos)
0259 {
0260 int clkflags;
0261 u8 gateflags;
0262
0263 clkflags = CLK_SET_RATE_PARENT;
0264 gateflags = CLK_GATE_BIG_ENDIAN;
0265 return clk_register_gate(NULL, name, parent_name, clkflags,
0266 reg, pos, gateflags, &clklock);
0267 }
0268
0269 static inline struct clk *mpc512x_clk_muxed(const char *name,
0270 const char **parent_names, int parent_count,
0271 u32 __iomem *reg, u8 pos, u8 len)
0272 {
0273 int clkflags;
0274 u8 muxflags;
0275
0276 clkflags = CLK_SET_RATE_PARENT;
0277 muxflags = CLK_MUX_BIG_ENDIAN;
0278 return clk_register_mux(NULL, name,
0279 parent_names, parent_count, clkflags,
0280 reg, pos, len, muxflags, &clklock);
0281 }
0282
0283
0284
0285
0286 static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len)
0287 {
0288 uint32_t val;
0289
0290 val = in_be32(reg);
0291 val >>= pos;
0292 val &= (1 << len) - 1;
0293 return val;
0294 }
0295
0296
0297 static int __init get_spmf_mult(void)
0298 {
0299 static int spmf_to_mult[] = {
0300 68, 1, 12, 16, 20, 24, 28, 32,
0301 36, 40, 44, 48, 52, 56, 60, 64,
0302 };
0303 int spmf;
0304
0305 spmf = get_bit_field(&clkregs->spmr, 24, 4);
0306 return spmf_to_mult[spmf];
0307 }
0308
0309
0310
0311
0312
0313
0314
0315 static int __init get_sys_div_x2(void)
0316 {
0317 static int sysdiv_code_to_x2[] = {
0318 4, 5, 6, 7, 8, 9, 10, 14,
0319 12, 16, 18, 22, 20, 24, 26, 30,
0320 28, 32, 34, 38, 36, 40, 42, 46,
0321 44, 48, 50, 54, 52, 56, 58, 62,
0322 60, 64, 66,
0323 };
0324 int divcode;
0325
0326 divcode = get_bit_field(&clkregs->scfr2, 26, 6);
0327 return sysdiv_code_to_x2[divcode];
0328 }
0329
0330
0331
0332
0333
0334
0335
0336 static int __init get_cpmf_mult_x2(void)
0337 {
0338 static int cpmf_to_mult_x36[] = {
0339
0340 72, 2, 2, 3, 4, 5, 6, 7,
0341 };
0342 static int cpmf_to_mult_0by[] = {
0343
0344 2, 2, 2, 3, 4, 5, 6, 7,
0345 };
0346
0347 int *cpmf_to_mult;
0348 int cpmf;
0349
0350 cpmf = get_bit_field(&clkregs->spmr, 16, 4);
0351 if (soc_has_cpmf_0_bypass())
0352 cpmf_to_mult = cpmf_to_mult_0by;
0353 else
0354 cpmf_to_mult = cpmf_to_mult_x36;
0355 return cpmf_to_mult[cpmf];
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365 static const struct clk_div_table divtab_2346[] = {
0366 { .val = 2, .div = 2, },
0367 { .val = 3, .div = 3, },
0368 { .val = 4, .div = 4, },
0369 { .val = 6, .div = 6, },
0370 { .div = 0, },
0371 };
0372
0373
0374 static const struct clk_div_table divtab_1234[] = {
0375 { .val = 1, .div = 1, },
0376 { .val = 2, .div = 2, },
0377 { .val = 3, .div = 3, },
0378 { .val = 4, .div = 4, },
0379 { .div = 0, },
0380 };
0381
0382 static int __init get_freq_from_dt(char *propname)
0383 {
0384 struct device_node *np;
0385 const unsigned int *prop;
0386 int val;
0387
0388 val = 0;
0389 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
0390 if (np) {
0391 prop = of_get_property(np, propname, NULL);
0392 if (prop)
0393 val = *prop;
0394 of_node_put(np);
0395 }
0396 return val;
0397 }
0398
0399 static void __init mpc512x_clk_preset_data(void)
0400 {
0401 size_t i;
0402
0403 for (i = 0; i < ARRAY_SIZE(clks); i++)
0404 clks[i] = ERR_PTR(-ENODEV);
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 static void __init mpc512x_clk_setup_ref_clock(struct device_node *np, int bus_freq,
0422 int *sys_mul, int *sys_div,
0423 int *ips_div)
0424 {
0425 struct clk *osc_clk;
0426 int calc_freq;
0427
0428
0429 *sys_mul = get_spmf_mult();
0430 *sys_mul *= 2;
0431 *sys_div = get_sys_div_x2();
0432 *ips_div = get_bit_field(&clkregs->scfr1, 23, 3);
0433
0434
0435 osc_clk = of_clk_get_by_name(np, "osc");
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445 if (!IS_ERR(osc_clk)) {
0446 clks[MPC512x_CLK_REF] = mpc512x_clk_factor("ref", "osc", 1, 1);
0447 calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]);
0448 calc_freq *= *sys_mul;
0449 calc_freq /= *sys_div;
0450 calc_freq /= 2;
0451 calc_freq /= *ips_div;
0452 if (bus_freq && calc_freq != bus_freq)
0453 pr_warn("calc rate %d != OF spec %d\n",
0454 calc_freq, bus_freq);
0455 } else {
0456 calc_freq = bus_freq;
0457 calc_freq *= *ips_div;
0458 calc_freq *= 2;
0459 calc_freq *= *sys_div;
0460 calc_freq /= *sys_mul;
0461 clks[MPC512x_CLK_REF] = mpc512x_clk_fixed("ref", calc_freq);
0462 }
0463 }
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500 static const char *parent_names_mux0_spdif[] = {
0501 "sys", "ref", "psc-mclk-in", "spdif-tx",
0502 };
0503
0504 static const char *parent_names_mux0_canin[] = {
0505 "sys", "ref", "psc-mclk-in", "can-clk-in",
0506 };
0507
0508 enum mclk_type {
0509 MCLK_TYPE_PSC,
0510 MCLK_TYPE_MSCAN,
0511 MCLK_TYPE_SPDIF,
0512 MCLK_TYPE_OUTCLK,
0513 };
0514
0515 struct mclk_setup_data {
0516 enum mclk_type type;
0517 bool has_mclk1;
0518 const char *name_mux0;
0519 const char *name_en0;
0520 const char *name_div0;
0521 const char *parent_names_mux1[2];
0522 const char *name_mclk;
0523 };
0524
0525 #define MCLK_SETUP_DATA_PSC(id) { \
0526 MCLK_TYPE_PSC, 0, \
0527 "psc" #id "-mux0", \
0528 "psc" #id "-en0", \
0529 "psc" #id "_mclk_div", \
0530 { "psc" #id "_mclk_div", "dummy", }, \
0531 "psc" #id "_mclk", \
0532 }
0533
0534 #define MCLK_SETUP_DATA_MSCAN(id) { \
0535 MCLK_TYPE_MSCAN, 0, \
0536 "mscan" #id "-mux0", \
0537 "mscan" #id "-en0", \
0538 "mscan" #id "_mclk_div", \
0539 { "mscan" #id "_mclk_div", "dummy", }, \
0540 "mscan" #id "_mclk", \
0541 }
0542
0543 #define MCLK_SETUP_DATA_SPDIF { \
0544 MCLK_TYPE_SPDIF, 1, \
0545 "spdif-mux0", \
0546 "spdif-en0", \
0547 "spdif_mclk_div", \
0548 { "spdif_mclk_div", "spdif-rx", }, \
0549 "spdif_mclk", \
0550 }
0551
0552 #define MCLK_SETUP_DATA_OUTCLK(id) { \
0553 MCLK_TYPE_OUTCLK, 0, \
0554 "out" #id "-mux0", \
0555 "out" #id "-en0", \
0556 "out" #id "_mclk_div", \
0557 { "out" #id "_mclk_div", "dummy", }, \
0558 "out" #id "_clk", \
0559 }
0560
0561 static struct mclk_setup_data mclk_psc_data[] = {
0562 MCLK_SETUP_DATA_PSC(0),
0563 MCLK_SETUP_DATA_PSC(1),
0564 MCLK_SETUP_DATA_PSC(2),
0565 MCLK_SETUP_DATA_PSC(3),
0566 MCLK_SETUP_DATA_PSC(4),
0567 MCLK_SETUP_DATA_PSC(5),
0568 MCLK_SETUP_DATA_PSC(6),
0569 MCLK_SETUP_DATA_PSC(7),
0570 MCLK_SETUP_DATA_PSC(8),
0571 MCLK_SETUP_DATA_PSC(9),
0572 MCLK_SETUP_DATA_PSC(10),
0573 MCLK_SETUP_DATA_PSC(11),
0574 };
0575
0576 static struct mclk_setup_data mclk_mscan_data[] = {
0577 MCLK_SETUP_DATA_MSCAN(0),
0578 MCLK_SETUP_DATA_MSCAN(1),
0579 MCLK_SETUP_DATA_MSCAN(2),
0580 MCLK_SETUP_DATA_MSCAN(3),
0581 };
0582
0583 static struct mclk_setup_data mclk_spdif_data[] = {
0584 MCLK_SETUP_DATA_SPDIF,
0585 };
0586
0587 static struct mclk_setup_data mclk_outclk_data[] = {
0588 MCLK_SETUP_DATA_OUTCLK(0),
0589 MCLK_SETUP_DATA_OUTCLK(1),
0590 MCLK_SETUP_DATA_OUTCLK(2),
0591 MCLK_SETUP_DATA_OUTCLK(3),
0592 };
0593
0594
0595 static void __init mpc512x_clk_setup_mclk(struct mclk_setup_data *entry, size_t idx)
0596 {
0597 size_t clks_idx_pub, clks_idx_int;
0598 u32 __iomem *mccr_reg;
0599 int div;
0600
0601
0602 switch (entry->type) {
0603 case MCLK_TYPE_PSC:
0604 clks_idx_pub = MPC512x_CLK_PSC0_MCLK + idx;
0605 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
0606 + (idx) * MCLK_MAX_IDX;
0607 mccr_reg = &clkregs->psc_ccr[idx];
0608 break;
0609 case MCLK_TYPE_MSCAN:
0610 clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + idx;
0611 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
0612 + (NR_PSCS + idx) * MCLK_MAX_IDX;
0613 mccr_reg = &clkregs->mscan_ccr[idx];
0614 break;
0615 case MCLK_TYPE_SPDIF:
0616 clks_idx_pub = MPC512x_CLK_SPDIF_MCLK;
0617 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
0618 + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX;
0619 mccr_reg = &clkregs->spccr;
0620 break;
0621 case MCLK_TYPE_OUTCLK:
0622 clks_idx_pub = MPC512x_CLK_OUT0_CLK + idx;
0623 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
0624 + (NR_PSCS + NR_MSCANS + NR_SPDIFS + idx)
0625 * MCLK_MAX_IDX;
0626 mccr_reg = &clkregs->out_ccr[idx];
0627 break;
0628 default:
0629 return;
0630 }
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650 div = clk_get_rate(clks[MPC512x_CLK_SYS]);
0651 div /= clk_get_rate(clks[MPC512x_CLK_IPS]);
0652 out_be32(mccr_reg, (0 << 16));
0653 out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17));
0654 out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17));
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674 clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed(
0675 entry->name_mux0,
0676 soc_has_mclk_mux0_canin()
0677 ? &parent_names_mux0_canin[0]
0678 : &parent_names_mux0_spdif[0],
0679 ARRAY_SIZE(parent_names_mux0_spdif),
0680 mccr_reg, 14, 2);
0681 clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated(
0682 entry->name_en0, entry->name_mux0,
0683 mccr_reg, 16);
0684 clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider(
0685 entry->name_div0,
0686 entry->name_en0, CLK_SET_RATE_GATE,
0687 mccr_reg, 17, 15, 0);
0688 if (entry->has_mclk1) {
0689 clks[clks_idx_pub] = mpc512x_clk_muxed(
0690 entry->name_mclk,
0691 &entry->parent_names_mux1[0],
0692 ARRAY_SIZE(entry->parent_names_mux1),
0693 mccr_reg, 7, 1);
0694 } else {
0695 clks[clks_idx_pub] = mpc512x_clk_factor(
0696 entry->name_mclk,
0697 entry->parent_names_mux1[0],
0698 1, 1);
0699 }
0700 }
0701
0702
0703
0704 static void __init mpc512x_clk_setup_clock_tree(struct device_node *np, int busfreq)
0705 {
0706 int sys_mul, sys_div, ips_div;
0707 int mul, div;
0708 size_t mclk_idx;
0709 int freq;
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732 mpc512x_clk_setup_ref_clock(np, busfreq, &sys_mul, &sys_div, &ips_div);
0733
0734
0735 clks[MPC512x_CLK_SYS] = mpc512x_clk_factor("sys", "ref",
0736 sys_mul, sys_div);
0737 clks[MPC512x_CLK_CSB] = mpc512x_clk_factor("csb", "sys", 1, 2);
0738 clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable("ips", "csb",
0739 &clkregs->scfr1, 23, 3,
0740 divtab_2346);
0741
0742
0743 clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor("ddr-ug", "sys", 1, 2);
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756 clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor("sdhc-x4", "csb", 2, 1);
0757 clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider("sdhc-ug", "sdhc-x4", 0,
0758 &clkregs->scfr2, 1, 7,
0759 CLK_DIVIDER_ONE_BASED);
0760 if (soc_has_sdhc2()) {
0761 clks[MPC512x_CLK_SDHC2_UG] = mpc512x_clk_divider(
0762 "sdhc2-ug", "sdhc-x4", 0, &clkregs->scfr2,
0763 9, 7, CLK_DIVIDER_ONE_BASED);
0764 }
0765
0766 clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor("diu-x4", "csb", 4, 1);
0767 clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider("diu-ug", "diu-x4", 0,
0768 &clkregs->scfr1, 0, 8,
0769 CLK_DIVIDER_ONE_BASED);
0770
0771
0772
0773
0774
0775
0776
0777
0778 mul = get_cpmf_mult_x2();
0779 div = 2;
0780 clks[MPC512x_CLK_E300] = mpc512x_clk_factor("e300", "csb", mul, div);
0781
0782 if (soc_has_mbx()) {
0783 clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor(
0784 "mbx-bus-ug", "csb", 1, 2);
0785 clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable(
0786 "mbx-ug", "mbx-bus-ug", &clkregs->scfr1,
0787 14, 3, divtab_1234);
0788 clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor(
0789 "mbx-3d-ug", "mbx-ug", 1, 1);
0790 }
0791 if (soc_has_pci()) {
0792 clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable(
0793 "pci-ug", "csb", &clkregs->scfr1,
0794 20, 3, divtab_2346);
0795 }
0796 if (soc_has_nfc_5125()) {
0797
0798
0799
0800
0801
0802 clks[MPC512x_CLK_NFC_UG] = ERR_PTR(-ENOTSUPP);
0803 } else {
0804 clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable(
0805 "nfc-ug", "ips", &clkregs->scfr1,
0806 8, 3, divtab_1234);
0807 }
0808 clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable("lpc-ug", "ips",
0809 &clkregs->scfr1, 11, 3,
0810 divtab_1234);
0811
0812 clks[MPC512x_CLK_LPC] = mpc512x_clk_gated("lpc", "lpc-ug",
0813 &clkregs->sccr1, 30);
0814 clks[MPC512x_CLK_NFC] = mpc512x_clk_gated("nfc", "nfc-ug",
0815 &clkregs->sccr1, 29);
0816 if (soc_has_pata()) {
0817 clks[MPC512x_CLK_PATA] = mpc512x_clk_gated(
0818 "pata", "ips", &clkregs->sccr1, 28);
0819 }
0820
0821 for (mclk_idx = 0; mclk_idx < soc_max_pscnum(); mclk_idx++) {
0822 char name[12];
0823 snprintf(name, sizeof(name), "psc%d", mclk_idx);
0824 clks[MPC512x_CLK_PSC0 + mclk_idx] = mpc512x_clk_gated(
0825 name, "ips", &clkregs->sccr1, 27 - mclk_idx);
0826 mpc512x_clk_setup_mclk(&mclk_psc_data[mclk_idx], mclk_idx);
0827 }
0828 clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated("psc-fifo", "ips",
0829 &clkregs->sccr1, 15);
0830 if (soc_has_sata()) {
0831 clks[MPC512x_CLK_SATA] = mpc512x_clk_gated(
0832 "sata", "ips", &clkregs->sccr1, 14);
0833 }
0834 clks[MPC512x_CLK_FEC] = mpc512x_clk_gated("fec", "ips",
0835 &clkregs->sccr1, 13);
0836 if (soc_has_pci()) {
0837 clks[MPC512x_CLK_PCI] = mpc512x_clk_gated(
0838 "pci", "pci-ug", &clkregs->sccr1, 11);
0839 }
0840 clks[MPC512x_CLK_DDR] = mpc512x_clk_gated("ddr", "ddr-ug",
0841 &clkregs->sccr1, 10);
0842 if (soc_has_fec2()) {
0843 clks[MPC512x_CLK_FEC2] = mpc512x_clk_gated(
0844 "fec2", "ips", &clkregs->sccr1, 9);
0845 }
0846
0847 clks[MPC512x_CLK_DIU] = mpc512x_clk_gated("diu", "diu-ug",
0848 &clkregs->sccr2, 31);
0849 if (soc_has_axe()) {
0850 clks[MPC512x_CLK_AXE] = mpc512x_clk_gated(
0851 "axe", "csb", &clkregs->sccr2, 30);
0852 }
0853 clks[MPC512x_CLK_MEM] = mpc512x_clk_gated("mem", "ips",
0854 &clkregs->sccr2, 29);
0855 clks[MPC512x_CLK_USB1] = mpc512x_clk_gated("usb1", "csb",
0856 &clkregs->sccr2, 28);
0857 clks[MPC512x_CLK_USB2] = mpc512x_clk_gated("usb2", "csb",
0858 &clkregs->sccr2, 27);
0859 clks[MPC512x_CLK_I2C] = mpc512x_clk_gated("i2c", "ips",
0860 &clkregs->sccr2, 26);
0861
0862 clks[MPC512x_CLK_BDLC] = mpc512x_clk_gated("bdlc", "ips",
0863 &clkregs->sccr2, 25);
0864 for (mclk_idx = 0; mclk_idx < ARRAY_SIZE(mclk_mscan_data); mclk_idx++)
0865 mpc512x_clk_setup_mclk(&mclk_mscan_data[mclk_idx], mclk_idx);
0866 clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated("sdhc", "sdhc-ug",
0867 &clkregs->sccr2, 24);
0868
0869 if (soc_has_spdif()) {
0870 clks[MPC512x_CLK_SPDIF] = mpc512x_clk_gated(
0871 "spdif", "ips", &clkregs->sccr2, 23);
0872 mpc512x_clk_setup_mclk(&mclk_spdif_data[0], 0);
0873 }
0874 if (soc_has_mbx()) {
0875 clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated(
0876 "mbx-bus", "mbx-bus-ug", &clkregs->sccr2, 22);
0877 clks[MPC512x_CLK_MBX] = mpc512x_clk_gated(
0878 "mbx", "mbx-ug", &clkregs->sccr2, 21);
0879 clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated(
0880 "mbx-3d", "mbx-3d-ug", &clkregs->sccr2, 20);
0881 }
0882 clks[MPC512x_CLK_IIM] = mpc512x_clk_gated("iim", "csb",
0883 &clkregs->sccr2, 19);
0884 if (soc_has_viu()) {
0885 clks[MPC512x_CLK_VIU] = mpc512x_clk_gated(
0886 "viu", "csb", &clkregs->sccr2, 18);
0887 }
0888 if (soc_has_sdhc2()) {
0889 clks[MPC512x_CLK_SDHC2] = mpc512x_clk_gated(
0890 "sdhc-2", "sdhc2-ug", &clkregs->sccr2, 17);
0891 }
0892
0893 if (soc_has_outclk()) {
0894 size_t idx;
0895 for (idx = 0; idx < ARRAY_SIZE(mclk_outclk_data); idx++)
0896 mpc512x_clk_setup_mclk(&mclk_outclk_data[idx], idx);
0897 }
0898
0899
0900
0901
0902
0903 freq = get_freq_from_dt("psc_mclk_in");
0904 if (!freq)
0905 freq = 25000000;
0906 clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed("psc_mclk_in", freq);
0907 if (soc_has_mclk_mux0_canin()) {
0908 freq = get_freq_from_dt("can_clk_in");
0909 clks[MPC512x_CLK_CAN_CLK_IN] = mpc512x_clk_fixed(
0910 "can_clk_in", freq);
0911 } else {
0912 freq = get_freq_from_dt("spdif_tx_in");
0913 clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(
0914 "spdif_tx_in", freq);
0915 freq = get_freq_from_dt("spdif_rx_in");
0916 clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(
0917 "spdif_rx_in", freq);
0918 }
0919
0920
0921 clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed("ac97", 24567000);
0922
0923
0924
0925
0926
0927
0928 clk_prepare_enable(clks[MPC512x_CLK_DUMMY]);
0929 clk_prepare_enable(clks[MPC512x_CLK_E300]);
0930 clk_prepare_enable(clks[MPC512x_CLK_DDR]);
0931 clk_prepare_enable(clks[MPC512x_CLK_MEM]);
0932 clk_prepare_enable(clks[MPC512x_CLK_IPS]);
0933 clk_prepare_enable(clks[MPC512x_CLK_LPC]);
0934 }
0935
0936
0937
0938
0939
0940 static void __init mpc5121_clk_register_of_provider(struct device_node *np)
0941 {
0942 clk_data.clks = clks;
0943 clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1;
0944 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
0945 }
0946
0947
0948
0949
0950
0951 static void __init mpc5121_clk_provide_migration_support(void)
0952 {
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972 clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);
0973 if (of_find_compatible_node(NULL, "pci", "fsl,mpc5121-pci"))
0974 clk_prepare_enable(clks[MPC512x_CLK_PCI]);
0975 }
0976
0977
0978
0979
0980
0981
0982 #define FOR_NODES(compatname) \
0983 for_each_compatible_node(np, NULL, compatname)
0984
0985 #define NODE_PREP do { \
0986 of_address_to_resource(np, 0, &res); \
0987 snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \
0988 } while (0)
0989
0990 #define NODE_CHK(clkname, clkitem, regnode, regflag) do { \
0991 struct clk *clk; \
0992 clk = of_clk_get_by_name(np, clkname); \
0993 if (IS_ERR(clk)) { \
0994 clk = clkitem; \
0995 clk_register_clkdev(clk, clkname, devname); \
0996 if (regnode) \
0997 clk_register_clkdev(clk, clkname, np->name); \
0998 did_register |= DID_REG_ ## regflag; \
0999 pr_debug("clock alias name '%s' for dev '%s' pointer %p\n", \
1000 clkname, devname, clk); \
1001 } else { \
1002 clk_put(clk); \
1003 } \
1004 } while (0)
1005
1006
1007
1008
1009
1010
1011
1012 static void __init mpc5121_clk_provide_backwards_compat(void)
1013 {
1014 enum did_reg_flags {
1015 DID_REG_PSC = BIT(0),
1016 DID_REG_PSCFIFO = BIT(1),
1017 DID_REG_NFC = BIT(2),
1018 DID_REG_CAN = BIT(3),
1019 DID_REG_I2C = BIT(4),
1020 DID_REG_DIU = BIT(5),
1021 DID_REG_VIU = BIT(6),
1022 DID_REG_FEC = BIT(7),
1023 DID_REG_USB = BIT(8),
1024 DID_REG_PATA = BIT(9),
1025 };
1026
1027 int did_register;
1028 struct device_node *np;
1029 struct resource res;
1030 int idx;
1031 char devname[32];
1032
1033 did_register = 0;
1034
1035 FOR_NODES(mpc512x_select_psc_compat()) {
1036 NODE_PREP;
1037 idx = (res.start >> 8) & 0xf;
1038 NODE_CHK("ipg", clks[MPC512x_CLK_PSC0 + idx], 0, PSC);
1039 NODE_CHK("mclk", clks[MPC512x_CLK_PSC0_MCLK + idx], 0, PSC);
1040 }
1041
1042 FOR_NODES("fsl,mpc5121-psc-fifo") {
1043 NODE_PREP;
1044 NODE_CHK("ipg", clks[MPC512x_CLK_PSC_FIFO], 1, PSCFIFO);
1045 }
1046
1047 FOR_NODES("fsl,mpc5121-nfc") {
1048 NODE_PREP;
1049 NODE_CHK("ipg", clks[MPC512x_CLK_NFC], 0, NFC);
1050 }
1051
1052 FOR_NODES("fsl,mpc5121-mscan") {
1053 NODE_PREP;
1054 idx = 0;
1055 idx += (res.start & 0x2000) ? 2 : 0;
1056 idx += (res.start & 0x0080) ? 1 : 0;
1057 NODE_CHK("ipg", clks[MPC512x_CLK_BDLC], 0, CAN);
1058 NODE_CHK("mclk", clks[MPC512x_CLK_MSCAN0_MCLK + idx], 0, CAN);
1059 }
1060
1061
1062
1063
1064
1065
1066 if (did_register & DID_REG_CAN) {
1067 clk_register_clkdev(clks[MPC512x_CLK_IPS], "ips", NULL);
1068 clk_register_clkdev(clks[MPC512x_CLK_SYS], "sys", NULL);
1069 clk_register_clkdev(clks[MPC512x_CLK_REF], "ref", NULL);
1070 }
1071
1072 FOR_NODES("fsl,mpc5121-i2c") {
1073 NODE_PREP;
1074 NODE_CHK("ipg", clks[MPC512x_CLK_I2C], 0, I2C);
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 if (did_register & DID_REG_I2C)
1093 clk_prepare_enable(clks[MPC512x_CLK_I2C]);
1094
1095 FOR_NODES("fsl,mpc5121-diu") {
1096 NODE_PREP;
1097 NODE_CHK("ipg", clks[MPC512x_CLK_DIU], 1, DIU);
1098 }
1099
1100 FOR_NODES("fsl,mpc5121-viu") {
1101 NODE_PREP;
1102 NODE_CHK("ipg", clks[MPC512x_CLK_VIU], 0, VIU);
1103 }
1104
1105
1106
1107
1108
1109
1110
1111
1112 FOR_NODES("fsl,mpc5121-fec") {
1113 NODE_PREP;
1114 NODE_CHK("per", clks[MPC512x_CLK_FEC], 0, FEC);
1115 }
1116 FOR_NODES("fsl,mpc5121-fec-mdio") {
1117 NODE_PREP;
1118 NODE_CHK("per", clks[MPC512x_CLK_FEC], 0, FEC);
1119 }
1120
1121
1122
1123
1124
1125
1126 FOR_NODES("fsl,mpc5125-fec") {
1127 NODE_PREP;
1128 if (res.start & 0x4000)
1129 idx = MPC512x_CLK_FEC2;
1130 else
1131 idx = MPC512x_CLK_FEC;
1132 NODE_CHK("per", clks[idx], 0, FEC);
1133 }
1134
1135 FOR_NODES("fsl,mpc5121-usb2-dr") {
1136 NODE_PREP;
1137 idx = (res.start & 0x4000) ? 1 : 0;
1138 NODE_CHK("ipg", clks[MPC512x_CLK_USB1 + idx], 0, USB);
1139 }
1140
1141 FOR_NODES("fsl,mpc5121-pata") {
1142 NODE_PREP;
1143 NODE_CHK("ipg", clks[MPC512x_CLK_PATA], 0, PATA);
1144 }
1145
1146
1147
1148
1149
1150
1151
1152
1153 if (did_register) {
1154 pr_notice("device tree lacks clock specs, adding fallbacks (0x%x,%s%s%s%s%s%s%s%s%s%s)\n",
1155 did_register,
1156 (did_register & DID_REG_PSC) ? " PSC" : "",
1157 (did_register & DID_REG_PSCFIFO) ? " PSCFIFO" : "",
1158 (did_register & DID_REG_NFC) ? " NFC" : "",
1159 (did_register & DID_REG_CAN) ? " CAN" : "",
1160 (did_register & DID_REG_I2C) ? " I2C" : "",
1161 (did_register & DID_REG_DIU) ? " DIU" : "",
1162 (did_register & DID_REG_VIU) ? " VIU" : "",
1163 (did_register & DID_REG_FEC) ? " FEC" : "",
1164 (did_register & DID_REG_USB) ? " USB" : "",
1165 (did_register & DID_REG_PATA) ? " PATA" : "");
1166 } else {
1167 pr_debug("device tree has clock specs, no fallbacks added\n");
1168 }
1169 }
1170
1171
1172
1173
1174
1175
1176 int __init mpc5121_clk_init(void)
1177 {
1178 struct device_node *clk_np;
1179 int busfreq;
1180
1181
1182 clk_np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
1183 if (!clk_np)
1184 return -ENODEV;
1185 clkregs = of_iomap(clk_np, 0);
1186 WARN_ON(!clkregs);
1187
1188
1189 mpc512x_clk_determine_soc();
1190
1191
1192 mpc512x_clk_preset_data();
1193
1194
1195
1196
1197
1198 clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed("dummy", 0);
1199
1200
1201
1202
1203
1204
1205 busfreq = get_freq_from_dt("bus-frequency");
1206 mpc512x_clk_setup_clock_tree(clk_np, busfreq);
1207
1208
1209 mpc5121_clk_register_of_provider(clk_np);
1210
1211
1212
1213
1214
1215
1216 mpc5121_clk_provide_migration_support();
1217 mpc5121_clk_provide_backwards_compat();
1218
1219 return 0;
1220 }