0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk-provider.h>
0011 #include <linux/device.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/io.h>
0015 #include <linux/err.h>
0016 #include <linux/string.h>
0017 #include <linux/log2.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 static inline u32 clk_div_readl(struct clk_divider *divider)
0030 {
0031 if (divider->flags & CLK_DIVIDER_BIG_ENDIAN)
0032 return ioread32be(divider->reg);
0033
0034 return readl(divider->reg);
0035 }
0036
0037 static inline void clk_div_writel(struct clk_divider *divider, u32 val)
0038 {
0039 if (divider->flags & CLK_DIVIDER_BIG_ENDIAN)
0040 iowrite32be(val, divider->reg);
0041 else
0042 writel(val, divider->reg);
0043 }
0044
0045 static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
0046 u8 width)
0047 {
0048 unsigned int maxdiv = 0, mask = clk_div_mask(width);
0049 const struct clk_div_table *clkt;
0050
0051 for (clkt = table; clkt->div; clkt++)
0052 if (clkt->div > maxdiv && clkt->val <= mask)
0053 maxdiv = clkt->div;
0054 return maxdiv;
0055 }
0056
0057 static unsigned int _get_table_mindiv(const struct clk_div_table *table)
0058 {
0059 unsigned int mindiv = UINT_MAX;
0060 const struct clk_div_table *clkt;
0061
0062 for (clkt = table; clkt->div; clkt++)
0063 if (clkt->div < mindiv)
0064 mindiv = clkt->div;
0065 return mindiv;
0066 }
0067
0068 static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
0069 unsigned long flags)
0070 {
0071 if (flags & CLK_DIVIDER_ONE_BASED)
0072 return clk_div_mask(width);
0073 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0074 return 1 << clk_div_mask(width);
0075 if (table)
0076 return _get_table_maxdiv(table, width);
0077 return clk_div_mask(width) + 1;
0078 }
0079
0080 static unsigned int _get_table_div(const struct clk_div_table *table,
0081 unsigned int val)
0082 {
0083 const struct clk_div_table *clkt;
0084
0085 for (clkt = table; clkt->div; clkt++)
0086 if (clkt->val == val)
0087 return clkt->div;
0088 return 0;
0089 }
0090
0091 static unsigned int _get_div(const struct clk_div_table *table,
0092 unsigned int val, unsigned long flags, u8 width)
0093 {
0094 if (flags & CLK_DIVIDER_ONE_BASED)
0095 return val;
0096 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0097 return 1 << val;
0098 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
0099 return val ? val : clk_div_mask(width) + 1;
0100 if (table)
0101 return _get_table_div(table, val);
0102 return val + 1;
0103 }
0104
0105 static unsigned int _get_table_val(const struct clk_div_table *table,
0106 unsigned int div)
0107 {
0108 const struct clk_div_table *clkt;
0109
0110 for (clkt = table; clkt->div; clkt++)
0111 if (clkt->div == div)
0112 return clkt->val;
0113 return 0;
0114 }
0115
0116 static unsigned int _get_val(const struct clk_div_table *table,
0117 unsigned int div, unsigned long flags, u8 width)
0118 {
0119 if (flags & CLK_DIVIDER_ONE_BASED)
0120 return div;
0121 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0122 return __ffs(div);
0123 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
0124 return (div == clk_div_mask(width) + 1) ? 0 : div;
0125 if (table)
0126 return _get_table_val(table, div);
0127 return div - 1;
0128 }
0129
0130 unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
0131 unsigned int val,
0132 const struct clk_div_table *table,
0133 unsigned long flags, unsigned long width)
0134 {
0135 unsigned int div;
0136
0137 div = _get_div(table, val, flags, width);
0138 if (!div) {
0139 WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
0140 "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
0141 clk_hw_get_name(hw));
0142 return parent_rate;
0143 }
0144
0145 return DIV_ROUND_UP_ULL((u64)parent_rate, div);
0146 }
0147 EXPORT_SYMBOL_GPL(divider_recalc_rate);
0148
0149 static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
0150 unsigned long parent_rate)
0151 {
0152 struct clk_divider *divider = to_clk_divider(hw);
0153 unsigned int val;
0154
0155 val = clk_div_readl(divider) >> divider->shift;
0156 val &= clk_div_mask(divider->width);
0157
0158 return divider_recalc_rate(hw, parent_rate, val, divider->table,
0159 divider->flags, divider->width);
0160 }
0161
0162 static bool _is_valid_table_div(const struct clk_div_table *table,
0163 unsigned int div)
0164 {
0165 const struct clk_div_table *clkt;
0166
0167 for (clkt = table; clkt->div; clkt++)
0168 if (clkt->div == div)
0169 return true;
0170 return false;
0171 }
0172
0173 static bool _is_valid_div(const struct clk_div_table *table, unsigned int div,
0174 unsigned long flags)
0175 {
0176 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0177 return is_power_of_2(div);
0178 if (table)
0179 return _is_valid_table_div(table, div);
0180 return true;
0181 }
0182
0183 static int _round_up_table(const struct clk_div_table *table, int div)
0184 {
0185 const struct clk_div_table *clkt;
0186 int up = INT_MAX;
0187
0188 for (clkt = table; clkt->div; clkt++) {
0189 if (clkt->div == div)
0190 return clkt->div;
0191 else if (clkt->div < div)
0192 continue;
0193
0194 if ((clkt->div - div) < (up - div))
0195 up = clkt->div;
0196 }
0197
0198 return up;
0199 }
0200
0201 static int _round_down_table(const struct clk_div_table *table, int div)
0202 {
0203 const struct clk_div_table *clkt;
0204 int down = _get_table_mindiv(table);
0205
0206 for (clkt = table; clkt->div; clkt++) {
0207 if (clkt->div == div)
0208 return clkt->div;
0209 else if (clkt->div > div)
0210 continue;
0211
0212 if ((div - clkt->div) < (div - down))
0213 down = clkt->div;
0214 }
0215
0216 return down;
0217 }
0218
0219 static int _div_round_up(const struct clk_div_table *table,
0220 unsigned long parent_rate, unsigned long rate,
0221 unsigned long flags)
0222 {
0223 int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
0224
0225 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0226 div = __roundup_pow_of_two(div);
0227 if (table)
0228 div = _round_up_table(table, div);
0229
0230 return div;
0231 }
0232
0233 static int _div_round_closest(const struct clk_div_table *table,
0234 unsigned long parent_rate, unsigned long rate,
0235 unsigned long flags)
0236 {
0237 int up, down;
0238 unsigned long up_rate, down_rate;
0239
0240 up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
0241 down = parent_rate / rate;
0242
0243 if (flags & CLK_DIVIDER_POWER_OF_TWO) {
0244 up = __roundup_pow_of_two(up);
0245 down = __rounddown_pow_of_two(down);
0246 } else if (table) {
0247 up = _round_up_table(table, up);
0248 down = _round_down_table(table, down);
0249 }
0250
0251 up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
0252 down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
0253
0254 return (rate - up_rate) <= (down_rate - rate) ? up : down;
0255 }
0256
0257 static int _div_round(const struct clk_div_table *table,
0258 unsigned long parent_rate, unsigned long rate,
0259 unsigned long flags)
0260 {
0261 if (flags & CLK_DIVIDER_ROUND_CLOSEST)
0262 return _div_round_closest(table, parent_rate, rate, flags);
0263
0264 return _div_round_up(table, parent_rate, rate, flags);
0265 }
0266
0267 static bool _is_best_div(unsigned long rate, unsigned long now,
0268 unsigned long best, unsigned long flags)
0269 {
0270 if (flags & CLK_DIVIDER_ROUND_CLOSEST)
0271 return abs(rate - now) < abs(rate - best);
0272
0273 return now <= rate && now > best;
0274 }
0275
0276 static int _next_div(const struct clk_div_table *table, int div,
0277 unsigned long flags)
0278 {
0279 div++;
0280
0281 if (flags & CLK_DIVIDER_POWER_OF_TWO)
0282 return __roundup_pow_of_two(div);
0283 if (table)
0284 return _round_up_table(table, div);
0285
0286 return div;
0287 }
0288
0289 static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
0290 unsigned long rate,
0291 unsigned long *best_parent_rate,
0292 const struct clk_div_table *table, u8 width,
0293 unsigned long flags)
0294 {
0295 int i, bestdiv = 0;
0296 unsigned long parent_rate, best = 0, now, maxdiv;
0297 unsigned long parent_rate_saved = *best_parent_rate;
0298
0299 if (!rate)
0300 rate = 1;
0301
0302 maxdiv = _get_maxdiv(table, width, flags);
0303
0304 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
0305 parent_rate = *best_parent_rate;
0306 bestdiv = _div_round(table, parent_rate, rate, flags);
0307 bestdiv = bestdiv == 0 ? 1 : bestdiv;
0308 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
0309 return bestdiv;
0310 }
0311
0312
0313
0314
0315
0316 maxdiv = min(ULONG_MAX / rate, maxdiv);
0317
0318 for (i = _next_div(table, 0, flags); i <= maxdiv;
0319 i = _next_div(table, i, flags)) {
0320 if (rate * i == parent_rate_saved) {
0321
0322
0323
0324
0325
0326 *best_parent_rate = parent_rate_saved;
0327 return i;
0328 }
0329 parent_rate = clk_hw_round_rate(parent, rate * i);
0330 now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
0331 if (_is_best_div(rate, now, best, flags)) {
0332 bestdiv = i;
0333 best = now;
0334 *best_parent_rate = parent_rate;
0335 }
0336 }
0337
0338 if (!bestdiv) {
0339 bestdiv = _get_maxdiv(table, width, flags);
0340 *best_parent_rate = clk_hw_round_rate(parent, 1);
0341 }
0342
0343 return bestdiv;
0344 }
0345
0346 int divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req,
0347 const struct clk_div_table *table, u8 width,
0348 unsigned long flags)
0349 {
0350 int div;
0351
0352 div = clk_divider_bestdiv(hw, req->best_parent_hw, req->rate,
0353 &req->best_parent_rate, table, width, flags);
0354
0355 req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, div);
0356
0357 return 0;
0358 }
0359 EXPORT_SYMBOL_GPL(divider_determine_rate);
0360
0361 int divider_ro_determine_rate(struct clk_hw *hw, struct clk_rate_request *req,
0362 const struct clk_div_table *table, u8 width,
0363 unsigned long flags, unsigned int val)
0364 {
0365 int div;
0366
0367 div = _get_div(table, val, flags, width);
0368
0369
0370 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
0371 if (!req->best_parent_hw)
0372 return -EINVAL;
0373
0374 req->best_parent_rate = clk_hw_round_rate(req->best_parent_hw,
0375 req->rate * div);
0376 }
0377
0378 req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, div);
0379
0380 return 0;
0381 }
0382 EXPORT_SYMBOL_GPL(divider_ro_determine_rate);
0383
0384 long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
0385 unsigned long rate, unsigned long *prate,
0386 const struct clk_div_table *table,
0387 u8 width, unsigned long flags)
0388 {
0389 struct clk_rate_request req = {
0390 .rate = rate,
0391 .best_parent_rate = *prate,
0392 .best_parent_hw = parent,
0393 };
0394 int ret;
0395
0396 ret = divider_determine_rate(hw, &req, table, width, flags);
0397 if (ret)
0398 return ret;
0399
0400 *prate = req.best_parent_rate;
0401
0402 return req.rate;
0403 }
0404 EXPORT_SYMBOL_GPL(divider_round_rate_parent);
0405
0406 long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
0407 unsigned long rate, unsigned long *prate,
0408 const struct clk_div_table *table, u8 width,
0409 unsigned long flags, unsigned int val)
0410 {
0411 struct clk_rate_request req = {
0412 .rate = rate,
0413 .best_parent_rate = *prate,
0414 .best_parent_hw = parent,
0415 };
0416 int ret;
0417
0418 ret = divider_ro_determine_rate(hw, &req, table, width, flags, val);
0419 if (ret)
0420 return ret;
0421
0422 *prate = req.best_parent_rate;
0423
0424 return req.rate;
0425 }
0426 EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent);
0427
0428 static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
0429 unsigned long *prate)
0430 {
0431 struct clk_divider *divider = to_clk_divider(hw);
0432
0433
0434 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
0435 u32 val;
0436
0437 val = clk_div_readl(divider) >> divider->shift;
0438 val &= clk_div_mask(divider->width);
0439
0440 return divider_ro_round_rate(hw, rate, prate, divider->table,
0441 divider->width, divider->flags,
0442 val);
0443 }
0444
0445 return divider_round_rate(hw, rate, prate, divider->table,
0446 divider->width, divider->flags);
0447 }
0448
0449 static int clk_divider_determine_rate(struct clk_hw *hw,
0450 struct clk_rate_request *req)
0451 {
0452 struct clk_divider *divider = to_clk_divider(hw);
0453
0454
0455 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
0456 u32 val;
0457
0458 val = clk_div_readl(divider) >> divider->shift;
0459 val &= clk_div_mask(divider->width);
0460
0461 return divider_ro_determine_rate(hw, req, divider->table,
0462 divider->width,
0463 divider->flags, val);
0464 }
0465
0466 return divider_determine_rate(hw, req, divider->table, divider->width,
0467 divider->flags);
0468 }
0469
0470 int divider_get_val(unsigned long rate, unsigned long parent_rate,
0471 const struct clk_div_table *table, u8 width,
0472 unsigned long flags)
0473 {
0474 unsigned int div, value;
0475
0476 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
0477
0478 if (!_is_valid_div(table, div, flags))
0479 return -EINVAL;
0480
0481 value = _get_val(table, div, flags, width);
0482
0483 return min_t(unsigned int, value, clk_div_mask(width));
0484 }
0485 EXPORT_SYMBOL_GPL(divider_get_val);
0486
0487 static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
0488 unsigned long parent_rate)
0489 {
0490 struct clk_divider *divider = to_clk_divider(hw);
0491 int value;
0492 unsigned long flags = 0;
0493 u32 val;
0494
0495 value = divider_get_val(rate, parent_rate, divider->table,
0496 divider->width, divider->flags);
0497 if (value < 0)
0498 return value;
0499
0500 if (divider->lock)
0501 spin_lock_irqsave(divider->lock, flags);
0502 else
0503 __acquire(divider->lock);
0504
0505 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
0506 val = clk_div_mask(divider->width) << (divider->shift + 16);
0507 } else {
0508 val = clk_div_readl(divider);
0509 val &= ~(clk_div_mask(divider->width) << divider->shift);
0510 }
0511 val |= (u32)value << divider->shift;
0512 clk_div_writel(divider, val);
0513
0514 if (divider->lock)
0515 spin_unlock_irqrestore(divider->lock, flags);
0516 else
0517 __release(divider->lock);
0518
0519 return 0;
0520 }
0521
0522 const struct clk_ops clk_divider_ops = {
0523 .recalc_rate = clk_divider_recalc_rate,
0524 .round_rate = clk_divider_round_rate,
0525 .determine_rate = clk_divider_determine_rate,
0526 .set_rate = clk_divider_set_rate,
0527 };
0528 EXPORT_SYMBOL_GPL(clk_divider_ops);
0529
0530 const struct clk_ops clk_divider_ro_ops = {
0531 .recalc_rate = clk_divider_recalc_rate,
0532 .round_rate = clk_divider_round_rate,
0533 .determine_rate = clk_divider_determine_rate,
0534 };
0535 EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
0536
0537 struct clk_hw *__clk_hw_register_divider(struct device *dev,
0538 struct device_node *np, const char *name,
0539 const char *parent_name, const struct clk_hw *parent_hw,
0540 const struct clk_parent_data *parent_data, unsigned long flags,
0541 void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
0542 const struct clk_div_table *table, spinlock_t *lock)
0543 {
0544 struct clk_divider *div;
0545 struct clk_hw *hw;
0546 struct clk_init_data init = {};
0547 int ret;
0548
0549 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
0550 if (width + shift > 16) {
0551 pr_warn("divider value exceeds LOWORD field\n");
0552 return ERR_PTR(-EINVAL);
0553 }
0554 }
0555
0556
0557 div = kzalloc(sizeof(*div), GFP_KERNEL);
0558 if (!div)
0559 return ERR_PTR(-ENOMEM);
0560
0561 init.name = name;
0562 if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
0563 init.ops = &clk_divider_ro_ops;
0564 else
0565 init.ops = &clk_divider_ops;
0566 init.flags = flags;
0567 init.parent_names = parent_name ? &parent_name : NULL;
0568 init.parent_hws = parent_hw ? &parent_hw : NULL;
0569 init.parent_data = parent_data;
0570 if (parent_name || parent_hw || parent_data)
0571 init.num_parents = 1;
0572 else
0573 init.num_parents = 0;
0574
0575
0576 div->reg = reg;
0577 div->shift = shift;
0578 div->width = width;
0579 div->flags = clk_divider_flags;
0580 div->lock = lock;
0581 div->hw.init = &init;
0582 div->table = table;
0583
0584
0585 hw = &div->hw;
0586 ret = clk_hw_register(dev, hw);
0587 if (ret) {
0588 kfree(div);
0589 hw = ERR_PTR(ret);
0590 }
0591
0592 return hw;
0593 }
0594 EXPORT_SYMBOL_GPL(__clk_hw_register_divider);
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610 struct clk *clk_register_divider_table(struct device *dev, const char *name,
0611 const char *parent_name, unsigned long flags,
0612 void __iomem *reg, u8 shift, u8 width,
0613 u8 clk_divider_flags, const struct clk_div_table *table,
0614 spinlock_t *lock)
0615 {
0616 struct clk_hw *hw;
0617
0618 hw = __clk_hw_register_divider(dev, NULL, name, parent_name, NULL,
0619 NULL, flags, reg, shift, width, clk_divider_flags,
0620 table, lock);
0621 if (IS_ERR(hw))
0622 return ERR_CAST(hw);
0623 return hw->clk;
0624 }
0625 EXPORT_SYMBOL_GPL(clk_register_divider_table);
0626
0627 void clk_unregister_divider(struct clk *clk)
0628 {
0629 struct clk_divider *div;
0630 struct clk_hw *hw;
0631
0632 hw = __clk_get_hw(clk);
0633 if (!hw)
0634 return;
0635
0636 div = to_clk_divider(hw);
0637
0638 clk_unregister(clk);
0639 kfree(div);
0640 }
0641 EXPORT_SYMBOL_GPL(clk_unregister_divider);
0642
0643
0644
0645
0646
0647 void clk_hw_unregister_divider(struct clk_hw *hw)
0648 {
0649 struct clk_divider *div;
0650
0651 div = to_clk_divider(hw);
0652
0653 clk_hw_unregister(hw);
0654 kfree(div);
0655 }
0656 EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);
0657
0658 static void devm_clk_hw_release_divider(struct device *dev, void *res)
0659 {
0660 clk_hw_unregister_divider(*(struct clk_hw **)res);
0661 }
0662
0663 struct clk_hw *__devm_clk_hw_register_divider(struct device *dev,
0664 struct device_node *np, const char *name,
0665 const char *parent_name, const struct clk_hw *parent_hw,
0666 const struct clk_parent_data *parent_data, unsigned long flags,
0667 void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
0668 const struct clk_div_table *table, spinlock_t *lock)
0669 {
0670 struct clk_hw **ptr, *hw;
0671
0672 ptr = devres_alloc(devm_clk_hw_release_divider, sizeof(*ptr), GFP_KERNEL);
0673 if (!ptr)
0674 return ERR_PTR(-ENOMEM);
0675
0676 hw = __clk_hw_register_divider(dev, np, name, parent_name, parent_hw,
0677 parent_data, flags, reg, shift, width,
0678 clk_divider_flags, table, lock);
0679
0680 if (!IS_ERR(hw)) {
0681 *ptr = hw;
0682 devres_add(dev, ptr);
0683 } else {
0684 devres_free(ptr);
0685 }
0686
0687 return hw;
0688 }
0689 EXPORT_SYMBOL_GPL(__devm_clk_hw_register_divider);