0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/clk-provider.h>
0012 #include <linux/clkdev.h>
0013 #include <linux/clk/ti.h>
0014 #include <linux/io.h>
0015 #include <linux/of.h>
0016 #include <linux/of_address.h>
0017 #include <linux/list.h>
0018 #include <linux/regmap.h>
0019 #include <linux/memblock.h>
0020 #include <linux/device.h>
0021
0022 #include "clock.h"
0023
0024 #undef pr_fmt
0025 #define pr_fmt(fmt) "%s: " fmt, __func__
0026
0027 static LIST_HEAD(clk_hw_omap_clocks);
0028 struct ti_clk_ll_ops *ti_clk_ll_ops;
0029 static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
0030
0031 struct ti_clk_features ti_clk_features;
0032
0033 struct clk_iomap {
0034 struct regmap *regmap;
0035 void __iomem *mem;
0036 };
0037
0038 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
0039
0040 static void clk_memmap_writel(u32 val, const struct clk_omap_reg *reg)
0041 {
0042 struct clk_iomap *io = clk_memmaps[reg->index];
0043
0044 if (reg->ptr)
0045 writel_relaxed(val, reg->ptr);
0046 else if (io->regmap)
0047 regmap_write(io->regmap, reg->offset, val);
0048 else
0049 writel_relaxed(val, io->mem + reg->offset);
0050 }
0051
0052 static void _clk_rmw(u32 val, u32 mask, void __iomem *ptr)
0053 {
0054 u32 v;
0055
0056 v = readl_relaxed(ptr);
0057 v &= ~mask;
0058 v |= val;
0059 writel_relaxed(v, ptr);
0060 }
0061
0062 static void clk_memmap_rmw(u32 val, u32 mask, const struct clk_omap_reg *reg)
0063 {
0064 struct clk_iomap *io = clk_memmaps[reg->index];
0065
0066 if (reg->ptr) {
0067 _clk_rmw(val, mask, reg->ptr);
0068 } else if (io->regmap) {
0069 regmap_update_bits(io->regmap, reg->offset, mask, val);
0070 } else {
0071 _clk_rmw(val, mask, io->mem + reg->offset);
0072 }
0073 }
0074
0075 static u32 clk_memmap_readl(const struct clk_omap_reg *reg)
0076 {
0077 u32 val;
0078 struct clk_iomap *io = clk_memmaps[reg->index];
0079
0080 if (reg->ptr)
0081 val = readl_relaxed(reg->ptr);
0082 else if (io->regmap)
0083 regmap_read(io->regmap, reg->offset, &val);
0084 else
0085 val = readl_relaxed(io->mem + reg->offset);
0086
0087 return val;
0088 }
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
0100 {
0101 if (ti_clk_ll_ops) {
0102 pr_err("Attempt to register ll_ops multiple times.\n");
0103 return -EBUSY;
0104 }
0105
0106 ti_clk_ll_ops = ops;
0107 ops->clk_readl = clk_memmap_readl;
0108 ops->clk_writel = clk_memmap_writel;
0109 ops->clk_rmw = clk_memmap_rmw;
0110
0111 return 0;
0112 }
0113
0114
0115
0116
0117
0118 static struct device_node *ti_find_clock_provider(struct device_node *from,
0119 const char *name)
0120 {
0121 struct device_node *np;
0122 bool found = false;
0123 const char *n;
0124 char *tmp;
0125
0126 tmp = kstrdup(name, GFP_KERNEL);
0127 if (!tmp)
0128 return NULL;
0129 strreplace(tmp, '-', '_');
0130
0131
0132 for_each_of_allnodes_from(from, np) {
0133 if (of_property_read_string_index(np, "clock-output-names",
0134 0, &n))
0135 continue;
0136
0137 if (!strncmp(n, tmp, strlen(tmp))) {
0138 of_node_get(np);
0139 found = true;
0140 break;
0141 }
0142 }
0143 of_node_put(from);
0144 kfree(tmp);
0145
0146 if (found)
0147 return np;
0148
0149
0150 return of_find_node_by_name(from, name);
0151 }
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
0164 {
0165 struct ti_dt_clk *c;
0166 struct device_node *node, *parent, *child;
0167 struct clk *clk;
0168 struct of_phandle_args clkspec;
0169 char buf[64];
0170 char *ptr;
0171 char *tags[2];
0172 int i;
0173 int num_args;
0174 int ret;
0175 static bool clkctrl_nodes_missing;
0176 static bool has_clkctrl_data;
0177 static bool compat_mode;
0178
0179 compat_mode = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT;
0180
0181 for (c = oclks; c->node_name != NULL; c++) {
0182 strcpy(buf, c->node_name);
0183 ptr = buf;
0184 for (i = 0; i < 2; i++)
0185 tags[i] = NULL;
0186 num_args = 0;
0187 while (*ptr) {
0188 if (*ptr == ':') {
0189 if (num_args >= 2) {
0190 pr_warn("Bad number of tags on %s\n",
0191 c->node_name);
0192 return;
0193 }
0194 tags[num_args++] = ptr + 1;
0195 *ptr = 0;
0196 }
0197 ptr++;
0198 }
0199
0200 if (num_args && clkctrl_nodes_missing)
0201 continue;
0202
0203 node = ti_find_clock_provider(NULL, buf);
0204 if (num_args && compat_mode) {
0205 parent = node;
0206 child = of_get_child_by_name(parent, "clock");
0207 if (!child)
0208 child = of_get_child_by_name(parent, "clk");
0209 if (child) {
0210 of_node_put(parent);
0211 node = child;
0212 }
0213 }
0214
0215 clkspec.np = node;
0216 clkspec.args_count = num_args;
0217 for (i = 0; i < num_args; i++) {
0218 ret = kstrtoint(tags[i], i ? 10 : 16, clkspec.args + i);
0219 if (ret) {
0220 pr_warn("Bad tag in %s at %d: %s\n",
0221 c->node_name, i, tags[i]);
0222 of_node_put(node);
0223 return;
0224 }
0225 }
0226 clk = of_clk_get_from_provider(&clkspec);
0227 of_node_put(node);
0228 if (!IS_ERR(clk)) {
0229 c->lk.clk = clk;
0230 clkdev_add(&c->lk);
0231 } else {
0232 if (num_args && !has_clkctrl_data) {
0233 struct device_node *np;
0234
0235 np = of_find_compatible_node(NULL, NULL,
0236 "ti,clkctrl");
0237 if (np) {
0238 has_clkctrl_data = true;
0239 of_node_put(np);
0240 } else {
0241 clkctrl_nodes_missing = true;
0242
0243 pr_warn("missing clkctrl nodes, please update your dts.\n");
0244 continue;
0245 }
0246 }
0247
0248 pr_warn("failed to lookup clock node %s, ret=%ld\n",
0249 c->node_name, PTR_ERR(clk));
0250 }
0251 }
0252 }
0253
0254 struct clk_init_item {
0255 struct device_node *node;
0256 void *user;
0257 ti_of_clk_init_cb_t func;
0258 struct list_head link;
0259 };
0260
0261 static LIST_HEAD(retry_list);
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 int __init ti_clk_retry_init(struct device_node *node, void *user,
0273 ti_of_clk_init_cb_t func)
0274 {
0275 struct clk_init_item *retry;
0276
0277 pr_debug("%pOFn: adding to retry list...\n", node);
0278 retry = kzalloc(sizeof(*retry), GFP_KERNEL);
0279 if (!retry)
0280 return -ENOMEM;
0281
0282 retry->node = node;
0283 retry->func = func;
0284 retry->user = user;
0285 list_add(&retry->link, &retry_list);
0286
0287 return 0;
0288 }
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 int ti_clk_get_reg_addr(struct device_node *node, int index,
0301 struct clk_omap_reg *reg)
0302 {
0303 u32 val;
0304 int i;
0305
0306 for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
0307 if (clocks_node_ptr[i] == node->parent)
0308 break;
0309 if (clocks_node_ptr[i] == node->parent->parent)
0310 break;
0311 }
0312
0313 if (i == CLK_MAX_MEMMAPS) {
0314 pr_err("clk-provider not found for %pOFn!\n", node);
0315 return -ENOENT;
0316 }
0317
0318 reg->index = i;
0319
0320 if (of_property_read_u32_index(node, "reg", index, &val)) {
0321 if (of_property_read_u32_index(node->parent, "reg",
0322 index, &val)) {
0323 pr_err("%pOFn or parent must have reg[%d]!\n",
0324 node, index);
0325 return -EINVAL;
0326 }
0327 }
0328
0329 reg->offset = val;
0330 reg->ptr = NULL;
0331
0332 return 0;
0333 }
0334
0335 void ti_clk_latch(struct clk_omap_reg *reg, s8 shift)
0336 {
0337 u32 latch;
0338
0339 if (shift < 0)
0340 return;
0341
0342 latch = 1 << shift;
0343
0344 ti_clk_ll_ops->clk_rmw(latch, latch, reg);
0345 ti_clk_ll_ops->clk_rmw(0, latch, reg);
0346 ti_clk_ll_ops->clk_readl(reg);
0347 }
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363 int __init omap2_clk_provider_init(struct device_node *parent, int index,
0364 struct regmap *syscon, void __iomem *mem)
0365 {
0366 struct device_node *clocks;
0367 struct clk_iomap *io;
0368
0369
0370 clocks = of_get_child_by_name(parent, "clocks");
0371 if (!clocks) {
0372 pr_err("%pOFn missing 'clocks' child node.\n", parent);
0373 return -EINVAL;
0374 }
0375
0376
0377 clocks_node_ptr[index] = clocks;
0378
0379 io = kzalloc(sizeof(*io), GFP_KERNEL);
0380 if (!io)
0381 return -ENOMEM;
0382
0383 io->regmap = syscon;
0384 io->mem = mem;
0385
0386 clk_memmaps[index] = io;
0387
0388 return 0;
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398 void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
0399 {
0400 struct clk_iomap *io;
0401
0402 io = memblock_alloc(sizeof(*io), SMP_CACHE_BYTES);
0403 if (!io)
0404 panic("%s: Failed to allocate %zu bytes\n", __func__,
0405 sizeof(*io));
0406
0407 io->mem = mem;
0408
0409 clk_memmaps[index] = io;
0410 }
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 void ti_dt_clk_init_retry_clks(void)
0421 {
0422 struct clk_init_item *retry;
0423 struct clk_init_item *tmp;
0424 int retries = 5;
0425
0426 while (!list_empty(&retry_list) && retries) {
0427 list_for_each_entry_safe(retry, tmp, &retry_list, link) {
0428 pr_debug("retry-init: %pOFn\n", retry->node);
0429 retry->func(retry->user, retry->node);
0430 list_del(&retry->link);
0431 kfree(retry);
0432 }
0433 retries--;
0434 }
0435 }
0436
0437 static const struct of_device_id simple_clk_match_table[] __initconst = {
0438 { .compatible = "fixed-clock" },
0439 { .compatible = "fixed-factor-clock" },
0440 { }
0441 };
0442
0443
0444
0445
0446
0447
0448
0449
0450 const char *ti_dt_clk_name(struct device_node *np)
0451 {
0452 const char *name;
0453
0454 if (!of_property_read_string_index(np, "clock-output-names", 0,
0455 &name))
0456 return name;
0457
0458 return np->name;
0459 }
0460
0461
0462
0463
0464
0465
0466 void __init ti_clk_add_aliases(void)
0467 {
0468 struct device_node *np;
0469 struct clk *clk;
0470
0471 for_each_matching_node(np, simple_clk_match_table) {
0472 struct of_phandle_args clkspec;
0473
0474 clkspec.np = np;
0475 clk = of_clk_get_from_provider(&clkspec);
0476
0477 ti_clk_add_alias(NULL, clk, ti_dt_clk_name(np));
0478 }
0479 }
0480
0481
0482
0483
0484
0485
0486
0487
0488 void __init ti_clk_setup_features(struct ti_clk_features *features)
0489 {
0490 memcpy(&ti_clk_features, features, sizeof(*features));
0491 }
0492
0493
0494
0495
0496
0497
0498
0499 const struct ti_clk_features *ti_clk_get_features(void)
0500 {
0501 return &ti_clk_features;
0502 }
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514 void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
0515 {
0516 struct clk *init_clk;
0517 int i;
0518
0519 for (i = 0; i < num_clocks; i++) {
0520 init_clk = clk_get(NULL, clk_names[i]);
0521 if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
0522 clk_names[i]))
0523 continue;
0524 clk_prepare_enable(init_clk);
0525 }
0526 }
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538 int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
0539 {
0540 struct clk_lookup *cl;
0541
0542 if (!clk)
0543 return 0;
0544
0545 if (IS_ERR(clk))
0546 return PTR_ERR(clk);
0547
0548 cl = kzalloc(sizeof(*cl), GFP_KERNEL);
0549 if (!cl)
0550 return -ENOMEM;
0551
0552 if (dev)
0553 cl->dev_id = dev_name(dev);
0554 cl->con_id = con;
0555 cl->clk = clk;
0556
0557 clkdev_add(cl);
0558
0559 return 0;
0560 }
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
0573 const char *con)
0574 {
0575 struct clk *clk;
0576 int ret;
0577
0578 clk = clk_register(dev, hw);
0579 if (IS_ERR(clk))
0580 return clk;
0581
0582 ret = ti_clk_add_alias(dev, clk, con);
0583 if (ret) {
0584 clk_unregister(clk);
0585 return ERR_PTR(ret);
0586 }
0587
0588 return clk;
0589 }
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602 struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
0603 const char *con)
0604 {
0605 struct clk *clk;
0606 struct clk_hw_omap *oclk;
0607
0608 clk = ti_clk_register(dev, hw, con);
0609 if (IS_ERR(clk))
0610 return clk;
0611
0612 oclk = to_clk_hw_omap(hw);
0613
0614 list_add(&oclk->node, &clk_hw_omap_clocks);
0615
0616 return clk;
0617 }
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629 int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw))
0630 {
0631 int ret;
0632 struct clk_hw_omap *hw;
0633
0634 list_for_each_entry(hw, &clk_hw_omap_clocks, node) {
0635 ret = (*fn)(hw);
0636 if (ret)
0637 break;
0638 }
0639
0640 return ret;
0641 }
0642
0643
0644
0645
0646
0647
0648
0649
0650 bool omap2_clk_is_hw_omap(struct clk_hw *hw)
0651 {
0652 struct clk_hw_omap *oclk;
0653
0654 list_for_each_entry(oclk, &clk_hw_omap_clocks, node) {
0655 if (&oclk->hw == hw)
0656 return true;
0657 }
0658
0659 return false;
0660 }