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