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          0xe6150000
  27#define FRQCRB          0xe6150004
  28#define FRQCRD          0xe61500e4
  29#define VCLKCR1         0xe6150008
  30#define VCLKCR2         0xe615000C
  31#define VCLKCR3         0xe615001C
  32#define ZBCKCR          0xe6150010
  33#define FLCKCR          0xe6150014
  34#define SD0CKCR         0xe6150074
  35#define SD1CKCR         0xe6150078
  36#define SD2CKCR         0xe615007C
  37#define FSIACKCR        0xe6150018
  38#define FSIBCKCR        0xe6150090
  39#define SUBCKCR         0xe6150080
  40#define SPUACKCR        0xe6150084
  41#define SPUVCKCR        0xe6150094
  42#define MSUCKCR         0xe6150088
  43#define HSICKCR         0xe615008C
  44#define MFCK1CR         0xe6150098
  45#define MFCK2CR         0xe615009C
  46#define DSITCKCR        0xe6150060
  47#define DSI0PCKCR       0xe6150064
  48#define DSI1PCKCR       0xe6150068
  49#define DSI0PHYCR       0xe615006C
  50#define DSI1PHYCR       0xe6150070
  51#define PLLECR          0xe61500d0
  52#define PLL0CR          0xe61500d8
  53#define PLL1CR          0xe6150028
  54#define PLL2CR          0xe615002c
  55#define PLL3CR          0xe61500dc
  56#define SMSTPCR0        0xe6150130
  57#define SMSTPCR1        0xe6150134
  58#define SMSTPCR2        0xe6150138
  59#define SMSTPCR3        0xe615013c
  60#define SMSTPCR4        0xe6150140
  61#define SMSTPCR5        0xe6150144
  62#define CKSCR           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 clk_ops div2_clk_ops = {
  92        .recalc         = div2_recalc,
  93};
  94
  95/* Divide extal1 by two */
  96static struct clk extal1_div2_clk = {
  97        .ops            = &div2_clk_ops,
  98        .parent         = &sh73a0_extal1_clk,
  99};
 100
 101/* Divide extal2 by two */
 102static struct clk extal2_div2_clk = {
 103        .ops            = &div2_clk_ops,
 104        .parent         = &sh73a0_extal2_clk,
 105};
 106
 107static struct clk_ops main_clk_ops = {
 108        .recalc         = followparent_recalc,
 109};
 110
 111/* Main clock */
 112static struct clk main_clk = {
 113        .ops            = &main_clk_ops,
 114};
 115
 116/* PLL0, PLL1, PLL2, PLL3 */
 117static unsigned long pll_recalc(struct clk *clk)
 118{
 119        unsigned long mult = 1;
 120
 121        if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
 122                mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
 123                /* handle CFG bit for PLL1 and PLL2 */
 124                switch (clk->enable_bit) {
 125                case 1:
 126                case 2:
 127                        if (__raw_readl(clk->enable_reg) & (1 << 20))
 128                                mult *= 2;
 129                }
 130        }
 131
 132        return clk->parent->rate * mult;
 133}
 134
 135static struct clk_ops pll_clk_ops = {
 136        .recalc         = pll_recalc,
 137};
 138
 139static struct clk pll0_clk = {
 140        .ops            = &pll_clk_ops,
 141        .flags          = CLK_ENABLE_ON_INIT,
 142        .parent         = &main_clk,
 143        .enable_reg     = (void __iomem *)PLL0CR,
 144        .enable_bit     = 0,
 145};
 146
 147static struct clk pll1_clk = {
 148        .ops            = &pll_clk_ops,
 149        .flags          = CLK_ENABLE_ON_INIT,
 150        .parent         = &main_clk,
 151        .enable_reg     = (void __iomem *)PLL1CR,
 152        .enable_bit     = 1,
 153};
 154
 155static struct clk pll2_clk = {
 156        .ops            = &pll_clk_ops,
 157        .flags          = CLK_ENABLE_ON_INIT,
 158        .parent         = &main_clk,
 159        .enable_reg     = (void __iomem *)PLL2CR,
 160        .enable_bit     = 2,
 161};
 162
 163static struct clk pll3_clk = {
 164        .ops            = &pll_clk_ops,
 165        .flags          = CLK_ENABLE_ON_INIT,
 166        .parent         = &main_clk,
 167        .enable_reg     = (void __iomem *)PLL3CR,
 168        .enable_bit     = 3,
 169};
 170
 171/* Divide PLL1 by two */
 172static struct clk pll1_div2_clk = {
 173        .ops            = &div2_clk_ops,
 174        .parent         = &pll1_clk,
 175};
 176
 177static struct clk *main_clks[] = {
 178        &r_clk,
 179        &sh73a0_extal1_clk,
 180        &sh73a0_extal2_clk,
 181        &extal1_div2_clk,
 182        &extal2_div2_clk,
 183        &main_clk,
 184        &pll0_clk,
 185        &pll1_clk,
 186        &pll2_clk,
 187        &pll3_clk,
 188        &pll1_div2_clk,
 189};
 190
 191static void div4_kick(struct clk *clk)
 192{
 193        unsigned long value;
 194
 195        /* set KICK bit in FRQCRB to update hardware setting */
 196        value = __raw_readl(FRQCRB);
 197        value |= (1 << 31);
 198        __raw_writel(value, FRQCRB);
 199}
 200
 201static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
 202                          24, 0, 36, 48, 7 };
 203
 204static struct clk_div_mult_table div4_div_mult_table = {
 205        .divisors = divisors,
 206        .nr_divisors = ARRAY_SIZE(divisors),
 207};
 208
 209static struct clk_div4_table div4_table = {
 210        .div_mult_table = &div4_div_mult_table,
 211        .kick = div4_kick,
 212};
 213
 214enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
 215        DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
 216
 217#define DIV4(_reg, _bit, _mask, _flags) \
 218        SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
 219
 220static struct clk div4_clks[DIV4_NR] = {
 221        [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
 222        [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
 223        [DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
 224        [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
 225        [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
 226        [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
 227        [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
 228        [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
 229        [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
 230        [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
 231        [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
 232};
 233
 234enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
 235        DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
 236        DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
 237        DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
 238        DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
 239        DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
 240        DIV6_NR };
 241
 242static struct clk div6_clks[DIV6_NR] = {
 243        [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
 244        [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
 245        [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
 246        [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
 247        [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
 248        [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
 249        [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
 250        [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
 251        [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
 252        [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
 253        [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
 254        [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
 255        [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
 256        [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
 257        [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
 258        [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
 259        [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
 260        [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
 261        [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
 262        [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
 263};
 264
 265enum { MSTP001,
 266        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
 267        MSTP219,
 268        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 269        MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
 270        MSTP314, MSTP313, MSTP312, MSTP311,
 271        MSTP411, MSTP410, MSTP403,
 272        MSTP_NR };
 273
 274#define MSTP(_parent, _reg, _bit, _flags) \
 275        SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
 276
 277static struct clk mstp_clks[MSTP_NR] = {
 278        [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
 279        [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
 280        [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
 281        [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
 282        [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
 283        [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 284        [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
 285        [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
 286        [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
 287        [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
 288        [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
 289        [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
 290        [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
 291        [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
 292        [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
 293        [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
 294        [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
 295        [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
 296        [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
 297        [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
 298        [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
 299        [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
 300        [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
 301        [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
 302        [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
 303        [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
 304        [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
 305        [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
 306        [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
 307};
 308
 309#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 310#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
 311#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
 312
 313static struct clk_lookup lookups[] = {
 314        /* main clocks */
 315        CLKDEV_CON_ID("r_clk", &r_clk),
 316
 317        /* DIV6 clocks */
 318        CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
 319        CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
 320        CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
 321        CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
 322        CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
 323        CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
 324        CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
 325        CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
 326        CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
 327        CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
 328
 329        /* MSTP32 clocks */
 330        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
 331        CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
 332        CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
 333        CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
 334        CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
 335        CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
 336        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
 337        CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
 338        CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
 339        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
 340        CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
 341        CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
 342        CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
 343        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
 344        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
 345        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
 346        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 347        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 348        CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
 349        CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
 350        CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
 351        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
 352        CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
 353        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
 354        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
 355        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
 356        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
 357        CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
 358        CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
 359        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
 360};
 361
 362void __init sh73a0_clock_init(void)
 363{
 364        int k, ret = 0;
 365
 366        /* Set SDHI clocks to a known state */
 367        __raw_writel(0x108, SD0CKCR);
 368        __raw_writel(0x108, SD1CKCR);
 369        __raw_writel(0x108, SD2CKCR);
 370
 371        /* detect main clock parent */
 372        switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
 373        case 0:
 374                main_clk.parent = &sh73a0_extal1_clk;
 375                break;
 376        case 1:
 377                main_clk.parent = &extal1_div2_clk;
 378                break;
 379        case 2:
 380                main_clk.parent = &sh73a0_extal2_clk;
 381                break;
 382        case 3:
 383                main_clk.parent = &extal2_div2_clk;
 384                break;
 385        }
 386
 387        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 388                ret = clk_register(main_clks[k]);
 389
 390        if (!ret)
 391                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 392
 393        if (!ret)
 394                ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 395
 396        if (!ret)
 397                ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 398
 399        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 400
 401        if (!ret)
 402                clk_init();
 403        else
 404                panic("failed to setup sh73a0 clocks\n");
 405}
 406