linux/drivers/clk/ti/clk.c
<<
>>
Prefs
   1/*
   2 * TI clock support
   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.h>
  19#include <linux/clk-provider.h>
  20#include <linux/clkdev.h>
  21#include <linux/clk/ti.h>
  22#include <linux/of.h>
  23#include <linux/of_address.h>
  24#include <linux/list.h>
  25#include <linux/regmap.h>
  26#include <linux/bootmem.h>
  27
  28#include "clock.h"
  29
  30#undef pr_fmt
  31#define pr_fmt(fmt) "%s: " fmt, __func__
  32
  33struct ti_clk_ll_ops *ti_clk_ll_ops;
  34static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
  35
  36static struct ti_clk_features ti_clk_features;
  37
  38struct clk_iomap {
  39        struct regmap *regmap;
  40        void __iomem *mem;
  41};
  42
  43static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
  44
  45static void clk_memmap_writel(u32 val, void __iomem *reg)
  46{
  47        struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
  48        struct clk_iomap *io = clk_memmaps[r->index];
  49
  50        if (io->regmap)
  51                regmap_write(io->regmap, r->offset, val);
  52        else
  53                writel_relaxed(val, io->mem + r->offset);
  54}
  55
  56static u32 clk_memmap_readl(void __iomem *reg)
  57{
  58        u32 val;
  59        struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
  60        struct clk_iomap *io = clk_memmaps[r->index];
  61
  62        if (io->regmap)
  63                regmap_read(io->regmap, r->offset, &val);
  64        else
  65                val = readl_relaxed(io->mem + r->offset);
  66
  67        return val;
  68}
  69
  70/**
  71 * ti_clk_setup_ll_ops - setup low level clock operations
  72 * @ops: low level clock ops descriptor
  73 *
  74 * Sets up low level clock operations for TI clock driver. This is used
  75 * to provide various callbacks for the clock driver towards platform
  76 * specific code. Returns 0 on success, -EBUSY if ll_ops have been
  77 * registered already.
  78 */
  79int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
  80{
  81        if (ti_clk_ll_ops) {
  82                pr_err("Attempt to register ll_ops multiple times.\n");
  83                return -EBUSY;
  84        }
  85
  86        ti_clk_ll_ops = ops;
  87        ops->clk_readl = clk_memmap_readl;
  88        ops->clk_writel = clk_memmap_writel;
  89
  90        return 0;
  91}
  92
  93/**
  94 * ti_dt_clocks_register - register DT alias clocks during boot
  95 * @oclks: list of clocks to register
  96 *
  97 * Register alias or non-standard DT clock entries during boot. By
  98 * default, DT clocks are found based on their node name. If any
  99 * additional con-id / dev-id -> clock mapping is required, use this
 100 * function to list these.
 101 */
 102void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
 103{
 104        struct ti_dt_clk *c;
 105        struct device_node *node;
 106        struct clk *clk;
 107        struct of_phandle_args clkspec;
 108
 109        for (c = oclks; c->node_name != NULL; c++) {
 110                node = of_find_node_by_name(NULL, c->node_name);
 111                clkspec.np = node;
 112                clk = of_clk_get_from_provider(&clkspec);
 113
 114                if (!IS_ERR(clk)) {
 115                        c->lk.clk = clk;
 116                        clkdev_add(&c->lk);
 117                } else {
 118                        pr_warn("failed to lookup clock node %s\n",
 119                                c->node_name);
 120                }
 121        }
 122}
 123
 124struct clk_init_item {
 125        struct device_node *node;
 126        struct clk_hw *hw;
 127        ti_of_clk_init_cb_t func;
 128        struct list_head link;
 129};
 130
 131static LIST_HEAD(retry_list);
 132
 133/**
 134 * ti_clk_retry_init - retries a failed clock init at later phase
 135 * @node: device not for the clock
 136 * @hw: partially initialized clk_hw struct for the clock
 137 * @func: init function to be called for the clock
 138 *
 139 * Adds a failed clock init to the retry list. The retry list is parsed
 140 * once all the other clocks have been initialized.
 141 */
 142int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 143                              ti_of_clk_init_cb_t func)
 144{
 145        struct clk_init_item *retry;
 146
 147        pr_debug("%s: adding to retry list...\n", node->name);
 148        retry = kzalloc(sizeof(*retry), GFP_KERNEL);
 149        if (!retry)
 150                return -ENOMEM;
 151
 152        retry->node = node;
 153        retry->func = func;
 154        retry->hw = hw;
 155        list_add(&retry->link, &retry_list);
 156
 157        return 0;
 158}
 159
 160/**
 161 * ti_clk_get_reg_addr - get register address for a clock register
 162 * @node: device node for the clock
 163 * @index: register index from the clock node
 164 *
 165 * Builds clock register address from device tree information. This
 166 * is a struct of type clk_omap_reg. Returns a pointer to the register
 167 * address, or a pointer error value in failure.
 168 */
 169void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
 170{
 171        struct clk_omap_reg *reg;
 172        u32 val;
 173        u32 tmp;
 174        int i;
 175
 176        reg = (struct clk_omap_reg *)&tmp;
 177
 178        for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
 179                if (clocks_node_ptr[i] == node->parent)
 180                        break;
 181        }
 182
 183        if (i == CLK_MAX_MEMMAPS) {
 184                pr_err("clk-provider not found for %s!\n", node->name);
 185                return IOMEM_ERR_PTR(-ENOENT);
 186        }
 187
 188        reg->index = i;
 189
 190        if (of_property_read_u32_index(node, "reg", index, &val)) {
 191                pr_err("%s must have reg[%d]!\n", node->name, index);
 192                return IOMEM_ERR_PTR(-EINVAL);
 193        }
 194
 195        reg->offset = val;
 196
 197        return (__force void __iomem *)tmp;
 198}
 199
 200/**
 201 * omap2_clk_provider_init - init master clock provider
 202 * @parent: master node
 203 * @index: internal index for clk_reg_ops
 204 * @syscon: syscon regmap pointer for accessing clock registers
 205 * @mem: iomem pointer for the clock provider memory area, only used if
 206 *       syscon is not provided
 207 *
 208 * Initializes a master clock IP block. This basically sets up the
 209 * mapping from clocks node to the memory map index. All the clocks
 210 * are then initialized through the common of_clk_init call, and the
 211 * clocks will access their memory maps based on the node layout.
 212 * Returns 0 in success.
 213 */
 214int __init omap2_clk_provider_init(struct device_node *parent, int index,
 215                                   struct regmap *syscon, void __iomem *mem)
 216{
 217        struct device_node *clocks;
 218        struct clk_iomap *io;
 219
 220        /* get clocks for this parent */
 221        clocks = of_get_child_by_name(parent, "clocks");
 222        if (!clocks) {
 223                pr_err("%s missing 'clocks' child node.\n", parent->name);
 224                return -EINVAL;
 225        }
 226
 227        /* add clocks node info */
 228        clocks_node_ptr[index] = clocks;
 229
 230        io = kzalloc(sizeof(*io), GFP_KERNEL);
 231        if (!io)
 232                return -ENOMEM;
 233
 234        io->regmap = syscon;
 235        io->mem = mem;
 236
 237        clk_memmaps[index] = io;
 238
 239        return 0;
 240}
 241
 242/**
 243 * omap2_clk_legacy_provider_init - initialize a legacy clock provider
 244 * @index: index for the clock provider
 245 * @mem: iomem pointer for the clock provider memory area
 246 *
 247 * Initializes a legacy clock provider memory mapping.
 248 */
 249void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
 250{
 251        struct clk_iomap *io;
 252
 253        io = memblock_virt_alloc(sizeof(*io), 0);
 254
 255        io->mem = mem;
 256
 257        clk_memmaps[index] = io;
 258}
 259
 260/**
 261 * ti_dt_clk_init_retry_clks - init clocks from the retry list
 262 *
 263 * Initializes any clocks that have failed to initialize before,
 264 * reasons being missing parent node(s) during earlier init. This
 265 * typically happens only for DPLLs which need to have both of their
 266 * parent clocks ready during init.
 267 */
 268void ti_dt_clk_init_retry_clks(void)
 269{
 270        struct clk_init_item *retry;
 271        struct clk_init_item *tmp;
 272        int retries = 5;
 273
 274        while (!list_empty(&retry_list) && retries) {
 275                list_for_each_entry_safe(retry, tmp, &retry_list, link) {
 276                        pr_debug("retry-init: %s\n", retry->node->name);
 277                        retry->func(retry->hw, retry->node);
 278                        list_del(&retry->link);
 279                        kfree(retry);
 280                }
 281                retries--;
 282        }
 283}
 284
 285#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS)
 286void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
 287{
 288        while (*patch) {
 289                memcpy((*patch)->patch, *patch, sizeof(**patch));
 290                patch++;
 291        }
 292}
 293
 294struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 295{
 296        struct clk *clk;
 297        struct ti_clk_fixed *fixed;
 298        struct ti_clk_fixed_factor *fixed_factor;
 299        struct clk_hw *clk_hw;
 300
 301        if (setup->clk)
 302                return setup->clk;
 303
 304        switch (setup->type) {
 305        case TI_CLK_FIXED:
 306                fixed = setup->data;
 307
 308                clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
 309                                              fixed->frequency);
 310                break;
 311        case TI_CLK_MUX:
 312                clk = ti_clk_register_mux(setup);
 313                break;
 314        case TI_CLK_DIVIDER:
 315                clk = ti_clk_register_divider(setup);
 316                break;
 317        case TI_CLK_COMPOSITE:
 318                clk = ti_clk_register_composite(setup);
 319                break;
 320        case TI_CLK_FIXED_FACTOR:
 321                fixed_factor = setup->data;
 322
 323                clk = clk_register_fixed_factor(NULL, setup->name,
 324                                                fixed_factor->parent,
 325                                                0, fixed_factor->mult,
 326                                                fixed_factor->div);
 327                break;
 328        case TI_CLK_GATE:
 329                clk = ti_clk_register_gate(setup);
 330                break;
 331        case TI_CLK_DPLL:
 332                clk = ti_clk_register_dpll(setup);
 333                break;
 334        default:
 335                pr_err("bad type for %s!\n", setup->name);
 336                clk = ERR_PTR(-EINVAL);
 337        }
 338
 339        if (!IS_ERR(clk)) {
 340                setup->clk = clk;
 341                if (setup->clkdm_name) {
 342                        clk_hw = __clk_get_hw(clk);
 343                        if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) {
 344                                pr_warn("can't setup clkdm for basic clk %s\n",
 345                                        setup->name);
 346                        } else {
 347                                to_clk_hw_omap(clk_hw)->clkdm_name =
 348                                        setup->clkdm_name;
 349                                omap2_init_clk_clkdm(clk_hw);
 350                        }
 351                }
 352        }
 353
 354        return clk;
 355}
 356
 357int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 358{
 359        struct clk *clk;
 360        bool retry;
 361        struct ti_clk_alias *retry_clk;
 362        struct ti_clk_alias *tmp;
 363
 364        while (clks->clk) {
 365                clk = ti_clk_register_clk(clks->clk);
 366                if (IS_ERR(clk)) {
 367                        if (PTR_ERR(clk) == -EAGAIN) {
 368                                list_add(&clks->link, &retry_list);
 369                        } else {
 370                                pr_err("register for %s failed: %ld\n",
 371                                       clks->clk->name, PTR_ERR(clk));
 372                                return PTR_ERR(clk);
 373                        }
 374                } else {
 375                        clks->lk.clk = clk;
 376                        clkdev_add(&clks->lk);
 377                }
 378                clks++;
 379        }
 380
 381        retry = true;
 382
 383        while (!list_empty(&retry_list) && retry) {
 384                retry = false;
 385                list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) {
 386                        pr_debug("retry-init: %s\n", retry_clk->clk->name);
 387                        clk = ti_clk_register_clk(retry_clk->clk);
 388                        if (IS_ERR(clk)) {
 389                                if (PTR_ERR(clk) == -EAGAIN) {
 390                                        continue;
 391                                } else {
 392                                        pr_err("register for %s failed: %ld\n",
 393                                               retry_clk->clk->name,
 394                                               PTR_ERR(clk));
 395                                        return PTR_ERR(clk);
 396                                }
 397                        } else {
 398                                retry = true;
 399                                retry_clk->lk.clk = clk;
 400                                clkdev_add(&retry_clk->lk);
 401                                list_del(&retry_clk->link);
 402                        }
 403                }
 404        }
 405
 406        return 0;
 407}
 408#endif
 409
 410/**
 411 * ti_clk_setup_features - setup clock features flags
 412 * @features: features definition to use
 413 *
 414 * Initializes the clock driver features flags based on platform
 415 * provided data. No return value.
 416 */
 417void __init ti_clk_setup_features(struct ti_clk_features *features)
 418{
 419        memcpy(&ti_clk_features, features, sizeof(*features));
 420}
 421
 422/**
 423 * ti_clk_get_features - get clock driver features flags
 424 *
 425 * Get TI clock driver features description. Returns a pointer
 426 * to the current feature setup.
 427 */
 428const struct ti_clk_features *ti_clk_get_features(void)
 429{
 430        return &ti_clk_features;
 431}
 432
 433/**
 434 * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
 435 * @clk_names: ptr to an array of strings of clock names to enable
 436 * @num_clocks: number of clock names in @clk_names
 437 *
 438 * Prepare and enable a list of clocks, named by @clk_names.  No
 439 * return value. XXX Deprecated; only needed until these clocks are
 440 * properly claimed and enabled by the drivers or core code that uses
 441 * them.  XXX What code disables & calls clk_put on these clocks?
 442 */
 443void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
 444{
 445        struct clk *init_clk;
 446        int i;
 447
 448        for (i = 0; i < num_clocks; i++) {
 449                init_clk = clk_get(NULL, clk_names[i]);
 450                if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
 451                         clk_names[i]))
 452                        continue;
 453                clk_prepare_enable(init_clk);
 454        }
 455}
 456