linux/arch/arm/mach-davinci/clock.c
<<
>>
Prefs
   1/*
   2 * Clock and PLL control for DaVinci devices
   3 *
   4 * Copyright (C) 2006-2007 Texas Instruments.
   5 * Copyright (C) 2008-2009 Deep Root Systems, LLC
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/errno.h>
  17#include <linux/clk.h>
  18#include <linux/err.h>
  19#include <linux/mutex.h>
  20#include <linux/platform_device.h>
  21#include <linux/io.h>
  22
  23#include <mach/hardware.h>
  24
  25#include <mach/psc.h>
  26#include <mach/cputype.h>
  27#include "clock.h"
  28
  29static LIST_HEAD(clocks);
  30static DEFINE_MUTEX(clocks_mutex);
  31static DEFINE_SPINLOCK(clockfw_lock);
  32
  33static unsigned psc_domain(struct clk *clk)
  34{
  35        return (clk->flags & PSC_DSP)
  36                ? DAVINCI_GPSC_DSPDOMAIN
  37                : DAVINCI_GPSC_ARMDOMAIN;
  38}
  39
  40static void __clk_enable(struct clk *clk)
  41{
  42        if (clk->parent)
  43                __clk_enable(clk->parent);
  44        if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
  45                davinci_psc_config(psc_domain(clk), clk->lpsc, 1);
  46}
  47
  48static void __clk_disable(struct clk *clk)
  49{
  50        if (WARN_ON(clk->usecount == 0))
  51                return;
  52        if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
  53                davinci_psc_config(psc_domain(clk), clk->lpsc, 0);
  54        if (clk->parent)
  55                __clk_disable(clk->parent);
  56}
  57
  58int clk_enable(struct clk *clk)
  59{
  60        unsigned long flags;
  61
  62        if (clk == NULL || IS_ERR(clk))
  63                return -EINVAL;
  64
  65        spin_lock_irqsave(&clockfw_lock, flags);
  66        __clk_enable(clk);
  67        spin_unlock_irqrestore(&clockfw_lock, flags);
  68
  69        return 0;
  70}
  71EXPORT_SYMBOL(clk_enable);
  72
  73void clk_disable(struct clk *clk)
  74{
  75        unsigned long flags;
  76
  77        if (clk == NULL || IS_ERR(clk))
  78                return;
  79
  80        spin_lock_irqsave(&clockfw_lock, flags);
  81        __clk_disable(clk);
  82        spin_unlock_irqrestore(&clockfw_lock, flags);
  83}
  84EXPORT_SYMBOL(clk_disable);
  85
  86unsigned long clk_get_rate(struct clk *clk)
  87{
  88        if (clk == NULL || IS_ERR(clk))
  89                return -EINVAL;
  90
  91        return clk->rate;
  92}
  93EXPORT_SYMBOL(clk_get_rate);
  94
  95long clk_round_rate(struct clk *clk, unsigned long rate)
  96{
  97        if (clk == NULL || IS_ERR(clk))
  98                return -EINVAL;
  99
 100        return clk->rate;
 101}
 102EXPORT_SYMBOL(clk_round_rate);
 103
 104int clk_set_rate(struct clk *clk, unsigned long rate)
 105{
 106        if (clk == NULL || IS_ERR(clk))
 107                return -EINVAL;
 108
 109        /* changing the clk rate is not supported */
 110        return -EINVAL;
 111}
 112EXPORT_SYMBOL(clk_set_rate);
 113
 114int clk_register(struct clk *clk)
 115{
 116        if (clk == NULL || IS_ERR(clk))
 117                return -EINVAL;
 118
 119        if (WARN(clk->parent && !clk->parent->rate,
 120                        "CLK: %s parent %s has no rate!\n",
 121                        clk->name, clk->parent->name))
 122                return -EINVAL;
 123
 124        mutex_lock(&clocks_mutex);
 125        list_add_tail(&clk->node, &clocks);
 126        mutex_unlock(&clocks_mutex);
 127
 128        /* If rate is already set, use it */
 129        if (clk->rate)
 130                return 0;
 131
 132        /* Otherwise, default to parent rate */
 133        if (clk->parent)
 134                clk->rate = clk->parent->rate;
 135
 136        return 0;
 137}
 138EXPORT_SYMBOL(clk_register);
 139
 140void clk_unregister(struct clk *clk)
 141{
 142        if (clk == NULL || IS_ERR(clk))
 143                return;
 144
 145        mutex_lock(&clocks_mutex);
 146        list_del(&clk->node);
 147        mutex_unlock(&clocks_mutex);
 148}
 149EXPORT_SYMBOL(clk_unregister);
 150
 151#ifdef CONFIG_DAVINCI_RESET_CLOCKS
 152/*
 153 * Disable any unused clocks left on by the bootloader
 154 */
 155static int __init clk_disable_unused(void)
 156{
 157        struct clk *ck;
 158
 159        spin_lock_irq(&clockfw_lock);
 160        list_for_each_entry(ck, &clocks, node) {
 161                if (ck->usecount > 0)
 162                        continue;
 163                if (!(ck->flags & CLK_PSC))
 164                        continue;
 165
 166                /* ignore if in Disabled or SwRstDisable states */
 167                if (!davinci_psc_is_clk_active(ck->lpsc))
 168                        continue;
 169
 170                pr_info("Clocks: disable unused %s\n", ck->name);
 171                davinci_psc_config(psc_domain(ck), ck->lpsc, 0);
 172        }
 173        spin_unlock_irq(&clockfw_lock);
 174
 175        return 0;
 176}
 177late_initcall(clk_disable_unused);
 178#endif
 179
 180static void clk_sysclk_recalc(struct clk *clk)
 181{
 182        u32 v, plldiv;
 183        struct pll_data *pll;
 184
 185        /* If this is the PLL base clock, no more calculations needed */
 186        if (clk->pll_data)
 187                return;
 188
 189        if (WARN_ON(!clk->parent))
 190                return;
 191
 192        clk->rate = clk->parent->rate;
 193
 194        /* Otherwise, the parent must be a PLL */
 195        if (WARN_ON(!clk->parent->pll_data))
 196                return;
 197
 198        pll = clk->parent->pll_data;
 199
 200        /* If pre-PLL, source clock is before the multiplier and divider(s) */
 201        if (clk->flags & PRE_PLL)
 202                clk->rate = pll->input_rate;
 203
 204        if (!clk->div_reg)
 205                return;
 206
 207        v = __raw_readl(pll->base + clk->div_reg);
 208        if (v & PLLDIV_EN) {
 209                plldiv = (v & PLLDIV_RATIO_MASK) + 1;
 210                if (plldiv)
 211                        clk->rate /= plldiv;
 212        }
 213}
 214
 215static void __init clk_pll_init(struct clk *clk)
 216{
 217        u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
 218        u8 bypass;
 219        struct pll_data *pll = clk->pll_data;
 220
 221        pll->base = IO_ADDRESS(pll->phys_base);
 222        ctrl = __raw_readl(pll->base + PLLCTL);
 223        clk->rate = pll->input_rate = clk->parent->rate;
 224
 225        if (ctrl & PLLCTL_PLLEN) {
 226                bypass = 0;
 227                mult = __raw_readl(pll->base + PLLM);
 228                mult = (mult & PLLM_PLLM_MASK) + 1;
 229        } else
 230                bypass = 1;
 231
 232        if (pll->flags & PLL_HAS_PREDIV) {
 233                prediv = __raw_readl(pll->base + PREDIV);
 234                if (prediv & PLLDIV_EN)
 235                        prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
 236                else
 237                        prediv = 1;
 238        }
 239
 240        /* pre-divider is fixed, but (some?) chips won't report that */
 241        if (cpu_is_davinci_dm355() && pll->num == 1)
 242                prediv = 8;
 243
 244        if (pll->flags & PLL_HAS_POSTDIV) {
 245                postdiv = __raw_readl(pll->base + POSTDIV);
 246                if (postdiv & PLLDIV_EN)
 247                        postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1;
 248                else
 249                        postdiv = 1;
 250        }
 251
 252        if (!bypass) {
 253                clk->rate /= prediv;
 254                clk->rate *= mult;
 255                clk->rate /= postdiv;
 256        }
 257
 258        pr_debug("PLL%d: input = %lu MHz [ ",
 259                 pll->num, clk->parent->rate / 1000000);
 260        if (bypass)
 261                pr_debug("bypass ");
 262        if (prediv > 1)
 263                pr_debug("/ %d ", prediv);
 264        if (mult > 1)
 265                pr_debug("* %d ", mult);
 266        if (postdiv > 1)
 267                pr_debug("/ %d ", postdiv);
 268        pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
 269}
 270
 271int __init davinci_clk_init(struct davinci_clk *clocks)
 272  {
 273        struct davinci_clk *c;
 274        struct clk *clk;
 275
 276        for (c = clocks; c->lk.clk; c++) {
 277                clk = c->lk.clk;
 278
 279                if (clk->pll_data)
 280                        clk_pll_init(clk);
 281
 282                /* Calculate rates for PLL-derived clocks */
 283                else if (clk->flags & CLK_PLL)
 284                        clk_sysclk_recalc(clk);
 285
 286                if (clk->lpsc)
 287                        clk->flags |= CLK_PSC;
 288
 289                clkdev_add(&c->lk);
 290                clk_register(clk);
 291
 292                /* Turn on clocks that Linux doesn't otherwise manage */
 293                if (clk->flags & ALWAYS_ENABLED)
 294                        clk_enable(clk);
 295        }
 296
 297        return 0;
 298}
 299
 300#ifdef CONFIG_PROC_FS
 301#include <linux/proc_fs.h>
 302#include <linux/seq_file.h>
 303
 304static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
 305{
 306        return *pos < 1 ? (void *)1 : NULL;
 307}
 308
 309static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
 310{
 311        ++*pos;
 312        return NULL;
 313}
 314
 315static void davinci_ck_stop(struct seq_file *m, void *v)
 316{
 317}
 318
 319#define CLKNAME_MAX     10              /* longest clock name */
 320#define NEST_DELTA      2
 321#define NEST_MAX        4
 322
 323static void
 324dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
 325{
 326        char            *state;
 327        char            buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
 328        struct clk      *clk;
 329        unsigned        i;
 330
 331        if (parent->flags & CLK_PLL)
 332                state = "pll";
 333        else if (parent->flags & CLK_PSC)
 334                state = "psc";
 335        else
 336                state = "";
 337
 338        /* <nest spaces> name <pad to end> */
 339        memset(buf, ' ', sizeof(buf) - 1);
 340        buf[sizeof(buf) - 1] = 0;
 341        i = strlen(parent->name);
 342        memcpy(buf + nest, parent->name,
 343                        min(i, (unsigned)(sizeof(buf) - 1 - nest)));
 344
 345        seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
 346                   buf, parent->usecount, state, clk_get_rate(parent));
 347        /* REVISIT show device associations too */
 348
 349        /* cost is now small, but not linear... */
 350        list_for_each_entry(clk, &clocks, node) {
 351                if (clk->parent == parent)
 352                        dump_clock(s, nest + NEST_DELTA, clk);
 353        }
 354}
 355
 356static int davinci_ck_show(struct seq_file *m, void *v)
 357{
 358        /* Show clock tree; we know the main oscillator is first.
 359         * We trust nonzero usecounts equate to PSC enables...
 360         */
 361        mutex_lock(&clocks_mutex);
 362        if (!list_empty(&clocks))
 363                dump_clock(m, 0, list_first_entry(&clocks, struct clk, node));
 364        mutex_unlock(&clocks_mutex);
 365
 366        return 0;
 367}
 368
 369static const struct seq_operations davinci_ck_op = {
 370        .start  = davinci_ck_start,
 371        .next   = davinci_ck_next,
 372        .stop   = davinci_ck_stop,
 373        .show   = davinci_ck_show
 374};
 375
 376static int davinci_ck_open(struct inode *inode, struct file *file)
 377{
 378        return seq_open(file, &davinci_ck_op);
 379}
 380
 381static const struct file_operations proc_davinci_ck_operations = {
 382        .open           = davinci_ck_open,
 383        .read           = seq_read,
 384        .llseek         = seq_lseek,
 385        .release        = seq_release,
 386};
 387
 388static int __init davinci_ck_proc_init(void)
 389{
 390        proc_create("davinci_clocks", 0, NULL, &proc_davinci_ck_operations);
 391        return 0;
 392
 393}
 394__initcall(davinci_ck_proc_init);
 395#endif /* CONFIG_DEBUG_PROC_FS */
 396
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.