1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 4 * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> 5 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> 6 * 7 * Adjustable divider clock implementation 8 */ 9 10#include <linux/clk-provider.h> 11#include <linux/module.h> 12#include <linux/slab.h> 13#include <linux/io.h> 14#include <linux/err.h> 15#include <linux/string.h> 16#include <linux/log2.h> 17 18/* 19 * DOC: basic adjustable divider clock that cannot gate 20 * 21 * Traits of this clock: 22 * prepare - clk_prepare only ensures that parents are prepared 23 * enable - clk_enable only ensures that parents are enabled 24 * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor) 25 * parent - fixed parent. No clk_set_parent support 26 */ 27 28static inline u32 clk_div_readl(struct clk_divider *divider) 29{ 30 if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) 31 return ioread32be(divider->reg); 32 33 return readl(divider->reg); 34} 35 36static inline void clk_div_writel(struct clk_divider *divider, u32 val) 37{ 38 if (divider->flags & CLK_DIVIDER_BIG_ENDIAN) 39 iowrite32be(val, divider->reg); 40 else 41 writel(val, divider->reg); 42} 43 44static unsigned int _get_table_maxdiv(const struct clk_div_table *table, 45 u8 width) 46{ 47 unsigned int maxdiv = 0, mask = clk_div_mask(width); 48 const struct clk_div_table *clkt; 49 50 for (clkt = table; clkt->div; clkt++) 51 if (clkt->div > maxdiv && clkt->val <= mask) 52 maxdiv = clkt->div; 53 return maxdiv; 54} 55 56static unsigned int _get_table_mindiv(const struct clk_div_table *table) 57{ 58 unsigned int mindiv = UINT_MAX; 59 const struct clk_div_table *clkt; 60 61 for (clkt = table; clkt->div; clkt++) 62 if (clkt->div < mindiv) 63 mindiv = clkt->div; 64 return mindiv; 65} 66 67static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width, 68 unsigned long flags) 69{ 70 if (flags & CLK_DIVIDER_ONE_BASED) 71 return clk_div_mask(width); 72 if (flags & CLK_DIVIDER_POWER_OF_TWO) 73 return 1 << clk_div_mask(width); 74 if (table) 75 return _get_table_maxdiv(table, width); 76 return clk_div_mask(width) + 1; 77} 78 79static unsigned int _get_table_div(const struct clk_div_table *table, 80 unsigned int val) 81{ 82 const struct clk_div_table *clkt; 83 84 for (clkt = table; clkt->div; clkt++) 85 if (clkt->val == val) 86 return clkt->div; 87 return 0; 88} 89 90static unsigned int _get_div(const struct clk_div_table *table, 91 unsigned int val, unsigned long flags, u8 width) 92{ 93 if (flags & CLK_DIVIDER_ONE_BASED) 94 return val; 95 if (flags & CLK_DIVIDER_POWER_OF_TWO) 96 return 1 << val; 97 if (flags & CLK_DIVIDER_MAX_AT_ZERO) 98 return val ? val : clk_div_mask(width) + 1; 99 if (table) 100 return _get_table_div(table, val); 101 return val + 1; 102} 103 104static unsigned int _get_table_val(const struct clk_div_table *table, 105 unsigned int div) 106{ 107 const struct clk_div_table *clkt; 108 109 for (clkt = table; clkt->div; clkt++) 110 if (clkt->div == div) 111 return clkt->val; 112 return 0; 113} 114 115static unsigned int _get_val(const struct clk_div_table *table, 116 unsigned int div, unsigned long flags, u8 width) 117{ 118 if (flags & CLK_DIVIDER_ONE_BASED) 119 return div; 120 if (flags & CLK_DIVIDER_POWER_OF_TWO) 121 return __ffs(div); 122 if (flags & CLK_DIVIDER_MAX_AT_ZERO) 123 return (div == clk_div_mask(width) + 1) ? 0 : div; 124 if (table) 125 return _get_table_val(table, div); 126 return div - 1; 127} 128 129unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, 130 unsigned int val, 131 const struct clk_div_table *table, 132 unsigned long flags, unsigned long width) 133{ 134 unsigned int div; 135 136 div = _get_div(table, val, flags, width); 137 if (!div) { 138 WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO), 139 "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", 140 clk_hw_get_name(hw)); 141 return parent_rate; 142 } 143 144 return DIV_ROUND_UP_ULL((u64)parent_rate, div); 145} 146EXPORT_SYMBOL_GPL(divider_recalc_rate); 147 148static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, 149 unsigned long parent_rate) 150{ 151 struct clk_divider *divider = to_clk_divider(hw); 152 unsigned int val; 153 154 val = clk_div_readl(divider) >> divider->shift; 155 val &= clk_div_mask(divider->width); 156 157 return divider_recalc_rate(hw, parent_rate, val, divider->table, 158 divider->flags, divider->width); 159} 160 161static bool _is_valid_table_div(const struct clk_div_table *table, 162 unsigned int div) 163{ 164 const struct clk_div_table *clkt; 165 166 for (clkt = table; clkt->div; clkt++) 167 if (clkt->div == div) 168 return true; 169 return false; 170} 171 172static bool _is_valid_div(const struct clk_div_table *table, unsigned int div, 173 unsigned long flags) 174{ 175 if (flags & CLK_DIVIDER_POWER_OF_TWO) 176 return is_power_of_2(div); 177 if (table) 178 return _is_valid_table_div(table, div); 179 return true; 180} 181 182static int _round_up_table(const struct clk_div_table *table, int div) 183{ 184 const struct clk_div_table *clkt; 185 int up = INT_MAX; 186 187 for (clkt = table; clkt->div; clkt++) { 188 if (clkt->div == div) 189 return clkt->div; 190 else if (clkt->div < div) 191 continue; 192 193 if ((clkt->div - div) < (up - div)) 194 up = clkt->div; 195 } 196 197 return up; 198} 199 200static int _round_down_table(const struct clk_div_table *table, int div) 201{ 202 const struct clk_div_table *clkt; 203 int down = _get_table_mindiv(table); 204 205 for (clkt = table; clkt->div; clkt++) { 206 if (clkt->div == div) 207 return clkt->div; 208 else if (clkt->div > div) 209 continue; 210 211 if ((div - clkt->div) < (div - down)) 212 down = clkt->div; 213 } 214 215 return down; 216} 217 218static int _div_round_up(const struct clk_div_table *table, 219 unsigned long parent_rate, unsigned long rate, 220 unsigned long flags) 221{ 222 int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); 223 224 if (flags & CLK_DIVIDER_POWER_OF_TWO) 225 div = __roundup_pow_of_two(div); 226 if (table) 227 div = _round_up_table(table, div); 228 229 return div; 230} 231 232static int _div_round_closest(const struct clk_div_table *table, 233 unsigned long parent_rate, unsigned long rate, 234 unsigned long flags) 235{ 236 int up, down; 237 unsigned long up_rate, down_rate; 238 239 up = DIV_ROUND_UP_ULL((u64)parent_rate, rate); 240 down = parent_rate / rate; 241 242 if (flags & CLK_DIVIDER_POWER_OF_TWO) { 243 up = __roundup_pow_of_two(up); 244 down = __rounddown_pow_of_two(down); 245 } else if (table) { 246 up = _round_up_table(table, up); 247 down = _round_down_table(table, down); 248 } 249 250 up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up); 251 down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down); 252 253 return (rate - up_rate) <= (down_rate - rate) ? up : down; 254} 255 256static int _div_round(const struct clk_div_table *table, 257 unsigned long parent_rate, unsigned long rate, 258 unsigned long flags) 259{ 260 if (flags & CLK_DIVIDER_ROUND_CLOSEST) 261 return _div_round_closest(table, parent_rate, rate, flags); 262 263 return _div_round_up(table, parent_rate, rate, flags); 264} 265 266static bool _is_best_div(unsigned long rate, unsigned long now, 267 unsigned long best, unsigned long flags) 268{ 269 if (flags & CLK_DIVIDER_ROUND_CLOSEST) 270 return abs(rate - now) < abs(rate - best); 271 272 return now <= rate && now > best; 273} 274 275static int _next_div(const struct clk_div_table *table, int div, 276 unsigned long flags) 277{ 278 div++; 279 280 if (flags & CLK_DIVIDER_POWER_OF_TWO) 281 return __roundup_pow_of_two(div); 282 if (table) 283 return _round_up_table(table, div); 284 285 return div; 286} 287 288static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent, 289 unsigned long rate, 290 unsigned long *best_parent_rate, 291 const struct clk_div_table *table, u8 width, 292 unsigned long flags) 293{ 294 int i, bestdiv = 0; 295 unsigned long parent_rate, best = 0, now, maxdiv; 296 unsigned long parent_rate_saved = *best_parent_rate; 297 298 if (!rate) 299 rate = 1; 300 301 maxdiv = _get_maxdiv(table, width, flags); 302 303 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { 304 parent_rate = *best_parent_rate; 305 bestdiv = _div_round(table, parent_rate, rate, flags); 306 bestdiv = bestdiv == 0 ? 1 : bestdiv; 307 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; 308 return bestdiv; 309 } 310 311 /* 312 * The maximum divider we can use without overflowing 313 * unsigned long in rate * i below 314 */ 315 maxdiv = min(ULONG_MAX / rate, maxdiv); 316 317 for (i = _next_div(table, 0, flags); i <= maxdiv; 318 i = _next_div(table, i, flags)) { 319 if (rate * i == parent_rate_saved) { 320 /* 321 * It's the most ideal case if the requested rate can be 322 * divided from parent clock without needing to change 323 * parent rate, so return the divider immediately. 324 */ 325 *best_parent_rate = parent_rate_saved; 326 return i; 327 } 328 parent_rate = clk_hw_round_rate(parent, rate * i); 329 now = DIV_ROUND_UP_ULL((u64)parent_rate, i); 330 if (_is_best_div(rate, now, best, flags)) { 331 bestdiv = i; 332 best = now; 333 *best_parent_rate = parent_rate; 334 } 335 } 336 337 if (!bestdiv) { 338 bestdiv = _get_maxdiv(table, width, flags); 339 *best_parent_rate = clk_hw_round_rate(parent, 1); 340 } 341 342 return bestdiv; 343} 344 345long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, 346 unsigned long rate, unsigned long *prate, 347 const struct clk_div_table *table, 348 u8 width, unsigned long flags) 349{ 350 int div; 351 352 div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags); 353 354 return DIV_ROUND_UP_ULL((u64)*prate, div); 355} 356EXPORT_SYMBOL_GPL(divider_round_rate_parent); 357 358long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, 359 unsigned long rate, unsigned long *prate, 360 const struct clk_div_table *table, u8 width, 361 unsigned long flags, unsigned int val) 362{ 363 int div; 364 365 div = _get_div(table, val, flags, width); 366 367 /* Even a read-only clock can propagate a rate change */ 368 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { 369 if (!parent) 370 return -EINVAL; 371 372 *prate = clk_hw_round_rate(parent, rate * div); 373 } 374 375 return DIV_ROUND_UP_ULL((u64)*prate, div); 376} 377EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent); 378 379 380static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, 381 unsigned long *prate) 382{ 383 struct clk_divider *divider = to_clk_divider(hw); 384 385 /* if read only, just return current value */ 386 if (divider->flags & CLK_DIVIDER_READ_ONLY) { 387 u32 val; 388 389 val = clk_div_readl(divider) >> divider->shift; 390 val &= clk_div_mask(divider->width); 391 392 return divider_ro_round_rate(hw, rate, prate, divider->table, 393 divider->width, divider->flags, 394 val); 395 } 396 397 return divider_round_rate(hw, rate, prate, divider->table, 398 divider->width, divider->flags); 399} 400 401int divider_get_val(unsigned long rate, unsigned long parent_rate, 402 const struct clk_div_table *table, u8 width, 403 unsigned long flags) 404{ 405 unsigned int div, value; 406 407 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); 408 409 if (!_is_valid_div(table, div, flags)) 410 return -EINVAL; 411 412 value = _get_val(table, div, flags, width); 413 414 return min_t(unsigned int, value, clk_div_mask(width)); 415} 416EXPORT_SYMBOL_GPL(divider_get_val); 417 418static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, 419 unsigned long parent_rate) 420{ 421 struct clk_divider *divider = to_clk_divider(hw); 422 int value; 423 unsigned long flags = 0; 424 u32 val; 425 426 value = divider_get_val(rate, parent_rate, divider->table, 427 divider->width, divider->flags); 428 if (value < 0) 429 return value; 430 431 if (divider->lock) 432 spin_lock_irqsave(divider->lock, flags); 433 else 434 __acquire(divider->lock); 435 436 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { 437 val = clk_div_mask(divider->width) << (divider->shift + 16); 438 } else { 439 val = clk_div_readl(divider); 440 val &= ~(clk_div_mask(divider->width) << divider->shift); 441 } 442 val |= (u32)value << divider->shift; 443 clk_div_writel(divider, val); 444 445 if (divider->lock) 446 spin_unlock_irqrestore(divider->lock, flags); 447 else 448 __release(divider->lock); 449 450 return 0; 451} 452 453const struct clk_ops clk_divider_ops = { 454 .recalc_rate = clk_divider_recalc_rate, 455 .round_rate = clk_divider_round_rate, 456 .set_rate = clk_divider_set_rate, 457}; 458EXPORT_SYMBOL_GPL(clk_divider_ops); 459 460const struct clk_ops clk_divider_ro_ops = { 461 .recalc_rate = clk_divider_recalc_rate, 462 .round_rate = clk_divider_round_rate, 463}; 464EXPORT_SYMBOL_GPL(clk_divider_ro_ops); 465 466struct clk_hw *__clk_hw_register_divider(struct device *dev, 467 struct device_node *np, const char *name, 468 const char *parent_name, const struct clk_hw *parent_hw, 469 const struct clk_parent_data *parent_data, unsigned long flags, 470 void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, 471 const struct clk_div_table *table, spinlock_t *lock) 472{ 473 struct clk_divider *div; 474 struct clk_hw *hw; 475 struct clk_init_data init = {}; 476 int ret; 477 478 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { 479 if (width + shift > 16) { 480 pr_warn("divider value exceeds LOWORD field\n"); 481 return ERR_PTR(-EINVAL); 482 } 483 } 484 485 /* allocate the divider */ 486 div = kzalloc(sizeof(*div), GFP_KERNEL); 487 if (!div) 488 return ERR_PTR(-ENOMEM); 489 490 init.name = name; 491 if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) 492 init.ops = &clk_divider_ro_ops; 493 else 494 init.ops = &clk_divider_ops; 495 init.flags = flags; 496 init.parent_names = parent_name ? &parent_name : NULL; 497 init.parent_hws = parent_hw ? &parent_hw : NULL; 498 init.parent_data = parent_data; 499 if (parent_name || parent_hw || parent_data) 500 init.num_parents = 1; 501 else 502 init.num_parents = 0; 503 504 /* struct clk_divider assignments */ 505 div->reg = reg; 506 div->shift = shift; 507 div->width = width; 508 div->flags = clk_divider_flags; 509 div->lock = lock; 510 div->hw.init = &init; 511 div->table = table; 512 513 /* register the clock */ 514 hw = &div->hw; 515 ret = clk_hw_register(dev, hw); 516 if (ret) { 517 kfree(div); 518 hw = ERR_PTR(ret); 519 } 520 521 return hw; 522} 523EXPORT_SYMBOL_GPL(__clk_hw_register_divider); 524 525/** 526 * clk_register_divider_table - register a table based divider clock with 527 * the clock framework 528 * @dev: device registering this clock 529 * @name: name of this clock 530 * @parent_name: name of clock's parent 531 * @flags: framework-specific flags 532 * @reg: register address to adjust divider 533 * @shift: number of bits to shift the bitfield 534 * @width: width of the bitfield 535 * @clk_divider_flags: divider-specific flags for this clock 536 * @table: array of divider/value pairs ending with a div set to 0 537 * @lock: shared register lock for this clock 538 */ 539struct clk *clk_register_divider_table(struct device *dev, const char *name, 540 const char *parent_name, unsigned long flags, 541 void __iomem *reg, u8 shift, u8 width, 542 u8 clk_divider_flags, const struct clk_div_table *table, 543 spinlock_t *lock) 544{ 545 struct clk_hw *hw; 546 547 hw = __clk_hw_register_divider(dev, NULL, name, parent_name, NULL, 548 NULL, flags, reg, shift, width, clk_divider_flags, 549 table, lock); 550 if (IS_ERR(hw)) 551 return ERR_CAST(hw); 552 return hw->clk; 553} 554EXPORT_SYMBOL_GPL(clk_register_divider_table); 555 556void clk_unregister_divider(struct clk *clk) 557{ 558 struct clk_divider *div; 559 struct clk_hw *hw; 560 561 hw = __clk_get_hw(clk); 562 if (!hw) 563 return; 564 565 div = to_clk_divider(hw); 566 567 clk_unregister(clk); 568 kfree(div); 569} 570EXPORT_SYMBOL_GPL(clk_unregister_divider); 571 572/** 573 * clk_hw_unregister_divider - unregister a clk divider 574 * @hw: hardware-specific clock data to unregister 575 */ 576void clk_hw_unregister_divider(struct clk_hw *hw) 577{ 578 struct clk_divider *div; 579 580 div = to_clk_divider(hw); 581 582 clk_hw_unregister(hw); 583 kfree(div); 584} 585EXPORT_SYMBOL_GPL(clk_hw_unregister_divider); 586