linux/arch/arm/mach-ep93xx/clock.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-ep93xx/clock.c
   3 * Clock control for Cirrus EP93xx chips.
   4 *
   5 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
   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 (at
  10 * your option) any later version.
  11 */
  12
  13#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
  14
  15#include <linux/kernel.h>
  16#include <linux/clk.h>
  17#include <linux/err.h>
  18#include <linux/module.h>
  19#include <linux/string.h>
  20#include <linux/io.h>
  21#include <linux/spinlock.h>
  22#include <linux/clkdev.h>
  23
  24#include <mach/hardware.h>
  25
  26#include <asm/div64.h>
  27
  28#include "soc.h"
  29
  30struct clk {
  31        struct clk      *parent;
  32        unsigned long   rate;
  33        int             users;
  34        int             sw_locked;
  35        void __iomem    *enable_reg;
  36        u32             enable_mask;
  37
  38        unsigned long   (*get_rate)(struct clk *clk);
  39        int             (*set_rate)(struct clk *clk, unsigned long rate);
  40};
  41
  42
  43static unsigned long get_uart_rate(struct clk *clk);
  44
  45static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
  46static int set_div_rate(struct clk *clk, unsigned long rate);
  47static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
  48static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
  49
  50static struct clk clk_xtali = {
  51        .rate           = EP93XX_EXT_CLK_RATE,
  52};
  53static struct clk clk_uart1 = {
  54        .parent         = &clk_xtali,
  55        .sw_locked      = 1,
  56        .enable_reg     = EP93XX_SYSCON_DEVCFG,
  57        .enable_mask    = EP93XX_SYSCON_DEVCFG_U1EN,
  58        .get_rate       = get_uart_rate,
  59};
  60static struct clk clk_uart2 = {
  61        .parent         = &clk_xtali,
  62        .sw_locked      = 1,
  63        .enable_reg     = EP93XX_SYSCON_DEVCFG,
  64        .enable_mask    = EP93XX_SYSCON_DEVCFG_U2EN,
  65        .get_rate       = get_uart_rate,
  66};
  67static struct clk clk_uart3 = {
  68        .parent         = &clk_xtali,
  69        .sw_locked      = 1,
  70        .enable_reg     = EP93XX_SYSCON_DEVCFG,
  71        .enable_mask    = EP93XX_SYSCON_DEVCFG_U3EN,
  72        .get_rate       = get_uart_rate,
  73};
  74static struct clk clk_pll1 = {
  75        .parent         = &clk_xtali,
  76};
  77static struct clk clk_f = {
  78        .parent         = &clk_pll1,
  79};
  80static struct clk clk_h = {
  81        .parent         = &clk_pll1,
  82};
  83static struct clk clk_p = {
  84        .parent         = &clk_pll1,
  85};
  86static struct clk clk_pll2 = {
  87        .parent         = &clk_xtali,
  88};
  89static struct clk clk_usb_host = {
  90        .parent         = &clk_pll2,
  91        .enable_reg     = EP93XX_SYSCON_PWRCNT,
  92        .enable_mask    = EP93XX_SYSCON_PWRCNT_USH_EN,
  93};
  94static struct clk clk_keypad = {
  95        .parent         = &clk_xtali,
  96        .sw_locked      = 1,
  97        .enable_reg     = EP93XX_SYSCON_KEYTCHCLKDIV,
  98        .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
  99        .set_rate       = set_keytchclk_rate,
 100};
 101static struct clk clk_adc = {
 102        .parent         = &clk_xtali,
 103        .sw_locked      = 1,
 104        .enable_reg     = EP93XX_SYSCON_KEYTCHCLKDIV,
 105        .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
 106        .set_rate       = set_keytchclk_rate,
 107};
 108static struct clk clk_spi = {
 109        .parent         = &clk_xtali,
 110        .rate           = EP93XX_EXT_CLK_RATE,
 111};
 112static struct clk clk_pwm = {
 113        .parent         = &clk_xtali,
 114        .rate           = EP93XX_EXT_CLK_RATE,
 115};
 116
 117static struct clk clk_video = {
 118        .sw_locked      = 1,
 119        .enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
 120        .enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
 121        .set_rate       = set_div_rate,
 122};
 123
 124static struct clk clk_i2s_mclk = {
 125        .sw_locked      = 1,
 126        .enable_reg     = EP93XX_SYSCON_I2SCLKDIV,
 127        .enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
 128        .set_rate       = set_div_rate,
 129};
 130
 131static struct clk clk_i2s_sclk = {
 132        .sw_locked      = 1,
 133        .parent         = &clk_i2s_mclk,
 134        .enable_reg     = EP93XX_SYSCON_I2SCLKDIV,
 135        .enable_mask    = EP93XX_SYSCON_I2SCLKDIV_SENA,
 136        .set_rate       = set_i2s_sclk_rate,
 137};
 138
 139static struct clk clk_i2s_lrclk = {
 140        .sw_locked      = 1,
 141        .parent         = &clk_i2s_sclk,
 142        .enable_reg     = EP93XX_SYSCON_I2SCLKDIV,
 143        .enable_mask    = EP93XX_SYSCON_I2SCLKDIV_SENA,
 144        .set_rate       = set_i2s_lrclk_rate,
 145};
 146
 147/* DMA Clocks */
 148static struct clk clk_m2p0 = {
 149        .parent         = &clk_h,
 150        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 151        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
 152};
 153static struct clk clk_m2p1 = {
 154        .parent         = &clk_h,
 155        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 156        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
 157};
 158static struct clk clk_m2p2 = {
 159        .parent         = &clk_h,
 160        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 161        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
 162};
 163static struct clk clk_m2p3 = {
 164        .parent         = &clk_h,
 165        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 166        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
 167};
 168static struct clk clk_m2p4 = {
 169        .parent         = &clk_h,
 170        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 171        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
 172};
 173static struct clk clk_m2p5 = {
 174        .parent         = &clk_h,
 175        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 176        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
 177};
 178static struct clk clk_m2p6 = {
 179        .parent         = &clk_h,
 180        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 181        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
 182};
 183static struct clk clk_m2p7 = {
 184        .parent         = &clk_h,
 185        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 186        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
 187};
 188static struct clk clk_m2p8 = {
 189        .parent         = &clk_h,
 190        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 191        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
 192};
 193static struct clk clk_m2p9 = {
 194        .parent         = &clk_h,
 195        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 196        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
 197};
 198static struct clk clk_m2m0 = {
 199        .parent         = &clk_h,
 200        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 201        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
 202};
 203static struct clk clk_m2m1 = {
 204        .parent         = &clk_h,
 205        .enable_reg     = EP93XX_SYSCON_PWRCNT,
 206        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
 207};
 208
 209#define INIT_CK(dev,con,ck)                                     \
 210        { .dev_id = dev, .con_id = con, .clk = ck }
 211
 212static struct clk_lookup clocks[] = {
 213        INIT_CK(NULL,                   "xtali",        &clk_xtali),
 214        INIT_CK("apb:uart1",            NULL,           &clk_uart1),
 215        INIT_CK("apb:uart2",            NULL,           &clk_uart2),
 216        INIT_CK("apb:uart3",            NULL,           &clk_uart3),
 217        INIT_CK(NULL,                   "pll1",         &clk_pll1),
 218        INIT_CK(NULL,                   "fclk",         &clk_f),
 219        INIT_CK(NULL,                   "hclk",         &clk_h),
 220        INIT_CK(NULL,                   "apb_pclk",     &clk_p),
 221        INIT_CK(NULL,                   "pll2",         &clk_pll2),
 222        INIT_CK("ohci-platform",        NULL,           &clk_usb_host),
 223        INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
 224        INIT_CK("ep93xx-adc",           NULL,           &clk_adc),
 225        INIT_CK("ep93xx-fb",            NULL,           &clk_video),
 226        INIT_CK("ep93xx-spi.0",         NULL,           &clk_spi),
 227        INIT_CK("ep93xx-i2s",           "mclk",         &clk_i2s_mclk),
 228        INIT_CK("ep93xx-i2s",           "sclk",         &clk_i2s_sclk),
 229        INIT_CK("ep93xx-i2s",           "lrclk",        &clk_i2s_lrclk),
 230        INIT_CK(NULL,                   "pwm_clk",      &clk_pwm),
 231        INIT_CK(NULL,                   "m2p0",         &clk_m2p0),
 232        INIT_CK(NULL,                   "m2p1",         &clk_m2p1),
 233        INIT_CK(NULL,                   "m2p2",         &clk_m2p2),
 234        INIT_CK(NULL,                   "m2p3",         &clk_m2p3),
 235        INIT_CK(NULL,                   "m2p4",         &clk_m2p4),
 236        INIT_CK(NULL,                   "m2p5",         &clk_m2p5),
 237        INIT_CK(NULL,                   "m2p6",         &clk_m2p6),
 238        INIT_CK(NULL,                   "m2p7",         &clk_m2p7),
 239        INIT_CK(NULL,                   "m2p8",         &clk_m2p8),
 240        INIT_CK(NULL,                   "m2p9",         &clk_m2p9),
 241        INIT_CK(NULL,                   "m2m0",         &clk_m2m0),
 242        INIT_CK(NULL,                   "m2m1",         &clk_m2m1),
 243};
 244
 245static DEFINE_SPINLOCK(clk_lock);
 246
 247static void __clk_enable(struct clk *clk)
 248{
 249        if (!clk->users++) {
 250                if (clk->parent)
 251                        __clk_enable(clk->parent);
 252
 253                if (clk->enable_reg) {
 254                        u32 v;
 255
 256                        v = __raw_readl(clk->enable_reg);
 257                        v |= clk->enable_mask;
 258                        if (clk->sw_locked)
 259                                ep93xx_syscon_swlocked_write(v, clk->enable_reg);
 260                        else
 261                                __raw_writel(v, clk->enable_reg);
 262                }
 263        }
 264}
 265
 266int clk_enable(struct clk *clk)
 267{
 268        unsigned long flags;
 269
 270        if (!clk)
 271                return -EINVAL;
 272
 273        spin_lock_irqsave(&clk_lock, flags);
 274        __clk_enable(clk);
 275        spin_unlock_irqrestore(&clk_lock, flags);
 276
 277        return 0;
 278}
 279EXPORT_SYMBOL(clk_enable);
 280
 281static void __clk_disable(struct clk *clk)
 282{
 283        if (!--clk->users) {
 284                if (clk->enable_reg) {
 285                        u32 v;
 286
 287                        v = __raw_readl(clk->enable_reg);
 288                        v &= ~clk->enable_mask;
 289                        if (clk->sw_locked)
 290                                ep93xx_syscon_swlocked_write(v, clk->enable_reg);
 291                        else
 292                                __raw_writel(v, clk->enable_reg);
 293                }
 294
 295                if (clk->parent)
 296                        __clk_disable(clk->parent);
 297        }
 298}
 299
 300void clk_disable(struct clk *clk)
 301{
 302        unsigned long flags;
 303
 304        if (!clk)
 305                return;
 306
 307        spin_lock_irqsave(&clk_lock, flags);
 308        __clk_disable(clk);
 309        spin_unlock_irqrestore(&clk_lock, flags);
 310}
 311EXPORT_SYMBOL(clk_disable);
 312
 313static unsigned long get_uart_rate(struct clk *clk)
 314{
 315        unsigned long rate = clk_get_rate(clk->parent);
 316        u32 value;
 317
 318        value = __raw_readl(EP93XX_SYSCON_PWRCNT);
 319        if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
 320                return rate;
 321        else
 322                return rate / 2;
 323}
 324
 325unsigned long clk_get_rate(struct clk *clk)
 326{
 327        if (clk->get_rate)
 328                return clk->get_rate(clk);
 329
 330        return clk->rate;
 331}
 332EXPORT_SYMBOL(clk_get_rate);
 333
 334static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
 335{
 336        u32 val;
 337        u32 div_bit;
 338
 339        val = __raw_readl(clk->enable_reg);
 340
 341        /*
 342         * The Key Matrix and ADC clocks are configured using the same
 343         * System Controller register.  The clock used will be either
 344         * 1/4 or 1/16 the external clock rate depending on the
 345         * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
 346         * bit being set or cleared.
 347         */
 348        div_bit = clk->enable_mask >> 15;
 349
 350        if (rate == EP93XX_KEYTCHCLK_DIV4)
 351                val |= div_bit;
 352        else if (rate == EP93XX_KEYTCHCLK_DIV16)
 353                val &= ~div_bit;
 354        else
 355                return -EINVAL;
 356
 357        ep93xx_syscon_swlocked_write(val, clk->enable_reg);
 358        clk->rate = rate;
 359        return 0;
 360}
 361
 362static int calc_clk_div(struct clk *clk, unsigned long rate,
 363                        int *psel, int *esel, int *pdiv, int *div)
 364{
 365        struct clk *mclk;
 366        unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
 367        int i, found = 0, __div = 0, __pdiv = 0;
 368
 369        /* Don't exceed the maximum rate */
 370        max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
 371        rate = min(rate, max_rate);
 372
 373        /*
 374         * Try the two pll's and the external clock
 375         * Because the valid predividers are 2, 2.5 and 3, we multiply
 376         * all the clocks by 2 to avoid floating point math.
 377         *
 378         * This is based on the algorithm in the ep93xx raster guide:
 379         * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
 380         *
 381         */
 382        for (i = 0; i < 3; i++) {
 383                if (i == 0)
 384                        mclk = &clk_xtali;
 385                else if (i == 1)
 386                        mclk = &clk_pll1;
 387                else
 388                        mclk = &clk_pll2;
 389                mclk_rate = mclk->rate * 2;
 390
 391                /* Try each predivider value */
 392                for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
 393                        __div = mclk_rate / (rate * __pdiv);
 394                        if (__div < 2 || __div > 127)
 395                                continue;
 396
 397                        actual_rate = mclk_rate / (__pdiv * __div);
 398
 399                        if (!found || abs(actual_rate - rate) < rate_err) {
 400                                *pdiv = __pdiv - 3;
 401                                *div = __div;
 402                                *psel = (i == 2);
 403                                *esel = (i != 0);
 404                                clk->parent = mclk;
 405                                clk->rate = actual_rate;
 406                                rate_err = abs(actual_rate - rate);
 407                                found = 1;
 408                        }
 409                }
 410        }
 411
 412        if (!found)
 413                return -EINVAL;
 414
 415        return 0;
 416}
 417
 418static int set_div_rate(struct clk *clk, unsigned long rate)
 419{
 420        int err, psel = 0, esel = 0, pdiv = 0, div = 0;
 421        u32 val;
 422
 423        err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
 424        if (err)
 425                return err;
 426
 427        /* Clear the esel, psel, pdiv and div bits */
 428        val = __raw_readl(clk->enable_reg);
 429        val &= ~0x7fff;
 430
 431        /* Set the new esel, psel, pdiv and div bits for the new clock rate */
 432        val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
 433                (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
 434                (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
 435        ep93xx_syscon_swlocked_write(val, clk->enable_reg);
 436        return 0;
 437}
 438
 439static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
 440{
 441        unsigned val = __raw_readl(clk->enable_reg);
 442
 443        if (rate == clk_i2s_mclk.rate / 2)
 444                ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV, 
 445                                             clk->enable_reg);
 446        else if (rate == clk_i2s_mclk.rate / 4)
 447                ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV, 
 448                                             clk->enable_reg);
 449        else
 450                return -EINVAL;
 451
 452        clk_i2s_sclk.rate = rate;
 453        return 0;
 454}
 455
 456static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
 457{
 458        unsigned val = __raw_readl(clk->enable_reg) & 
 459                ~EP93XX_I2SCLKDIV_LRDIV_MASK;
 460        
 461        if (rate == clk_i2s_sclk.rate / 32)
 462                ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
 463                                             clk->enable_reg);
 464        else if (rate == clk_i2s_sclk.rate / 64)
 465                ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
 466                                             clk->enable_reg);
 467        else if (rate == clk_i2s_sclk.rate / 128)
 468                ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
 469                                             clk->enable_reg);
 470        else
 471                return -EINVAL;
 472
 473        clk_i2s_lrclk.rate = rate;
 474        return 0;
 475}
 476
 477int clk_set_rate(struct clk *clk, unsigned long rate)
 478{
 479        if (clk->set_rate)
 480                return clk->set_rate(clk, rate);
 481
 482        return -EINVAL;
 483}
 484EXPORT_SYMBOL(clk_set_rate);
 485
 486long clk_round_rate(struct clk *clk, unsigned long rate)
 487{
 488        WARN_ON(clk);
 489        return 0;
 490}
 491EXPORT_SYMBOL(clk_round_rate);
 492
 493int clk_set_parent(struct clk *clk, struct clk *parent)
 494{
 495        WARN_ON(clk);
 496        return 0;
 497}
 498EXPORT_SYMBOL(clk_set_parent);
 499
 500struct clk *clk_get_parent(struct clk *clk)
 501{
 502        return clk->parent;
 503}
 504EXPORT_SYMBOL(clk_get_parent);
 505
 506
 507static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
 508static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
 509static char pclk_divisors[] = { 1, 2, 4, 8 };
 510
 511/*
 512 * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
 513 */
 514static unsigned long calc_pll_rate(u32 config_word)
 515{
 516        unsigned long long rate;
 517        int i;
 518
 519        rate = clk_xtali.rate;
 520        rate *= ((config_word >> 11) & 0x1f) + 1;               /* X1FBD */
 521        rate *= ((config_word >> 5) & 0x3f) + 1;                /* X2FBD */
 522        do_div(rate, (config_word & 0x1f) + 1);                 /* X2IPD */
 523        for (i = 0; i < ((config_word >> 16) & 3); i++)         /* PS */
 524                rate >>= 1;
 525
 526        return (unsigned long)rate;
 527}
 528
 529static void __init ep93xx_dma_clock_init(void)
 530{
 531        clk_m2p0.rate = clk_h.rate;
 532        clk_m2p1.rate = clk_h.rate;
 533        clk_m2p2.rate = clk_h.rate;
 534        clk_m2p3.rate = clk_h.rate;
 535        clk_m2p4.rate = clk_h.rate;
 536        clk_m2p5.rate = clk_h.rate;
 537        clk_m2p6.rate = clk_h.rate;
 538        clk_m2p7.rate = clk_h.rate;
 539        clk_m2p8.rate = clk_h.rate;
 540        clk_m2p9.rate = clk_h.rate;
 541        clk_m2m0.rate = clk_h.rate;
 542        clk_m2m1.rate = clk_h.rate;
 543}
 544
 545static int __init ep93xx_clock_init(void)
 546{
 547        u32 value;
 548
 549        /* Determine the bootloader configured pll1 rate */
 550        value = __raw_readl(EP93XX_SYSCON_CLKSET1);
 551        if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
 552                clk_pll1.rate = clk_xtali.rate;
 553        else
 554                clk_pll1.rate = calc_pll_rate(value);
 555
 556        /* Initialize the pll1 derived clocks */
 557        clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
 558        clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
 559        clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
 560        ep93xx_dma_clock_init();
 561
 562        /* Determine the bootloader configured pll2 rate */
 563        value = __raw_readl(EP93XX_SYSCON_CLKSET2);
 564        if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
 565                clk_pll2.rate = clk_xtali.rate;
 566        else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
 567                clk_pll2.rate = calc_pll_rate(value);
 568        else
 569                clk_pll2.rate = 0;
 570
 571        /* Initialize the pll2 derived clocks */
 572        clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
 573
 574        /*
 575         * EP93xx SSP clock rate was doubled in version E2. For more information
 576         * see:
 577         *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
 578         */
 579        if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
 580                clk_spi.rate /= 2;
 581
 582        pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
 583                clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
 584        pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
 585                clk_f.rate / 1000000, clk_h.rate / 1000000,
 586                clk_p.rate / 1000000);
 587
 588        clkdev_add_table(clocks, ARRAY_SIZE(clocks));
 589        return 0;
 590}
 591postcore_initcall(ep93xx_clock_init);
 592