linux/arch/arm/mach-shmobile/clock-r8a7740.c
<<
>>
Prefs
   1/*
   2 * R8A7740 processor support
   3 *
   4 * Copyright (C) 2011  Renesas Solutions Corp.
   5 * Copyright (C) 2011  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
   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
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20#include <linux/init.h>
  21#include <linux/kernel.h>
  22#include <linux/io.h>
  23#include <linux/sh_clk.h>
  24#include <linux/clkdev.h>
  25#include <mach/clock.h>
  26#include <mach/common.h>
  27#include <mach/r8a7740.h>
  28
  29/*
  30 *        |  MDx  |  XTAL1/EXTAL1   |  System   | EXTALR |
  31 *  Clock |-------+-----------------+  clock    | 32.768 |   RCLK
  32 *  Mode  | 2/1/0 | src         MHz |  source   |  KHz   |  source
  33 * -------+-------+-----------------+-----------+--------+----------
  34 *    0   | 0 0 0 | External  20~50 | XTAL1     |    O   |  EXTALR
  35 *    1   | 0 0 1 | Crystal   20~30 | XTAL1     |    O   |  EXTALR
  36 *    2   | 0 1 0 | External  40~50 | XTAL1 / 2 |    O   |  EXTALR
  37 *    3   | 0 1 1 | Crystal   40~50 | XTAL1 / 2 |    O   |  EXTALR
  38 *    4   | 1 0 0 | External  20~50 | XTAL1     |    x   |  XTAL1 / 1024
  39 *    5   | 1 0 1 | Crystal   20~30 | XTAL1     |    x   |  XTAL1 / 1024
  40 *    6   | 1 1 0 | External  40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
  41 *    7   | 1 1 1 | Crystal   40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
  42 */
  43
  44/* CPG registers */
  45#define FRQCRA          IOMEM(0xe6150000)
  46#define FRQCRB          IOMEM(0xe6150004)
  47#define VCLKCR1         IOMEM(0xE6150008)
  48#define VCLKCR2         IOMEM(0xE615000c)
  49#define FRQCRC          IOMEM(0xe61500e0)
  50#define FSIACKCR        IOMEM(0xe6150018)
  51#define PLLC01CR        IOMEM(0xe6150028)
  52
  53#define SUBCKCR         IOMEM(0xe6150080)
  54#define USBCKCR         IOMEM(0xe615008c)
  55
  56#define MSTPSR0         IOMEM(0xe6150030)
  57#define MSTPSR1         IOMEM(0xe6150038)
  58#define MSTPSR2         IOMEM(0xe6150040)
  59#define MSTPSR3         IOMEM(0xe6150048)
  60#define MSTPSR4         IOMEM(0xe615004c)
  61#define FSIBCKCR        IOMEM(0xe6150090)
  62#define HDMICKCR        IOMEM(0xe6150094)
  63#define SMSTPCR0        IOMEM(0xe6150130)
  64#define SMSTPCR1        IOMEM(0xe6150134)
  65#define SMSTPCR2        IOMEM(0xe6150138)
  66#define SMSTPCR3        IOMEM(0xe615013c)
  67#define SMSTPCR4        IOMEM(0xe6150140)
  68
  69#define FSIDIVA         IOMEM(0xFE1F8000)
  70#define FSIDIVB         IOMEM(0xFE1F8008)
  71
  72/* Fixed 32 KHz root clock from EXTALR pin */
  73static struct clk extalr_clk = {
  74        .rate   = 32768,
  75};
  76
  77/*
  78 * 25MHz default rate for the EXTAL1 root input clock.
  79 * If needed, reset this with clk_set_rate() from the platform code.
  80 */
  81static struct clk extal1_clk = {
  82        .rate   = 25000000,
  83};
  84
  85/*
  86 * 48MHz default rate for the EXTAL2 root input clock.
  87 * If needed, reset this with clk_set_rate() from the platform code.
  88 */
  89static struct clk extal2_clk = {
  90        .rate   = 48000000,
  91};
  92
  93/*
  94 * 27MHz default rate for the DV_CLKI root input clock.
  95 * If needed, reset this with clk_set_rate() from the platform code.
  96 */
  97static struct clk dv_clk = {
  98        .rate   = 27000000,
  99};
 100
 101SH_CLK_RATIO(div2,      1, 2);
 102SH_CLK_RATIO(div1k,     1, 1024);
 103
 104SH_FIXED_RATIO_CLK(extal1_div2_clk,     extal1_clk,             div2);
 105SH_FIXED_RATIO_CLK(extal1_div1024_clk,  extal1_clk,             div1k);
 106SH_FIXED_RATIO_CLK(extal1_div2048_clk,  extal1_div2_clk,        div1k);
 107SH_FIXED_RATIO_CLK(extal2_div2_clk,     extal2_clk,             div2);
 108
 109static struct sh_clk_ops followparent_clk_ops = {
 110        .recalc = followparent_recalc,
 111};
 112
 113/* Main clock */
 114static struct clk system_clk = {
 115        .ops    = &followparent_clk_ops,
 116};
 117
 118SH_FIXED_RATIO_CLK(system_div2_clk, system_clk, div2);
 119
 120/* r_clk */
 121static struct clk r_clk = {
 122        .ops    = &followparent_clk_ops,
 123};
 124
 125/* PLLC0/PLLC1 */
 126static unsigned long pllc01_recalc(struct clk *clk)
 127{
 128        unsigned long mult = 1;
 129
 130        if (__raw_readl(PLLC01CR) & (1 << 14))
 131                mult = ((__raw_readl(clk->enable_reg) >> 24) & 0x7f) + 1;
 132
 133        return clk->parent->rate * mult;
 134}
 135
 136static struct sh_clk_ops pllc01_clk_ops = {
 137        .recalc         = pllc01_recalc,
 138};
 139
 140static struct clk pllc0_clk = {
 141        .ops            = &pllc01_clk_ops,
 142        .flags          = CLK_ENABLE_ON_INIT,
 143        .parent         = &system_clk,
 144        .enable_reg     = (void __iomem *)FRQCRC,
 145};
 146
 147static struct clk pllc1_clk = {
 148        .ops            = &pllc01_clk_ops,
 149        .flags          = CLK_ENABLE_ON_INIT,
 150        .parent         = &system_div2_clk,
 151        .enable_reg     = (void __iomem *)FRQCRA,
 152};
 153
 154/* PLLC1 / 2 */
 155SH_FIXED_RATIO_CLK(pllc1_div2_clk, pllc1_clk, div2);
 156
 157/* USB clock */
 158/*
 159 * USBCKCR is controlling usb24 clock
 160 * bit[7] : parent clock
 161 * bit[6] : clock divide rate
 162 * And this bit[7] is used as a "usb24s" from other devices.
 163 * (Video clock / Sub clock / SPU clock)
 164 * You can controll this clock as a below.
 165 *
 166 * struct clk *usb24    = clk_get(dev,  "usb24");
 167 * struct clk *usb24s   = clk_get(NULL, "usb24s");
 168 * struct clk *system   = clk_get(NULL, "system_clk");
 169 * int rate = clk_get_rate(system);
 170 *
 171 * clk_set_parent(usb24s, system);  // for bit[7]
 172 * clk_set_rate(usb24, rate / 2);   // for bit[6]
 173 */
 174static struct clk *usb24s_parents[] = {
 175        [0] = &system_clk,
 176        [1] = &extal2_clk
 177};
 178
 179static int usb24s_enable(struct clk *clk)
 180{
 181        __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
 182
 183        return 0;
 184}
 185
 186static void usb24s_disable(struct clk *clk)
 187{
 188        __raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
 189}
 190
 191static int usb24s_set_parent(struct clk *clk, struct clk *parent)
 192{
 193        int i, ret;
 194        u32 val;
 195
 196        if (!clk->parent_table || !clk->parent_num)
 197                return -EINVAL;
 198
 199        /* Search the parent */
 200        for (i = 0; i < clk->parent_num; i++)
 201                if (clk->parent_table[i] == parent)
 202                        break;
 203
 204        if (i == clk->parent_num)
 205                return -ENODEV;
 206
 207        ret = clk_reparent(clk, parent);
 208        if (ret < 0)
 209                return ret;
 210
 211        val = __raw_readl(USBCKCR);
 212        val &= ~(1 << 7);
 213        val |= i << 7;
 214        __raw_writel(val, USBCKCR);
 215
 216        return 0;
 217}
 218
 219static struct sh_clk_ops usb24s_clk_ops = {
 220        .recalc         = followparent_recalc,
 221        .enable         = usb24s_enable,
 222        .disable        = usb24s_disable,
 223        .set_parent     = usb24s_set_parent,
 224};
 225
 226static struct clk usb24s_clk = {
 227        .ops            = &usb24s_clk_ops,
 228        .parent_table   = usb24s_parents,
 229        .parent_num     = ARRAY_SIZE(usb24s_parents),
 230        .parent         = &system_clk,
 231};
 232
 233static unsigned long usb24_recalc(struct clk *clk)
 234{
 235        return clk->parent->rate /
 236                ((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
 237};
 238
 239static int usb24_set_rate(struct clk *clk, unsigned long rate)
 240{
 241        u32 val;
 242
 243        /* closer to which ? parent->rate or parent->rate/2 */
 244        val = __raw_readl(USBCKCR);
 245        val &= ~(1 << 6);
 246        val |= (rate > (clk->parent->rate / 4) * 3) << 6;
 247        __raw_writel(val, USBCKCR);
 248
 249        return 0;
 250}
 251
 252static struct sh_clk_ops usb24_clk_ops = {
 253        .recalc         = usb24_recalc,
 254        .set_rate       = usb24_set_rate,
 255};
 256
 257static struct clk usb24_clk = {
 258        .ops            = &usb24_clk_ops,
 259        .parent         = &usb24s_clk,
 260};
 261
 262/* External FSIACK/FSIBCK clock */
 263static struct clk fsiack_clk = {
 264};
 265
 266static struct clk fsibck_clk = {
 267};
 268
 269struct clk *main_clks[] = {
 270        &extalr_clk,
 271        &extal1_clk,
 272        &extal2_clk,
 273        &extal1_div2_clk,
 274        &extal1_div1024_clk,
 275        &extal1_div2048_clk,
 276        &extal2_div2_clk,
 277        &dv_clk,
 278        &system_clk,
 279        &system_div2_clk,
 280        &r_clk,
 281        &pllc0_clk,
 282        &pllc1_clk,
 283        &pllc1_div2_clk,
 284        &usb24s_clk,
 285        &usb24_clk,
 286        &fsiack_clk,
 287        &fsibck_clk,
 288};
 289
 290/* DIV4 clocks */
 291static void div4_kick(struct clk *clk)
 292{
 293        unsigned long value;
 294
 295        /* set KICK bit in FRQCRB to update hardware setting */
 296        value = __raw_readl(FRQCRB);
 297        value |= (1 << 31);
 298        __raw_writel(value, FRQCRB);
 299}
 300
 301static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
 302                          24, 32, 36, 48, 0, 72, 96, 0 };
 303
 304static struct clk_div_mult_table div4_div_mult_table = {
 305        .divisors = divisors,
 306        .nr_divisors = ARRAY_SIZE(divisors),
 307};
 308
 309static struct clk_div4_table div4_table = {
 310        .div_mult_table = &div4_div_mult_table,
 311        .kick = div4_kick,
 312};
 313
 314enum {
 315        DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
 316        DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
 317        DIV4_NR
 318};
 319
 320struct clk div4_clks[DIV4_NR] = {
 321        [DIV4_I]        = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
 322        [DIV4_ZG]       = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
 323        [DIV4_B]        = SH_CLK_DIV4(&pllc1_clk, FRQCRA,  8, 0x6fff, CLK_ENABLE_ON_INIT),
 324        [DIV4_M1]       = SH_CLK_DIV4(&pllc1_clk, FRQCRA,  4, 0x6fff, CLK_ENABLE_ON_INIT),
 325        [DIV4_HP]       = SH_CLK_DIV4(&pllc1_clk, FRQCRB,  4, 0x6fff, 0),
 326        [DIV4_HPP]      = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
 327        [DIV4_USBP]     = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
 328        [DIV4_S]        = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
 329        [DIV4_ZB]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  8, 0x6fff, 0),
 330        [DIV4_M3]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  4, 0x6fff, 0),
 331        [DIV4_CP]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  0, 0x6fff, 0),
 332};
 333
 334/* DIV6 reparent */
 335enum {
 336        DIV6_HDMI,
 337        DIV6_VCLK1, DIV6_VCLK2,
 338        DIV6_FSIA, DIV6_FSIB,
 339        DIV6_REPARENT_NR,
 340};
 341
 342static struct clk *hdmi_parent[] = {
 343        [0] = &pllc1_div2_clk,
 344        [1] = &system_clk,
 345        [2] = &dv_clk
 346};
 347
 348static struct clk *vclk_parents[8] = {
 349        [0] = &pllc1_div2_clk,
 350        [2] = &dv_clk,
 351        [3] = &usb24s_clk,
 352        [4] = &extal1_div2_clk,
 353        [5] = &extalr_clk,
 354};
 355
 356static struct clk *fsia_parents[] = {
 357        [0] = &pllc1_div2_clk,
 358        [1] = &fsiack_clk, /* external clock */
 359};
 360
 361static struct clk *fsib_parents[] = {
 362        [0] = &pllc1_div2_clk,
 363        [1] = &fsibck_clk, /* external clock */
 364};
 365
 366static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
 367        [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
 368                                      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
 369        [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
 370                                       vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
 371        [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
 372                                       vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
 373        [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
 374                                      fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
 375        [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
 376                                      fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
 377};
 378
 379/* DIV6 clocks */
 380enum {
 381        DIV6_SUB,
 382        DIV6_NR
 383};
 384
 385static struct clk div6_clks[DIV6_NR] = {
 386        [DIV6_SUB]      = SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
 387};
 388
 389/* HDMI1/2 clock */
 390static unsigned long hdmi12_recalc(struct clk *clk)
 391{
 392        u32 val = __raw_readl(HDMICKCR);
 393        int shift = (int)clk->priv;
 394
 395        val >>= shift;
 396        val &= 0x3;
 397
 398        return clk->parent->rate / (1 << val);
 399};
 400
 401static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
 402{
 403        u32 val, mask;
 404        int i, shift;
 405
 406        for (i = 0; i < 3; i++)
 407                if (rate == clk->parent->rate / (1 << i))
 408                        goto find;
 409        return -ENODEV;
 410
 411find:
 412        shift = (int)clk->priv;
 413
 414        val = __raw_readl(HDMICKCR);
 415        mask = ~(0x3 << shift);
 416        val = (val & mask) | i << shift;
 417        __raw_writel(val, HDMICKCR);
 418
 419        return 0;
 420};
 421
 422static struct sh_clk_ops hdmi12_clk_ops = {
 423        .recalc         = hdmi12_recalc,
 424        .set_rate       = hdmi12_set_rate,
 425};
 426
 427static struct clk hdmi1_clk = {
 428        .ops            = &hdmi12_clk_ops,
 429        .priv           = (void *)9,
 430        .parent         = &div6_reparent_clks[DIV6_HDMI],  /* late install */
 431};
 432
 433static struct clk hdmi2_clk = {
 434        .ops            = &hdmi12_clk_ops,
 435        .priv           = (void *)11,
 436        .parent         = &div6_reparent_clks[DIV6_HDMI], /* late install */
 437};
 438
 439static struct clk *late_main_clks[] = {
 440        &hdmi1_clk,
 441        &hdmi2_clk,
 442};
 443
 444/* FSI DIV */
 445enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
 446
 447static struct clk fsidivs[] = {
 448        [FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
 449        [FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
 450};
 451
 452/* MSTP */
 453enum {
 454        MSTP128, MSTP127, MSTP125,
 455        MSTP116, MSTP111, MSTP100, MSTP117,
 456
 457        MSTP230,
 458        MSTP222,
 459        MSTP218, MSTP217, MSTP216, MSTP214,
 460        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 461
 462        MSTP329, MSTP328, MSTP323, MSTP320,
 463        MSTP314, MSTP313, MSTP312,
 464        MSTP309,
 465
 466        MSTP416, MSTP415, MSTP407, MSTP406,
 467
 468        MSTP_NR
 469};
 470
 471static struct clk mstp_clks[MSTP_NR] = {
 472        [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S],   SMSTPCR1, 28, 0), /* CEU21 */
 473        [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S],   SMSTPCR1, 27, 0), /* CEU20 */
 474        [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 475        [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1, 17, 0), /* LCDC1 */
 476        [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
 477        [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
 478        [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1,  0, 0), /* LCDC0 */
 479
 480        [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
 481        [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
 482        [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 18, 0), /* DMAC1 */
 483        [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 17, 0), /* DMAC2 */
 484        [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 16, 0), /* DMAC3 */
 485        [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 14, 0), /* USBDMAC */
 486        [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  7, 0), /* SCIFA5 */
 487        [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  6, 0), /* SCIFB */
 488        [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  4, 0), /* SCIFA0 */
 489        [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  3, 0), /* SCIFA1 */
 490        [MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  2, 0), /* SCIFA2 */
 491        [MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  1, 0), /* SCIFA3 */
 492        [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  0, 0), /* SCIFA4 */
 493
 494        [MSTP329] = SH_CLK_MSTP32(&r_clk,               SMSTPCR3, 29, 0), /* CMT10 */
 495        [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 28, 0), /* FSI */
 496        [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
 497        [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 20, 0), /* USBF */
 498        [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 14, 0), /* SDHI0 */
 499        [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 13, 0), /* SDHI1 */
 500        [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 12, 0), /* MMC */
 501        [MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3,  9, 0), /* GEther */
 502
 503        [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4, 16, 0), /* USBHOST */
 504        [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4, 15, 0), /* SDHI2 */
 505        [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4,  7, 0), /* USB-Func */
 506        [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4,  6, 0), /* USB Phy */
 507};
 508
 509static struct clk_lookup lookups[] = {
 510        /* main clocks */
 511        CLKDEV_CON_ID("extalr",                 &extalr_clk),
 512        CLKDEV_CON_ID("extal1",                 &extal1_clk),
 513        CLKDEV_CON_ID("extal2",                 &extal2_clk),
 514        CLKDEV_CON_ID("extal1_div2",            &extal1_div2_clk),
 515        CLKDEV_CON_ID("extal1_div1024",         &extal1_div1024_clk),
 516        CLKDEV_CON_ID("extal1_div2048",         &extal1_div2048_clk),
 517        CLKDEV_CON_ID("extal2_div2",            &extal2_div2_clk),
 518        CLKDEV_CON_ID("dv_clk",                 &dv_clk),
 519        CLKDEV_CON_ID("system_clk",             &system_clk),
 520        CLKDEV_CON_ID("system_div2_clk",        &system_div2_clk),
 521        CLKDEV_CON_ID("r_clk",                  &r_clk),
 522        CLKDEV_CON_ID("pllc0_clk",              &pllc0_clk),
 523        CLKDEV_CON_ID("pllc1_clk",              &pllc1_clk),
 524        CLKDEV_CON_ID("pllc1_div2_clk",         &pllc1_div2_clk),
 525        CLKDEV_CON_ID("usb24s",                 &usb24s_clk),
 526        CLKDEV_CON_ID("hdmi1",                  &hdmi1_clk),
 527        CLKDEV_CON_ID("hdmi2",                  &hdmi2_clk),
 528        CLKDEV_CON_ID("video1",                 &div6_reparent_clks[DIV6_VCLK1]),
 529        CLKDEV_CON_ID("video2",                 &div6_reparent_clks[DIV6_VCLK2]),
 530        CLKDEV_CON_ID("fsiack",                 &fsiack_clk),
 531        CLKDEV_CON_ID("fsibck",                 &fsibck_clk),
 532
 533        /* DIV4 clocks */
 534        CLKDEV_CON_ID("i_clk",                  &div4_clks[DIV4_I]),
 535        CLKDEV_CON_ID("zg_clk",                 &div4_clks[DIV4_ZG]),
 536        CLKDEV_CON_ID("b_clk",                  &div4_clks[DIV4_B]),
 537        CLKDEV_CON_ID("m1_clk",                 &div4_clks[DIV4_M1]),
 538        CLKDEV_CON_ID("hp_clk",                 &div4_clks[DIV4_HP]),
 539        CLKDEV_CON_ID("hpp_clk",                &div4_clks[DIV4_HPP]),
 540        CLKDEV_CON_ID("s_clk",                  &div4_clks[DIV4_S]),
 541        CLKDEV_CON_ID("zb_clk",                 &div4_clks[DIV4_ZB]),
 542        CLKDEV_CON_ID("m3_clk",                 &div4_clks[DIV4_M3]),
 543        CLKDEV_CON_ID("cp_clk",                 &div4_clks[DIV4_CP]),
 544
 545        /* DIV6 clocks */
 546        CLKDEV_CON_ID("sub_clk",                &div6_clks[DIV6_SUB]),
 547
 548        /* MSTP32 clocks */
 549        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0",    &mstp_clks[MSTP100]),
 550        CLKDEV_DEV_ID("sh_tmu.3",               &mstp_clks[MSTP111]),
 551        CLKDEV_DEV_ID("sh_tmu.4",               &mstp_clks[MSTP111]),
 552        CLKDEV_DEV_ID("sh_tmu.5",               &mstp_clks[MSTP111]),
 553        CLKDEV_DEV_ID("i2c-sh_mobile.0",        &mstp_clks[MSTP116]),
 554        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1",    &mstp_clks[MSTP117]),
 555        CLKDEV_DEV_ID("sh_tmu.0",               &mstp_clks[MSTP125]),
 556        CLKDEV_DEV_ID("sh_tmu.1",               &mstp_clks[MSTP125]),
 557        CLKDEV_DEV_ID("sh_tmu.2",               &mstp_clks[MSTP125]),
 558        CLKDEV_DEV_ID("sh_mobile_ceu.0",        &mstp_clks[MSTP127]),
 559        CLKDEV_DEV_ID("sh_mobile_ceu.1",        &mstp_clks[MSTP128]),
 560
 561        CLKDEV_DEV_ID("sh-sci.4",               &mstp_clks[MSTP200]),
 562        CLKDEV_DEV_ID("e6c80000.sci",           &mstp_clks[MSTP200]),
 563        CLKDEV_DEV_ID("sh-sci.3",               &mstp_clks[MSTP201]),
 564        CLKDEV_DEV_ID("e6c70000.sci",           &mstp_clks[MSTP201]),
 565        CLKDEV_DEV_ID("sh-sci.2",               &mstp_clks[MSTP202]),
 566        CLKDEV_DEV_ID("e6c60000.sci",           &mstp_clks[MSTP202]),
 567        CLKDEV_DEV_ID("sh-sci.1",               &mstp_clks[MSTP203]),
 568        CLKDEV_DEV_ID("e6c50000.sci",           &mstp_clks[MSTP203]),
 569        CLKDEV_DEV_ID("sh-sci.0",               &mstp_clks[MSTP204]),
 570        CLKDEV_DEV_ID("e6c40000.sci",           &mstp_clks[MSTP204]),
 571        CLKDEV_DEV_ID("sh-sci.8",               &mstp_clks[MSTP206]),
 572        CLKDEV_DEV_ID("e6c30000.sci",           &mstp_clks[MSTP206]),
 573        CLKDEV_DEV_ID("sh-sci.5",               &mstp_clks[MSTP207]),
 574        CLKDEV_DEV_ID("e6cb0000.sci",           &mstp_clks[MSTP207]),
 575        CLKDEV_DEV_ID("sh-dma-engine.3",        &mstp_clks[MSTP214]),
 576        CLKDEV_DEV_ID("sh-dma-engine.2",        &mstp_clks[MSTP216]),
 577        CLKDEV_DEV_ID("sh-dma-engine.1",        &mstp_clks[MSTP217]),
 578        CLKDEV_DEV_ID("sh-dma-engine.0",        &mstp_clks[MSTP218]),
 579        CLKDEV_DEV_ID("sh-sci.7",               &mstp_clks[MSTP222]),
 580        CLKDEV_DEV_ID("e6cd0000.sci",           &mstp_clks[MSTP222]),
 581        CLKDEV_DEV_ID("sh-sci.6",               &mstp_clks[MSTP230]),
 582        CLKDEV_DEV_ID("e6cc0000.sci",           &mstp_clks[MSTP230]),
 583
 584        CLKDEV_DEV_ID("sh_cmt.10",              &mstp_clks[MSTP329]),
 585        CLKDEV_DEV_ID("sh_fsi2",                &mstp_clks[MSTP328]),
 586        CLKDEV_DEV_ID("i2c-sh_mobile.1",        &mstp_clks[MSTP323]),
 587        CLKDEV_DEV_ID("renesas_usbhs",          &mstp_clks[MSTP320]),
 588        CLKDEV_DEV_ID("sh_mobile_sdhi.0",       &mstp_clks[MSTP314]),
 589        CLKDEV_DEV_ID("e6850000.sdhi",          &mstp_clks[MSTP314]),
 590        CLKDEV_DEV_ID("sh_mobile_sdhi.1",       &mstp_clks[MSTP313]),
 591        CLKDEV_DEV_ID("e6860000.sdhi",          &mstp_clks[MSTP313]),
 592        CLKDEV_DEV_ID("sh_mmcif",               &mstp_clks[MSTP312]),
 593        CLKDEV_DEV_ID("e6bd0000.mmcif",         &mstp_clks[MSTP312]),
 594        CLKDEV_DEV_ID("sh-eth",                 &mstp_clks[MSTP309]),
 595
 596        CLKDEV_DEV_ID("sh_mobile_sdhi.2",       &mstp_clks[MSTP415]),
 597        CLKDEV_DEV_ID("e6870000.sdhi",          &mstp_clks[MSTP415]),
 598
 599        /* ICK */
 600        CLKDEV_ICK_ID("host",   "renesas_usbhs",        &mstp_clks[MSTP416]),
 601        CLKDEV_ICK_ID("func",   "renesas_usbhs",        &mstp_clks[MSTP407]),
 602        CLKDEV_ICK_ID("phy",    "renesas_usbhs",        &mstp_clks[MSTP406]),
 603        CLKDEV_ICK_ID("pci",    "renesas_usbhs",        &div4_clks[DIV4_USBP]),
 604        CLKDEV_ICK_ID("usb24",  "renesas_usbhs",        &usb24_clk),
 605        CLKDEV_ICK_ID("ick",    "sh-mobile-hdmi",       &div6_reparent_clks[DIV6_HDMI]),
 606
 607        CLKDEV_ICK_ID("icka", "sh_fsi2",        &div6_reparent_clks[DIV6_FSIA]),
 608        CLKDEV_ICK_ID("ickb", "sh_fsi2",        &div6_reparent_clks[DIV6_FSIB]),
 609        CLKDEV_ICK_ID("diva", "sh_fsi2",        &fsidivs[FSIDIV_A]),
 610        CLKDEV_ICK_ID("divb", "sh_fsi2",        &fsidivs[FSIDIV_B]),
 611        CLKDEV_ICK_ID("xcka", "sh_fsi2",        &fsiack_clk),
 612        CLKDEV_ICK_ID("xckb", "sh_fsi2",        &fsibck_clk),
 613};
 614
 615void __init r8a7740_clock_init(u8 md_ck)
 616{
 617        int k, ret = 0;
 618
 619        /* detect system clock parent */
 620        if (md_ck & MD_CK1)
 621                system_clk.parent = &extal1_div2_clk;
 622        else
 623                system_clk.parent = &extal1_clk;
 624
 625        /* detect RCLK parent */
 626        switch (md_ck & (MD_CK2 | MD_CK1)) {
 627        case MD_CK2 | MD_CK1:
 628                r_clk.parent = &extal1_div2048_clk;
 629                break;
 630        case MD_CK2:
 631                r_clk.parent = &extal1_div1024_clk;
 632                break;
 633        case MD_CK1:
 634        default:
 635                r_clk.parent = &extalr_clk;
 636                break;
 637        }
 638
 639        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 640                ret = clk_register(main_clks[k]);
 641
 642        if (!ret)
 643                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 644
 645        if (!ret)
 646                ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 647
 648        if (!ret)
 649                ret = sh_clk_div6_reparent_register(div6_reparent_clks,
 650                                                    DIV6_REPARENT_NR);
 651
 652        if (!ret)
 653                ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 654
 655        for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
 656                ret = clk_register(late_main_clks[k]);
 657
 658        if (!ret)
 659                ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
 660
 661        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 662
 663        if (!ret)
 664                shmobile_clk_init();
 665        else
 666                panic("failed to setup r8a7740 clocks\n");
 667}
 668