linux/arch/arm/mach-shmobile/clock-sh73a0.c
<<
>>
Prefs
   1/*
   2 * sh73a0 clock framework support
   3 *
   4 * Copyright (C) 2010 Magnus Damm
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 */
  19#include <linux/init.h>
  20#include <linux/kernel.h>
  21#include <linux/io.h>
  22#include <linux/sh_clk.h>
  23#include <linux/clkdev.h>
  24#include <mach/common.h>
  25
  26#define FRQCRA          IOMEM(0xe6150000)
  27#define FRQCRB          IOMEM(0xe6150004)
  28#define FRQCRD          IOMEM(0xe61500e4)
  29#define VCLKCR1         IOMEM(0xe6150008)
  30#define VCLKCR2         IOMEM(0xe615000C)
  31#define VCLKCR3         IOMEM(0xe615001C)
  32#define ZBCKCR          IOMEM(0xe6150010)
  33#define FLCKCR          IOMEM(0xe6150014)
  34#define SD0CKCR         IOMEM(0xe6150074)
  35#define SD1CKCR         IOMEM(0xe6150078)
  36#define SD2CKCR         IOMEM(0xe615007C)
  37#define FSIACKCR        IOMEM(0xe6150018)
  38#define FSIBCKCR        IOMEM(0xe6150090)
  39#define SUBCKCR         IOMEM(0xe6150080)
  40#define SPUACKCR        IOMEM(0xe6150084)
  41#define SPUVCKCR        IOMEM(0xe6150094)
  42#define MSUCKCR         IOMEM(0xe6150088)
  43#define HSICKCR         IOMEM(0xe615008C)
  44#define MFCK1CR         IOMEM(0xe6150098)
  45#define MFCK2CR         IOMEM(0xe615009C)
  46#define DSITCKCR        IOMEM(0xe6150060)
  47#define DSI0PCKCR       IOMEM(0xe6150064)
  48#define DSI1PCKCR       IOMEM(0xe6150068)
  49#define DSI0PHYCR       0xe615006C
  50#define DSI1PHYCR       0xe6150070
  51#define PLLECR          IOMEM(0xe61500d0)
  52#define PLL0CR          IOMEM(0xe61500d8)
  53#define PLL1CR          IOMEM(0xe6150028)
  54#define PLL2CR          IOMEM(0xe615002c)
  55#define PLL3CR          IOMEM(0xe61500dc)
  56#define SMSTPCR0        IOMEM(0xe6150130)
  57#define SMSTPCR1        IOMEM(0xe6150134)
  58#define SMSTPCR2        IOMEM(0xe6150138)
  59#define SMSTPCR3        IOMEM(0xe615013c)
  60#define SMSTPCR4        IOMEM(0xe6150140)
  61#define SMSTPCR5        IOMEM(0xe6150144)
  62#define CKSCR           IOMEM(0xe61500c0)
  63
  64/* Fixed 32 KHz root clock from EXTALR pin */
  65static struct clk r_clk = {
  66        .rate           = 32768,
  67};
  68
  69/*
  70 * 26MHz default rate for the EXTAL1 root input clock.
  71 * If needed, reset this with clk_set_rate() from the platform code.
  72 */
  73struct clk sh73a0_extal1_clk = {
  74        .rate           = 26000000,
  75};
  76
  77/*
  78 * 48MHz default rate for the EXTAL2 root input clock.
  79 * If needed, reset this with clk_set_rate() from the platform code.
  80 */
  81struct clk sh73a0_extal2_clk = {
  82        .rate           = 48000000,
  83};
  84
  85/* A fixed divide-by-2 block */
  86static unsigned long div2_recalc(struct clk *clk)
  87{
  88        return clk->parent->rate / 2;
  89}
  90
  91static struct sh_clk_ops div2_clk_ops = {
  92        .recalc         = div2_recalc,
  93};
  94
  95static unsigned long div7_recalc(struct clk *clk)
  96{
  97        return clk->parent->rate / 7;
  98}
  99
 100static struct sh_clk_ops div7_clk_ops = {
 101        .recalc         = div7_recalc,
 102};
 103
 104static unsigned long div13_recalc(struct clk *clk)
 105{
 106        return clk->parent->rate / 13;
 107}
 108
 109static struct sh_clk_ops div13_clk_ops = {
 110        .recalc         = div13_recalc,
 111};
 112
 113/* Divide extal1 by two */
 114static struct clk extal1_div2_clk = {
 115        .ops            = &div2_clk_ops,
 116        .parent         = &sh73a0_extal1_clk,
 117};
 118
 119/* Divide extal2 by two */
 120static struct clk extal2_div2_clk = {
 121        .ops            = &div2_clk_ops,
 122        .parent         = &sh73a0_extal2_clk,
 123};
 124
 125static struct sh_clk_ops main_clk_ops = {
 126        .recalc         = followparent_recalc,
 127};
 128
 129/* Main clock */
 130static struct clk main_clk = {
 131        .ops            = &main_clk_ops,
 132};
 133
 134/* Divide Main clock by two */
 135static struct clk main_div2_clk = {
 136        .ops            = &div2_clk_ops,
 137        .parent         = &main_clk,
 138};
 139
 140/* PLL0, PLL1, PLL2, PLL3 */
 141static unsigned long pll_recalc(struct clk *clk)
 142{
 143        unsigned long mult = 1;
 144
 145        if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
 146                mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
 147                /* handle CFG bit for PLL1 and PLL2 */
 148                switch (clk->enable_bit) {
 149                case 1:
 150                case 2:
 151                        if (__raw_readl(clk->enable_reg) & (1 << 20))
 152                                mult *= 2;
 153                }
 154        }
 155
 156        return clk->parent->rate * mult;
 157}
 158
 159static struct sh_clk_ops pll_clk_ops = {
 160        .recalc         = pll_recalc,
 161};
 162
 163static struct clk pll0_clk = {
 164        .ops            = &pll_clk_ops,
 165        .flags          = CLK_ENABLE_ON_INIT,
 166        .parent         = &main_clk,
 167        .enable_reg     = (void __iomem *)PLL0CR,
 168        .enable_bit     = 0,
 169};
 170
 171static struct clk pll1_clk = {
 172        .ops            = &pll_clk_ops,
 173        .flags          = CLK_ENABLE_ON_INIT,
 174        .parent         = &main_clk,
 175        .enable_reg     = (void __iomem *)PLL1CR,
 176        .enable_bit     = 1,
 177};
 178
 179static struct clk pll2_clk = {
 180        .ops            = &pll_clk_ops,
 181        .flags          = CLK_ENABLE_ON_INIT,
 182        .parent         = &main_clk,
 183        .enable_reg     = (void __iomem *)PLL2CR,
 184        .enable_bit     = 2,
 185};
 186
 187static struct clk pll3_clk = {
 188        .ops            = &pll_clk_ops,
 189        .flags          = CLK_ENABLE_ON_INIT,
 190        .parent         = &main_clk,
 191        .enable_reg     = (void __iomem *)PLL3CR,
 192        .enable_bit     = 3,
 193};
 194
 195/* Divide PLL */
 196static struct clk pll1_div2_clk = {
 197        .ops            = &div2_clk_ops,
 198        .parent         = &pll1_clk,
 199};
 200
 201static struct clk pll1_div7_clk = {
 202        .ops            = &div7_clk_ops,
 203        .parent         = &pll1_clk,
 204};
 205
 206static struct clk pll1_div13_clk = {
 207        .ops            = &div13_clk_ops,
 208        .parent         = &pll1_clk,
 209};
 210
 211/* External input clock */
 212struct clk sh73a0_extcki_clk = {
 213};
 214
 215struct clk sh73a0_extalr_clk = {
 216};
 217
 218static struct clk *main_clks[] = {
 219        &r_clk,
 220        &sh73a0_extal1_clk,
 221        &sh73a0_extal2_clk,
 222        &extal1_div2_clk,
 223        &extal2_div2_clk,
 224        &main_clk,
 225        &main_div2_clk,
 226        &pll0_clk,
 227        &pll1_clk,
 228        &pll2_clk,
 229        &pll3_clk,
 230        &pll1_div2_clk,
 231        &pll1_div7_clk,
 232        &pll1_div13_clk,
 233        &sh73a0_extcki_clk,
 234        &sh73a0_extalr_clk,
 235};
 236
 237static void div4_kick(struct clk *clk)
 238{
 239        unsigned long value;
 240
 241        /* set KICK bit in FRQCRB to update hardware setting */
 242        value = __raw_readl(FRQCRB);
 243        value |= (1 << 31);
 244        __raw_writel(value, FRQCRB);
 245}
 246
 247static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
 248                          24, 0, 36, 48, 7 };
 249
 250static struct clk_div_mult_table div4_div_mult_table = {
 251        .divisors = divisors,
 252        .nr_divisors = ARRAY_SIZE(divisors),
 253};
 254
 255static struct clk_div4_table div4_table = {
 256        .div_mult_table = &div4_div_mult_table,
 257        .kick = div4_kick,
 258};
 259
 260enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
 261        DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
 262
 263#define DIV4(_reg, _bit, _mask, _flags) \
 264        SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
 265
 266static struct clk div4_clks[DIV4_NR] = {
 267        [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
 268        [DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
 269        [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
 270        [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
 271        [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
 272        [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
 273        [DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0),
 274        [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0),
 275        [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0),
 276        [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
 277        [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
 278};
 279
 280enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
 281        DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
 282        DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
 283        DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
 284        DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
 285        DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
 286        DIV6_NR };
 287
 288static struct clk *vck_parent[8] = {
 289        [0] = &pll1_div2_clk,
 290        [1] = &pll2_clk,
 291        [2] = &sh73a0_extcki_clk,
 292        [3] = &sh73a0_extal2_clk,
 293        [4] = &main_div2_clk,
 294        [5] = &sh73a0_extalr_clk,
 295        [6] = &main_clk,
 296};
 297
 298static struct clk *pll_parent[4] = {
 299        [0] = &pll1_div2_clk,
 300        [1] = &pll2_clk,
 301        [2] = &pll1_div13_clk,
 302};
 303
 304static struct clk *hsi_parent[4] = {
 305        [0] = &pll1_div2_clk,
 306        [1] = &pll2_clk,
 307        [2] = &pll1_div7_clk,
 308};
 309
 310static struct clk *pll_extal2_parent[] = {
 311        [0] = &pll1_div2_clk,
 312        [1] = &pll2_clk,
 313        [2] = &sh73a0_extal2_clk,
 314        [3] = &sh73a0_extal2_clk,
 315};
 316
 317static struct clk *dsi_parent[8] = {
 318        [0] = &pll1_div2_clk,
 319        [1] = &pll2_clk,
 320        [2] = &main_clk,
 321        [3] = &sh73a0_extal2_clk,
 322        [4] = &sh73a0_extcki_clk,
 323};
 324
 325static struct clk div6_clks[DIV6_NR] = {
 326        [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
 327                        vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
 328        [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
 329                        vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
 330        [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
 331                        vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
 332        [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
 333                        pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
 334        [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
 335                        pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
 336        [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
 337                        pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
 338        [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
 339                        pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
 340        [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
 341                        pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
 342        [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
 343                        pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
 344        [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
 345                        pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
 346        [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
 347                        pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
 348        [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
 349                        pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
 350        [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
 351                        pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
 352        [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
 353                        pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
 354        [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
 355                        hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
 356        [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
 357                        pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
 358        [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
 359                        pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
 360        [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
 361                        pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
 362        [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
 363                        dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
 364        [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
 365                        dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
 366};
 367
 368/* DSI DIV */
 369static unsigned long dsiphy_recalc(struct clk *clk)
 370{
 371        u32 value;
 372
 373        value = __raw_readl(clk->mapping->base);
 374
 375        /* FIXME */
 376        if (!(value & 0x000B8000))
 377                return clk->parent->rate;
 378
 379        value &= 0x3f;
 380        value += 1;
 381
 382        if ((value < 12) ||
 383            (value > 33)) {
 384                pr_err("DSIPHY has wrong value (%d)", value);
 385                return 0;
 386        }
 387
 388        return clk->parent->rate / value;
 389}
 390
 391static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
 392{
 393        return clk_rate_mult_range_round(clk, 12, 33, rate);
 394}
 395
 396static void dsiphy_disable(struct clk *clk)
 397{
 398        u32 value;
 399
 400        value = __raw_readl(clk->mapping->base);
 401        value &= ~0x000B8000;
 402
 403        __raw_writel(value , clk->mapping->base);
 404}
 405
 406static int dsiphy_enable(struct clk *clk)
 407{
 408        u32 value;
 409        int multi;
 410
 411        value = __raw_readl(clk->mapping->base);
 412        multi = (value & 0x3f) + 1;
 413
 414        if ((multi < 12) || (multi > 33))
 415                return -EIO;
 416
 417        __raw_writel(value | 0x000B8000, clk->mapping->base);
 418
 419        return 0;
 420}
 421
 422static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
 423{
 424        u32 value;
 425        int idx;
 426
 427        idx = rate / clk->parent->rate;
 428        if ((idx < 12) || (idx > 33))
 429                return -EINVAL;
 430
 431        idx += -1;
 432
 433        value = __raw_readl(clk->mapping->base);
 434        value = (value & ~0x3f) + idx;
 435
 436        __raw_writel(value, clk->mapping->base);
 437
 438        return 0;
 439}
 440
 441static struct sh_clk_ops dsiphy_clk_ops = {
 442        .recalc         = dsiphy_recalc,
 443        .round_rate     = dsiphy_round_rate,
 444        .set_rate       = dsiphy_set_rate,
 445        .enable         = dsiphy_enable,
 446        .disable        = dsiphy_disable,
 447};
 448
 449static struct clk_mapping dsi0phy_clk_mapping = {
 450        .phys   = DSI0PHYCR,
 451        .len    = 4,
 452};
 453
 454static struct clk_mapping dsi1phy_clk_mapping = {
 455        .phys   = DSI1PHYCR,
 456        .len    = 4,
 457};
 458
 459static struct clk dsi0phy_clk = {
 460        .ops            = &dsiphy_clk_ops,
 461        .parent         = &div6_clks[DIV6_DSI0P], /* late install */
 462        .mapping        = &dsi0phy_clk_mapping,
 463};
 464
 465static struct clk dsi1phy_clk = {
 466        .ops            = &dsiphy_clk_ops,
 467        .parent         = &div6_clks[DIV6_DSI1P], /* late install */
 468        .mapping        = &dsi1phy_clk_mapping,
 469};
 470
 471static struct clk *late_main_clks[] = {
 472        &dsi0phy_clk,
 473        &dsi1phy_clk,
 474};
 475
 476enum { MSTP001,
 477        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
 478        MSTP219, MSTP218, MSTP217,
 479        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 480        MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
 481        MSTP314, MSTP313, MSTP312, MSTP311,
 482        MSTP303, MSTP302, MSTP301, MSTP300,
 483        MSTP411, MSTP410, MSTP403,
 484        MSTP_NR };
 485
 486#define MSTP(_parent, _reg, _bit, _flags) \
 487        SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
 488
 489static struct clk mstp_clks[MSTP_NR] = {
 490        [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
 491        [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
 492        [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
 493        [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
 494        [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
 495        [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 496        [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
 497        [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
 498        [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
 499        [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
 500        [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
 501        [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
 502        [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
 503        [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
 504        [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
 505        [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
 506        [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
 507        [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
 508        [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
 509        [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
 510        [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
 511        [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
 512        [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
 513        [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
 514        [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
 515        [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
 516        [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
 517        [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
 518        [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
 519        [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
 520        [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
 521        [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
 522        [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
 523        [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
 524        [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
 525        [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
 526};
 527
 528/* The lookups structure below includes duplicate entries for some clocks
 529 * with alternate names.
 530 * - The traditional name used when a device is initialised with platform data
 531 * - The name used when a device is initialised using device tree
 532 * The longer-term aim is to remove these duplicates, and indeed the
 533 * lookups table entirely, by describing clocks using device tree.
 534 */
 535static struct clk_lookup lookups[] = {
 536        /* main clocks */
 537        CLKDEV_CON_ID("r_clk", &r_clk),
 538
 539        /* DIV6 clocks */
 540        CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
 541        CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
 542        CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
 543        CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
 544        CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
 545        CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
 546        CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
 547        CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
 548        CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
 549        CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
 550        CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
 551        CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
 552
 553        /* MSTP32 clocks */
 554        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
 555        CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
 556        CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
 557        CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
 558        CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
 559        CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
 560        CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
 561        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
 562        CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
 563        CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
 564        CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
 565        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
 566        CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
 567        CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
 568        CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
 569        CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
 570        CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
 571        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
 572        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
 573        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
 574        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 575        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 576        CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
 577        CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
 578        CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
 579        CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
 580        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
 581        CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
 582        CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
 583        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
 584        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
 585        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
 586        CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
 587        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
 588        CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
 589        CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
 590        CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
 591        CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
 592        CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
 593        CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
 594        CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
 595        CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
 596        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
 597};
 598
 599void __init sh73a0_clock_init(void)
 600{
 601        int k, ret = 0;
 602
 603        /* Set SDHI clocks to a known state */
 604        __raw_writel(0x108, SD0CKCR);
 605        __raw_writel(0x108, SD1CKCR);
 606        __raw_writel(0x108, SD2CKCR);
 607
 608        /* detect main clock parent */
 609        switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
 610        case 0:
 611                main_clk.parent = &sh73a0_extal1_clk;
 612                break;
 613        case 1:
 614                main_clk.parent = &extal1_div2_clk;
 615                break;
 616        case 2:
 617                main_clk.parent = &sh73a0_extal2_clk;
 618                break;
 619        case 3:
 620                main_clk.parent = &extal2_div2_clk;
 621                break;
 622        }
 623
 624        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 625                ret = clk_register(main_clks[k]);
 626
 627        if (!ret)
 628                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 629
 630        if (!ret)
 631                ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
 632
 633        if (!ret)
 634                ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 635
 636        for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
 637                ret = clk_register(late_main_clks[k]);
 638
 639        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 640
 641        if (!ret)
 642                shmobile_clk_init();
 643        else
 644                panic("failed to setup sh73a0 clocks\n");
 645}
 646