linux/drivers/clk/ti/divider.c
<<
>>
Prefs
   1/*
   2 * TI Divider Clock
   3 *
   4 * Copyright (C) 2013 Texas Instruments, Inc.
   5 *
   6 * Tero Kristo <t-kristo@ti.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13 * kind, whether express or implied; without even the implied warranty
  14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <linux/clk-provider.h>
  19#include <linux/slab.h>
  20#include <linux/err.h>
  21#include <linux/of.h>
  22#include <linux/of_address.h>
  23#include <linux/clk/ti.h>
  24#include "clock.h"
  25
  26#undef pr_fmt
  27#define pr_fmt(fmt) "%s: " fmt, __func__
  28
  29#define div_mask(d)     ((1 << ((d)->width)) - 1)
  30
  31static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
  32{
  33        unsigned int maxdiv = 0;
  34        const struct clk_div_table *clkt;
  35
  36        for (clkt = table; clkt->div; clkt++)
  37                if (clkt->div > maxdiv)
  38                        maxdiv = clkt->div;
  39        return maxdiv;
  40}
  41
  42static unsigned int _get_maxdiv(struct clk_divider *divider)
  43{
  44        if (divider->flags & CLK_DIVIDER_ONE_BASED)
  45                return div_mask(divider);
  46        if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
  47                return 1 << div_mask(divider);
  48        if (divider->table)
  49                return _get_table_maxdiv(divider->table);
  50        return div_mask(divider) + 1;
  51}
  52
  53static unsigned int _get_table_div(const struct clk_div_table *table,
  54                                   unsigned int val)
  55{
  56        const struct clk_div_table *clkt;
  57
  58        for (clkt = table; clkt->div; clkt++)
  59                if (clkt->val == val)
  60                        return clkt->div;
  61        return 0;
  62}
  63
  64static unsigned int _get_div(struct clk_divider *divider, unsigned int val)
  65{
  66        if (divider->flags & CLK_DIVIDER_ONE_BASED)
  67                return val;
  68        if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
  69                return 1 << val;
  70        if (divider->table)
  71                return _get_table_div(divider->table, val);
  72        return val + 1;
  73}
  74
  75static unsigned int _get_table_val(const struct clk_div_table *table,
  76                                   unsigned int div)
  77{
  78        const struct clk_div_table *clkt;
  79
  80        for (clkt = table; clkt->div; clkt++)
  81                if (clkt->div == div)
  82                        return clkt->val;
  83        return 0;
  84}
  85
  86static unsigned int _get_val(struct clk_divider *divider, u8 div)
  87{
  88        if (divider->flags & CLK_DIVIDER_ONE_BASED)
  89                return div;
  90        if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
  91                return __ffs(div);
  92        if (divider->table)
  93                return  _get_table_val(divider->table, div);
  94        return div - 1;
  95}
  96
  97static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
  98                                                unsigned long parent_rate)
  99{
 100        struct clk_divider *divider = to_clk_divider(hw);
 101        unsigned int div, val;
 102
 103        val = ti_clk_ll_ops->clk_readl(divider->reg) >> divider->shift;
 104        val &= div_mask(divider);
 105
 106        div = _get_div(divider, val);
 107        if (!div) {
 108                WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
 109                     "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
 110                     clk_hw_get_name(hw));
 111                return parent_rate;
 112        }
 113
 114        return DIV_ROUND_UP(parent_rate, div);
 115}
 116
 117/*
 118 * The reverse of DIV_ROUND_UP: The maximum number which
 119 * divided by m is r
 120 */
 121#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
 122
 123static bool _is_valid_table_div(const struct clk_div_table *table,
 124                                unsigned int div)
 125{
 126        const struct clk_div_table *clkt;
 127
 128        for (clkt = table; clkt->div; clkt++)
 129                if (clkt->div == div)
 130                        return true;
 131        return false;
 132}
 133
 134static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
 135{
 136        if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
 137                return is_power_of_2(div);
 138        if (divider->table)
 139                return _is_valid_table_div(divider->table, div);
 140        return true;
 141}
 142
 143static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 144                                  unsigned long *best_parent_rate)
 145{
 146        struct clk_divider *divider = to_clk_divider(hw);
 147        int i, bestdiv = 0;
 148        unsigned long parent_rate, best = 0, now, maxdiv;
 149        unsigned long parent_rate_saved = *best_parent_rate;
 150
 151        if (!rate)
 152                rate = 1;
 153
 154        maxdiv = _get_maxdiv(divider);
 155
 156        if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
 157                parent_rate = *best_parent_rate;
 158                bestdiv = DIV_ROUND_UP(parent_rate, rate);
 159                bestdiv = bestdiv == 0 ? 1 : bestdiv;
 160                bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
 161                return bestdiv;
 162        }
 163
 164        /*
 165         * The maximum divider we can use without overflowing
 166         * unsigned long in rate * i below
 167         */
 168        maxdiv = min(ULONG_MAX / rate, maxdiv);
 169
 170        for (i = 1; i <= maxdiv; i++) {
 171                if (!_is_valid_div(divider, i))
 172                        continue;
 173                if (rate * i == parent_rate_saved) {
 174                        /*
 175                         * It's the most ideal case if the requested rate can be
 176                         * divided from parent clock without needing to change
 177                         * parent rate, so return the divider immediately.
 178                         */
 179                        *best_parent_rate = parent_rate_saved;
 180                        return i;
 181                }
 182                parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
 183                                MULT_ROUND_UP(rate, i));
 184                now = DIV_ROUND_UP(parent_rate, i);
 185                if (now <= rate && now > best) {
 186                        bestdiv = i;
 187                        best = now;
 188                        *best_parent_rate = parent_rate;
 189                }
 190        }
 191
 192        if (!bestdiv) {
 193                bestdiv = _get_maxdiv(divider);
 194                *best_parent_rate =
 195                        clk_hw_round_rate(clk_hw_get_parent(hw), 1);
 196        }
 197
 198        return bestdiv;
 199}
 200
 201static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
 202                                      unsigned long *prate)
 203{
 204        int div;
 205        div = ti_clk_divider_bestdiv(hw, rate, prate);
 206
 207        return DIV_ROUND_UP(*prate, div);
 208}
 209
 210static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 211                                   unsigned long parent_rate)
 212{
 213        struct clk_divider *divider;
 214        unsigned int div, value;
 215        u32 val;
 216
 217        if (!hw || !rate)
 218                return -EINVAL;
 219
 220        divider = to_clk_divider(hw);
 221
 222        div = DIV_ROUND_UP(parent_rate, rate);
 223        value = _get_val(divider, div);
 224
 225        if (value > div_mask(divider))
 226                value = div_mask(divider);
 227
 228        if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
 229                val = div_mask(divider) << (divider->shift + 16);
 230        } else {
 231                val = ti_clk_ll_ops->clk_readl(divider->reg);
 232                val &= ~(div_mask(divider) << divider->shift);
 233        }
 234        val |= value << divider->shift;
 235        ti_clk_ll_ops->clk_writel(val, divider->reg);
 236
 237        return 0;
 238}
 239
 240const struct clk_ops ti_clk_divider_ops = {
 241        .recalc_rate = ti_clk_divider_recalc_rate,
 242        .round_rate = ti_clk_divider_round_rate,
 243        .set_rate = ti_clk_divider_set_rate,
 244};
 245
 246static struct clk *_register_divider(struct device *dev, const char *name,
 247                                     const char *parent_name,
 248                                     unsigned long flags, void __iomem *reg,
 249                                     u8 shift, u8 width, u8 clk_divider_flags,
 250                                     const struct clk_div_table *table)
 251{
 252        struct clk_divider *div;
 253        struct clk *clk;
 254        struct clk_init_data init;
 255
 256        if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
 257                if (width + shift > 16) {
 258                        pr_warn("divider value exceeds LOWORD field\n");
 259                        return ERR_PTR(-EINVAL);
 260                }
 261        }
 262
 263        /* allocate the divider */
 264        div = kzalloc(sizeof(*div), GFP_KERNEL);
 265        if (!div) {
 266                pr_err("%s: could not allocate divider clk\n", __func__);
 267                return ERR_PTR(-ENOMEM);
 268        }
 269
 270        init.name = name;
 271        init.ops = &ti_clk_divider_ops;
 272        init.flags = flags | CLK_IS_BASIC;
 273        init.parent_names = (parent_name ? &parent_name : NULL);
 274        init.num_parents = (parent_name ? 1 : 0);
 275
 276        /* struct clk_divider assignments */
 277        div->reg = reg;
 278        div->shift = shift;
 279        div->width = width;
 280        div->flags = clk_divider_flags;
 281        div->hw.init = &init;
 282        div->table = table;
 283
 284        /* register the clock */
 285        clk = clk_register(dev, &div->hw);
 286
 287        if (IS_ERR(clk))
 288                kfree(div);
 289
 290        return clk;
 291}
 292
 293static struct clk_div_table *
 294_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
 295{
 296        int valid_div = 0;
 297        struct clk_div_table *table;
 298        int i;
 299        int div;
 300        u32 val;
 301        u8 flags;
 302
 303        if (!setup->num_dividers) {
 304                /* Clk divider table not provided, determine min/max divs */
 305                flags = setup->flags;
 306
 307                if (flags & CLKF_INDEX_STARTS_AT_ONE)
 308                        val = 1;
 309                else
 310                        val = 0;
 311
 312                div = 1;
 313
 314                while (div < setup->max_div) {
 315                        if (flags & CLKF_INDEX_POWER_OF_TWO)
 316                                div <<= 1;
 317                        else
 318                                div++;
 319                        val++;
 320                }
 321
 322                *width = fls(val);
 323
 324                return NULL;
 325        }
 326
 327        for (i = 0; i < setup->num_dividers; i++)
 328                if (setup->dividers[i])
 329                        valid_div++;
 330
 331        table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL);
 332        if (!table)
 333                return ERR_PTR(-ENOMEM);
 334
 335        valid_div = 0;
 336        *width = 0;
 337
 338        for (i = 0; i < setup->num_dividers; i++)
 339                if (setup->dividers[i]) {
 340                        table[valid_div].div = setup->dividers[i];
 341                        table[valid_div].val = i;
 342                        valid_div++;
 343                        *width = i;
 344                }
 345
 346        *width = fls(*width);
 347
 348        return table;
 349}
 350
 351struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
 352{
 353        struct clk_divider *div;
 354        struct clk_omap_reg *reg;
 355
 356        if (!setup)
 357                return NULL;
 358
 359        div = kzalloc(sizeof(*div), GFP_KERNEL);
 360        if (!div)
 361                return ERR_PTR(-ENOMEM);
 362
 363        reg = (struct clk_omap_reg *)&div->reg;
 364        reg->index = setup->module;
 365        reg->offset = setup->reg;
 366
 367        if (setup->flags & CLKF_INDEX_STARTS_AT_ONE)
 368                div->flags |= CLK_DIVIDER_ONE_BASED;
 369
 370        if (setup->flags & CLKF_INDEX_POWER_OF_TWO)
 371                div->flags |= CLK_DIVIDER_POWER_OF_TWO;
 372
 373        div->table = _get_div_table_from_setup(setup, &div->width);
 374
 375        div->shift = setup->bit_shift;
 376
 377        return &div->hw;
 378}
 379
 380struct clk *ti_clk_register_divider(struct ti_clk *setup)
 381{
 382        struct ti_clk_divider *div;
 383        struct clk_omap_reg *reg_setup;
 384        u32 reg;
 385        u8 width;
 386        u32 flags = 0;
 387        u8 div_flags = 0;
 388        struct clk_div_table *table;
 389        struct clk *clk;
 390
 391        div = setup->data;
 392
 393        reg_setup = (struct clk_omap_reg *)&reg;
 394
 395        reg_setup->index = div->module;
 396        reg_setup->offset = div->reg;
 397
 398        if (div->flags & CLKF_INDEX_STARTS_AT_ONE)
 399                div_flags |= CLK_DIVIDER_ONE_BASED;
 400
 401        if (div->flags & CLKF_INDEX_POWER_OF_TWO)
 402                div_flags |= CLK_DIVIDER_POWER_OF_TWO;
 403
 404        if (div->flags & CLKF_SET_RATE_PARENT)
 405                flags |= CLK_SET_RATE_PARENT;
 406
 407        table = _get_div_table_from_setup(div, &width);
 408        if (IS_ERR(table))
 409                return (struct clk *)table;
 410
 411        clk = _register_divider(NULL, setup->name, div->parent,
 412                                flags, (void __iomem *)reg, div->bit_shift,
 413                                width, div_flags, table);
 414
 415        if (IS_ERR(clk))
 416                kfree(table);
 417
 418        return clk;
 419}
 420
 421static struct clk_div_table *
 422__init ti_clk_get_div_table(struct device_node *node)
 423{
 424        struct clk_div_table *table;
 425        const __be32 *divspec;
 426        u32 val;
 427        u32 num_div;
 428        u32 valid_div;
 429        int i;
 430
 431        divspec = of_get_property(node, "ti,dividers", &num_div);
 432
 433        if (!divspec)
 434                return NULL;
 435
 436        num_div /= 4;
 437
 438        valid_div = 0;
 439
 440        /* Determine required size for divider table */
 441        for (i = 0; i < num_div; i++) {
 442                of_property_read_u32_index(node, "ti,dividers", i, &val);
 443                if (val)
 444                        valid_div++;
 445        }
 446
 447        if (!valid_div) {
 448                pr_err("no valid dividers for %s table\n", node->name);
 449                return ERR_PTR(-EINVAL);
 450        }
 451
 452        table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL);
 453
 454        if (!table)
 455                return ERR_PTR(-ENOMEM);
 456
 457        valid_div = 0;
 458
 459        for (i = 0; i < num_div; i++) {
 460                of_property_read_u32_index(node, "ti,dividers", i, &val);
 461                if (val) {
 462                        table[valid_div].div = val;
 463                        table[valid_div].val = i;
 464                        valid_div++;
 465                }
 466        }
 467
 468        return table;
 469}
 470
 471static int _get_divider_width(struct device_node *node,
 472                              const struct clk_div_table *table,
 473                              u8 flags)
 474{
 475        u32 min_div;
 476        u32 max_div;
 477        u32 val = 0;
 478        u32 div;
 479
 480        if (!table) {
 481                /* Clk divider table not provided, determine min/max divs */
 482                if (of_property_read_u32(node, "ti,min-div", &min_div))
 483                        min_div = 1;
 484
 485                if (of_property_read_u32(node, "ti,max-div", &max_div)) {
 486                        pr_err("no max-div for %s!\n", node->name);
 487                        return -EINVAL;
 488                }
 489
 490                /* Determine bit width for the field */
 491                if (flags & CLK_DIVIDER_ONE_BASED)
 492                        val = 1;
 493
 494                div = min_div;
 495
 496                while (div < max_div) {
 497                        if (flags & CLK_DIVIDER_POWER_OF_TWO)
 498                                div <<= 1;
 499                        else
 500                                div++;
 501                        val++;
 502                }
 503        } else {
 504                div = 0;
 505
 506                while (table[div].div) {
 507                        val = table[div].val;
 508                        div++;
 509                }
 510        }
 511
 512        return fls(val);
 513}
 514
 515static int __init ti_clk_divider_populate(struct device_node *node,
 516        void __iomem **reg, const struct clk_div_table **table,
 517        u32 *flags, u8 *div_flags, u8 *width, u8 *shift)
 518{
 519        u32 val;
 520
 521        *reg = ti_clk_get_reg_addr(node, 0);
 522        if (IS_ERR(*reg))
 523                return PTR_ERR(*reg);
 524
 525        if (!of_property_read_u32(node, "ti,bit-shift", &val))
 526                *shift = val;
 527        else
 528                *shift = 0;
 529
 530        *flags = 0;
 531        *div_flags = 0;
 532
 533        if (of_property_read_bool(node, "ti,index-starts-at-one"))
 534                *div_flags |= CLK_DIVIDER_ONE_BASED;
 535
 536        if (of_property_read_bool(node, "ti,index-power-of-two"))
 537                *div_flags |= CLK_DIVIDER_POWER_OF_TWO;
 538
 539        if (of_property_read_bool(node, "ti,set-rate-parent"))
 540                *flags |= CLK_SET_RATE_PARENT;
 541
 542        *table = ti_clk_get_div_table(node);
 543
 544        if (IS_ERR(*table))
 545                return PTR_ERR(*table);
 546
 547        *width = _get_divider_width(node, *table, *div_flags);
 548
 549        return 0;
 550}
 551
 552/**
 553 * of_ti_divider_clk_setup - Setup function for simple div rate clock
 554 * @node: device node for this clock
 555 *
 556 * Sets up a basic divider clock.
 557 */
 558static void __init of_ti_divider_clk_setup(struct device_node *node)
 559{
 560        struct clk *clk;
 561        const char *parent_name;
 562        void __iomem *reg;
 563        u8 clk_divider_flags = 0;
 564        u8 width = 0;
 565        u8 shift = 0;
 566        const struct clk_div_table *table = NULL;
 567        u32 flags = 0;
 568
 569        parent_name = of_clk_get_parent_name(node, 0);
 570
 571        if (ti_clk_divider_populate(node, &reg, &table, &flags,
 572                                    &clk_divider_flags, &width, &shift))
 573                goto cleanup;
 574
 575        clk = _register_divider(NULL, node->name, parent_name, flags, reg,
 576                                shift, width, clk_divider_flags, table);
 577
 578        if (!IS_ERR(clk)) {
 579                of_clk_add_provider(node, of_clk_src_simple_get, clk);
 580                of_ti_clk_autoidle_setup(node);
 581                return;
 582        }
 583
 584cleanup:
 585        kfree(table);
 586}
 587CLK_OF_DECLARE(divider_clk, "ti,divider-clock", of_ti_divider_clk_setup);
 588
 589static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
 590{
 591        struct clk_divider *div;
 592        u32 val;
 593
 594        div = kzalloc(sizeof(*div), GFP_KERNEL);
 595        if (!div)
 596                return;
 597
 598        if (ti_clk_divider_populate(node, &div->reg, &div->table, &val,
 599                                    &div->flags, &div->width, &div->shift) < 0)
 600                goto cleanup;
 601
 602        if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))
 603                return;
 604
 605cleanup:
 606        kfree(div->table);
 607        kfree(div);
 608}
 609CLK_OF_DECLARE(ti_composite_divider_clk, "ti,composite-divider-clock",
 610               of_ti_composite_divider_clk_setup);
 611