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