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