linux/arch/arm/mach-imx/clock-imx35.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License
   6 * as published by the Free Software Foundation; either version 2
   7 * of the License, or (at your option) any later version.
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program; if not, write to the Free Software
  15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16 * MA 02110-1301, USA.
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/init.h>
  21#include <linux/list.h>
  22#include <linux/clk.h>
  23#include <linux/io.h>
  24#include <linux/clkdev.h>
  25
  26#include <mach/clock.h>
  27#include <mach/hardware.h>
  28#include <mach/common.h>
  29
  30#define CCM_BASE        MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
  31
  32#define CCM_CCMR        0x00
  33#define CCM_PDR0        0x04
  34#define CCM_PDR1        0x08
  35#define CCM_PDR2        0x0C
  36#define CCM_PDR3        0x10
  37#define CCM_PDR4        0x14
  38#define CCM_RCSR        0x18
  39#define CCM_MPCTL       0x1C
  40#define CCM_PPCTL       0x20
  41#define CCM_ACMR        0x24
  42#define CCM_COSR        0x28
  43#define CCM_CGR0        0x2C
  44#define CCM_CGR1        0x30
  45#define CCM_CGR2        0x34
  46#define CCM_CGR3        0x38
  47
  48#ifdef HAVE_SET_RATE_SUPPORT
  49static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
  50{
  51        u32 min_pre, temp_pre, old_err, err;
  52
  53        min_pre = (div - 1) / maxpost + 1;
  54        old_err = 8;
  55
  56        for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
  57                if (div > (temp_pre * maxpost))
  58                        break;
  59
  60                if (div < (temp_pre * temp_pre))
  61                        continue;
  62
  63                err = div % temp_pre;
  64
  65                if (err == 0) {
  66                        *pre = temp_pre;
  67                        break;
  68                }
  69
  70                err = temp_pre - err;
  71
  72                if (err < old_err) {
  73                        old_err = err;
  74                        *pre = temp_pre;
  75                }
  76        }
  77
  78        *post = (div + *pre - 1) / *pre;
  79}
  80
  81/* get the best values for a 3-bit divider combined with a 6-bit divider */
  82static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
  83{
  84        if (div >= 512) {
  85                *pre = 8;
  86                *post = 64;
  87        } else if (div >= 64) {
  88                calc_dividers(div, pre, post, 64);
  89        } else if (div <= 8) {
  90                *pre = div;
  91                *post = 1;
  92        } else {
  93                *pre = 1;
  94                *post = div;
  95        }
  96}
  97
  98/* get the best values for two cascaded 3-bit dividers */
  99static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
 100{
 101        if (div >= 64) {
 102                *pre = *post = 8;
 103        } else if (div > 8) {
 104                calc_dividers(div, pre, post, 8);
 105        } else {
 106                *pre = 1;
 107                *post = div;
 108        }
 109}
 110#endif
 111
 112static unsigned long get_rate_mpll(void)
 113{
 114        ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
 115
 116        return mxc_decode_pll(mpctl, 24000000);
 117}
 118
 119static unsigned long get_rate_ppll(void)
 120{
 121        ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
 122
 123        return mxc_decode_pll(ppctl, 24000000);
 124}
 125
 126struct arm_ahb_div {
 127        unsigned char arm, ahb, sel;
 128};
 129
 130static struct arm_ahb_div clk_consumer[] = {
 131        { .arm = 1, .ahb = 4, .sel = 0},
 132        { .arm = 1, .ahb = 3, .sel = 1},
 133        { .arm = 2, .ahb = 2, .sel = 0},
 134        { .arm = 0, .ahb = 0, .sel = 0},
 135        { .arm = 0, .ahb = 0, .sel = 0},
 136        { .arm = 0, .ahb = 0, .sel = 0},
 137        { .arm = 4, .ahb = 1, .sel = 0},
 138        { .arm = 1, .ahb = 5, .sel = 0},
 139        { .arm = 1, .ahb = 8, .sel = 0},
 140        { .arm = 1, .ahb = 6, .sel = 1},
 141        { .arm = 2, .ahb = 4, .sel = 0},
 142        { .arm = 0, .ahb = 0, .sel = 0},
 143        { .arm = 0, .ahb = 0, .sel = 0},
 144        { .arm = 0, .ahb = 0, .sel = 0},
 145        { .arm = 4, .ahb = 2, .sel = 0},
 146        { .arm = 0, .ahb = 0, .sel = 0},
 147};
 148
 149static unsigned long get_rate_arm(void)
 150{
 151        unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
 152        struct arm_ahb_div *aad;
 153        unsigned long fref = get_rate_mpll();
 154
 155        aad = &clk_consumer[(pdr0 >> 16) & 0xf];
 156        if (aad->sel)
 157                fref = fref * 3 / 4;
 158
 159        return fref / aad->arm;
 160}
 161
 162static unsigned long get_rate_ahb(struct clk *clk)
 163{
 164        unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
 165        struct arm_ahb_div *aad;
 166        unsigned long fref = get_rate_arm();
 167
 168        aad = &clk_consumer[(pdr0 >> 16) & 0xf];
 169
 170        return fref / aad->ahb;
 171}
 172
 173static unsigned long get_rate_ipg(struct clk *clk)
 174{
 175        return get_rate_ahb(NULL) >> 1;
 176}
 177
 178static unsigned long get_rate_uart(struct clk *clk)
 179{
 180        unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
 181        unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
 182        unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
 183
 184        if (pdr3 & (1 << 14))
 185                return get_rate_arm() / div;
 186        else
 187                return get_rate_ppll() / div;
 188}
 189
 190static unsigned long get_rate_sdhc(struct clk *clk)
 191{
 192        unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
 193        unsigned long div, rate;
 194
 195        if (pdr3 & (1 << 6))
 196                rate = get_rate_arm();
 197        else
 198                rate = get_rate_ppll();
 199
 200        switch (clk->id) {
 201        default:
 202        case 0:
 203                div = pdr3 & 0x3f;
 204                break;
 205        case 1:
 206                div = (pdr3 >> 8) & 0x3f;
 207                break;
 208        case 2:
 209                div = (pdr3 >> 16) & 0x3f;
 210                break;
 211        }
 212
 213        return rate / (div + 1);
 214}
 215
 216static unsigned long get_rate_mshc(struct clk *clk)
 217{
 218        unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
 219        unsigned long div1, div2, rate;
 220
 221        if (pdr1 & (1 << 7))
 222                rate = get_rate_arm();
 223        else
 224                rate = get_rate_ppll();
 225
 226        div1 = (pdr1 >> 29) & 0x7;
 227        div2 = (pdr1 >> 22) & 0x3f;
 228
 229        return rate / ((div1 + 1) * (div2 + 1));
 230}
 231
 232static unsigned long get_rate_ssi(struct clk *clk)
 233{
 234        unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
 235        unsigned long div1, div2, rate;
 236
 237        if (pdr2 & (1 << 6))
 238                rate = get_rate_arm();
 239        else
 240                rate = get_rate_ppll();
 241
 242        switch (clk->id) {
 243        default:
 244        case 0:
 245                div1 = pdr2 & 0x3f;
 246                div2 = (pdr2 >> 24) & 0x7;
 247                break;
 248        case 1:
 249                div1 = (pdr2 >> 8) & 0x3f;
 250                div2 = (pdr2 >> 27) & 0x7;
 251                break;
 252        }
 253
 254        return rate / ((div1 + 1) * (div2 + 1));
 255}
 256
 257static unsigned long get_rate_csi(struct clk *clk)
 258{
 259        unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
 260        unsigned long rate;
 261
 262        if (pdr2 & (1 << 7))
 263                rate = get_rate_arm();
 264        else
 265                rate = get_rate_ppll();
 266
 267        return rate / (((pdr2 >> 16) & 0x3f) + 1);
 268}
 269
 270static unsigned long get_rate_otg(struct clk *clk)
 271{
 272        unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
 273        unsigned long rate;
 274
 275        if (pdr4 & (1 << 9))
 276                rate = get_rate_arm();
 277        else
 278                rate = get_rate_ppll();
 279
 280        return rate / (((pdr4 >> 22) & 0x3f) + 1);
 281}
 282
 283static unsigned long get_rate_ipg_per(struct clk *clk)
 284{
 285        unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
 286        unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
 287        unsigned long div;
 288
 289        if (pdr0 & (1 << 26)) {
 290                div = (pdr4 >> 16) & 0x3f;
 291                return get_rate_arm() / (div + 1);
 292        } else {
 293                div = (pdr0 >> 12) & 0x7;
 294                return get_rate_ahb(NULL) / (div + 1);
 295        }
 296}
 297
 298static unsigned long get_rate_hsp(struct clk *clk)
 299{
 300        unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03;
 301        unsigned long fref = get_rate_mpll();
 302
 303        if (fref > 400 * 1000 * 1000) {
 304                switch (hsp_podf) {
 305                case 0:
 306                        return fref >> 2;
 307                case 1:
 308                        return fref >> 3;
 309                case 2:
 310                        return fref / 3;
 311                }
 312        } else {
 313                switch (hsp_podf) {
 314                case 0:
 315                case 2:
 316                        return fref / 3;
 317                case 1:
 318                        return fref / 6;
 319                }
 320        }
 321
 322        return 0;
 323}
 324
 325static int clk_cgr_enable(struct clk *clk)
 326{
 327        u32 reg;
 328
 329        reg = __raw_readl(clk->enable_reg);
 330        reg |= 3 << clk->enable_shift;
 331        __raw_writel(reg, clk->enable_reg);
 332
 333        return 0;
 334}
 335
 336static void clk_cgr_disable(struct clk *clk)
 337{
 338        u32 reg;
 339
 340        reg = __raw_readl(clk->enable_reg);
 341        reg &= ~(3 << clk->enable_shift);
 342        __raw_writel(reg, clk->enable_reg);
 343}
 344
 345#define DEFINE_CLOCK(name, i, er, es, gr, sr)           \
 346        static struct clk name = {                      \
 347                .id             = i,                    \
 348                .enable_reg     = CCM_BASE + er,        \
 349                .enable_shift   = es,                   \
 350                .get_rate       = gr,                   \
 351                .set_rate       = sr,                   \
 352                .enable         = clk_cgr_enable,       \
 353                .disable        = clk_cgr_disable,      \
 354        }
 355
 356DEFINE_CLOCK(asrc_clk,   0, CCM_CGR0,  0, NULL, NULL);
 357DEFINE_CLOCK(pata_clk,    0, CCM_CGR0,  2, get_rate_ipg, NULL);
 358/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL); */
 359DEFINE_CLOCK(can1_clk,   0, CCM_CGR0,  6, get_rate_ipg, NULL);
 360DEFINE_CLOCK(can2_clk,   1, CCM_CGR0,  8, get_rate_ipg, NULL);
 361DEFINE_CLOCK(cspi1_clk,  0, CCM_CGR0, 10, get_rate_ipg, NULL);
 362DEFINE_CLOCK(cspi2_clk,  1, CCM_CGR0, 12, get_rate_ipg, NULL);
 363DEFINE_CLOCK(ect_clk,    0, CCM_CGR0, 14, get_rate_ipg, NULL);
 364DEFINE_CLOCK(edio_clk,   0, CCM_CGR0, 16, NULL, NULL);
 365DEFINE_CLOCK(emi_clk,    0, CCM_CGR0, 18, get_rate_ipg, NULL);
 366DEFINE_CLOCK(epit1_clk,  0, CCM_CGR0, 20, get_rate_ipg, NULL);
 367DEFINE_CLOCK(epit2_clk,  1, CCM_CGR0, 22, get_rate_ipg, NULL);
 368DEFINE_CLOCK(esai_clk,   0, CCM_CGR0, 24, NULL, NULL);
 369DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
 370DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
 371DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
 372
 373DEFINE_CLOCK(fec_clk,    0, CCM_CGR1,  0, get_rate_ipg, NULL);
 374DEFINE_CLOCK(gpio1_clk,  0, CCM_CGR1,  2, NULL, NULL);
 375DEFINE_CLOCK(gpio2_clk,  1, CCM_CGR1,  4, NULL, NULL);
 376DEFINE_CLOCK(gpio3_clk,  2, CCM_CGR1,  6, NULL, NULL);
 377DEFINE_CLOCK(gpt_clk,    0, CCM_CGR1,  8, get_rate_ipg, NULL);
 378DEFINE_CLOCK(i2c1_clk,   0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
 379DEFINE_CLOCK(i2c2_clk,   1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
 380DEFINE_CLOCK(i2c3_clk,   2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
 381DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
 382DEFINE_CLOCK(ipu_clk,    0, CCM_CGR1, 18, get_rate_hsp, NULL);
 383DEFINE_CLOCK(kpp_clk,    0, CCM_CGR1, 20, get_rate_ipg, NULL);
 384DEFINE_CLOCK(mlb_clk,    0, CCM_CGR1, 22, get_rate_ahb, NULL);
 385DEFINE_CLOCK(mshc_clk,   0, CCM_CGR1, 24, get_rate_mshc, NULL);
 386DEFINE_CLOCK(owire_clk,  0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
 387DEFINE_CLOCK(pwm_clk,    0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
 388DEFINE_CLOCK(rngc_clk,   0, CCM_CGR1, 30, get_rate_ipg, NULL);
 389
 390DEFINE_CLOCK(rtc_clk,    0, CCM_CGR2,  0, get_rate_ipg, NULL);
 391DEFINE_CLOCK(rtic_clk,   0, CCM_CGR2,  2, get_rate_ahb, NULL);
 392DEFINE_CLOCK(scc_clk,    0, CCM_CGR2,  4, get_rate_ipg, NULL);
 393DEFINE_CLOCK(sdma_clk,   0, CCM_CGR2,  6, NULL, NULL);
 394DEFINE_CLOCK(spba_clk,   0, CCM_CGR2,  8, get_rate_ipg, NULL);
 395DEFINE_CLOCK(spdif_clk,  0, CCM_CGR2, 10, NULL, NULL);
 396DEFINE_CLOCK(ssi1_clk,   0, CCM_CGR2, 12, get_rate_ssi, NULL);
 397DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
 398DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
 399DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
 400DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
 401DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
 402DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
 403DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
 404DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
 405
 406DEFINE_CLOCK(csi_clk,    0, CCM_CGR3,  0, get_rate_csi, NULL);
 407DEFINE_CLOCK(iim_clk,    0, CCM_CGR3,  2, NULL, NULL);
 408DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4, NULL, NULL);
 409
 410DEFINE_CLOCK(usbahb_clk, 0, 0,         0, get_rate_ahb, NULL);
 411
 412static int clk_dummy_enable(struct clk *clk)
 413{
 414        return 0;
 415}
 416
 417static void clk_dummy_disable(struct clk *clk)
 418{
 419}
 420
 421static unsigned long get_rate_nfc(struct clk *clk)
 422{
 423        unsigned long div1;
 424
 425        div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
 426
 427        return get_rate_ahb(NULL) / div1;
 428}
 429
 430/* NAND Controller: It seems it can't be disabled */
 431static struct clk nfc_clk = {
 432        .id             = 0,
 433        .enable_reg     = 0,
 434        .enable_shift   = 0,
 435        .get_rate       = get_rate_nfc,
 436        .set_rate       = NULL, /* set_rate_nfc, */
 437        .enable         = clk_dummy_enable,
 438        .disable        = clk_dummy_disable
 439};
 440
 441#define _REGISTER_CLOCK(d, n, c)        \
 442        {                               \
 443                .dev_id = d,            \
 444                .con_id = n,            \
 445                .clk = &c,              \
 446        },
 447
 448static struct clk_lookup lookups[] = {
 449        _REGISTER_CLOCK(NULL, "asrc", asrc_clk)
 450        _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
 451        _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
 452        _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
 453        _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
 454        _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
 455        _REGISTER_CLOCK(NULL, "ect", ect_clk)
 456        _REGISTER_CLOCK(NULL, "edio", edio_clk)
 457        _REGISTER_CLOCK(NULL, "emi", emi_clk)
 458        _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
 459        _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
 460        _REGISTER_CLOCK(NULL, "esai", esai_clk)
 461        _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk)
 462        _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk)
 463        _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk)
 464        /* i.mx35 has the i.mx27 type fec */
 465        _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
 466        _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
 467        _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
 468        _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
 469        _REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
 470        _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
 471        _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
 472        _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
 473        _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
 474        _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
 475        _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
 476        _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
 477        _REGISTER_CLOCK(NULL, "mlb", mlb_clk)
 478        _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
 479        _REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
 480        _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
 481        _REGISTER_CLOCK(NULL, "rngc", rngc_clk)
 482        _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
 483        _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
 484        _REGISTER_CLOCK(NULL, "scc", scc_clk)
 485        _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
 486        _REGISTER_CLOCK(NULL, "spba", spba_clk)
 487        _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
 488        _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
 489        _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
 490        /* i.mx35 has the i.mx21 type uart */
 491        _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
 492        _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
 493        _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
 494        _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
 495        _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
 496        _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
 497        _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
 498        _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
 499        _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
 500        _REGISTER_CLOCK(NULL, "max", max_clk)
 501        _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
 502        _REGISTER_CLOCK(NULL, "csi", csi_clk)
 503        _REGISTER_CLOCK(NULL, "iim", iim_clk)
 504        _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
 505        _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
 506};
 507
 508int __init mx35_clocks_init()
 509{
 510        unsigned int cgr2 = 3 << 26;
 511
 512#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
 513        cgr2 |= 3 << 16;
 514#endif
 515
 516        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 517
 518        /* Turn off all clocks except the ones we need to survive, namely:
 519         * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
 520         */
 521        __raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
 522        __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
 523                        CCM_BASE + CCM_CGR1);
 524        __raw_writel(cgr2, CCM_BASE + CCM_CGR2);
 525        __raw_writel(0, CCM_BASE + CCM_CGR3);
 526
 527        clk_enable(&iim_clk);
 528        imx_print_silicon_rev("i.MX35", mx35_revision());
 529        clk_disable(&iim_clk);
 530
 531        /*
 532         * Check if we came up in internal boot mode. If yes, we need some
 533         * extra clocks turned on, otherwise the MX35 boot ROM code will
 534         * hang after a watchdog reset.
 535         */
 536        if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) {
 537                /* Additionally turn on UART1, SCC, and IIM clocks */
 538                clk_enable(&iim_clk);
 539                clk_enable(&uart1_clk);
 540                clk_enable(&scc_clk);
 541        }
 542
 543#ifdef CONFIG_MXC_USE_EPIT
 544        epit_timer_init(&epit1_clk,
 545                        MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
 546#else
 547        mxc_timer_init(&gpt_clk,
 548                        MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
 549#endif
 550
 551        return 0;
 552}
 553
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.