linux/arch/sh/kernel/cpu/sh4a/clock-shx3.c
<<
>>
Prefs
   1/*
   2 * arch/sh/kernel/cpu/sh4/clock-shx3.c
   3 *
   4 * SH-X3 support for the clock framework
   5 *
   6 *  Copyright (C) 2006-2007  Renesas Technology Corp.
   7 *  Copyright (C) 2006-2007  Renesas Solutions Corp.
   8 *  Copyright (C) 2006-2010  Paul Mundt
   9 *
  10 * This file is subject to the terms and conditions of the GNU General Public
  11 * License.  See the file "COPYING" in the main directory of this archive
  12 * for more details.
  13 */
  14#include <linux/init.h>
  15#include <linux/kernel.h>
  16#include <linux/io.h>
  17#include <linux/clkdev.h>
  18#include <asm/clock.h>
  19#include <asm/freq.h>
  20
  21/*
  22 * Default rate for the root input clock, reset this with clk_set_rate()
  23 * from the platform code.
  24 */
  25static struct clk extal_clk = {
  26        .rate           = 16666666,
  27};
  28
  29static unsigned long pll_recalc(struct clk *clk)
  30{
  31        /* PLL1 has a fixed x72 multiplier.  */
  32        return clk->parent->rate * 72;
  33}
  34
  35static struct clk_ops pll_clk_ops = {
  36        .recalc         = pll_recalc,
  37};
  38
  39static struct clk pll_clk = {
  40        .ops            = &pll_clk_ops,
  41        .parent         = &extal_clk,
  42        .flags          = CLK_ENABLE_ON_INIT,
  43};
  44
  45static struct clk *clks[] = {
  46        &extal_clk,
  47        &pll_clk,
  48};
  49
  50static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
  51                               24, 32, 36, 48 };
  52
  53static struct clk_div_mult_table div4_div_mult_table = {
  54        .divisors = div2,
  55        .nr_divisors = ARRAY_SIZE(div2),
  56};
  57
  58static struct clk_div4_table div4_table = {
  59        .div_mult_table = &div4_div_mult_table,
  60};
  61
  62enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_SHA, DIV4_P, DIV4_NR };
  63
  64#define DIV4(_bit, _mask, _flags) \
  65  SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
  66
  67struct clk div4_clks[DIV4_NR] = {
  68        [DIV4_P] = DIV4(0, 0x0f80, 0),
  69        [DIV4_SHA] = DIV4(4, 0x0ff0, 0),
  70        [DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT),
  71        [DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT),
  72        [DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT),
  73        [DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT),
  74};
  75
  76#define MSTPCR0         0xffc00030
  77#define MSTPCR1         0xffc00034
  78
  79enum { MSTP027, MSTP026, MSTP025, MSTP024,
  80       MSTP009, MSTP008, MSTP003, MSTP002,
  81       MSTP001, MSTP000, MSTP119, MSTP105,
  82       MSTP104, MSTP_NR };
  83
  84static struct clk mstp_clks[MSTP_NR] = {
  85        /* MSTPCR0 */
  86        [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
  87        [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
  88        [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
  89        [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
  90        [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
  91        [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
  92        [MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
  93        [MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
  94        [MSTP001] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
  95        [MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
  96
  97        /* MSTPCR1 */
  98        [MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0),
  99        [MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
 100        [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
 101};
 102
 103#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 104
 105static struct clk_lookup lookups[] = {
 106        /* main clocks */
 107        CLKDEV_CON_ID("extal", &extal_clk),
 108        CLKDEV_CON_ID("pll_clk", &pll_clk),
 109
 110        /* DIV4 clocks */
 111        CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
 112        CLKDEV_CON_ID("shywaya_clk", &div4_clks[DIV4_SHA]),
 113        CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
 114        CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
 115        CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
 116        CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
 117
 118        /* MSTP32 clocks */
 119        {
 120                /* SCIF3 */
 121                .dev_id         = "sh-sci.3",
 122                .con_id         = "sci_fck",
 123                .clk            = &mstp_clks[MSTP027],
 124        }, {
 125                /* SCIF2 */
 126                .dev_id         = "sh-sci.2",
 127                .con_id         = "sci_fck",
 128                .clk            = &mstp_clks[MSTP026],
 129        }, {
 130                /* SCIF1 */
 131                .dev_id         = "sh-sci.1",
 132                .con_id         = "sci_fck",
 133                .clk            = &mstp_clks[MSTP025],
 134        }, {
 135                /* SCIF0 */
 136                .dev_id         = "sh-sci.0",
 137                .con_id         = "sci_fck",
 138                .clk            = &mstp_clks[MSTP024],
 139        },
 140        CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]),
 141        CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]),
 142        CLKDEV_CON_ID("fe1_fck", &mstp_clks[MSTP001]),
 143        CLKDEV_CON_ID("fe0_fck", &mstp_clks[MSTP000]),
 144        {
 145                /* TMU0 */
 146                .dev_id         = "sh_tmu.0",
 147                .con_id         = "tmu_fck",
 148                .clk            = &mstp_clks[MSTP008],
 149        }, {
 150                /* TMU1 */
 151                .dev_id         = "sh_tmu.1",
 152                .con_id         = "tmu_fck",
 153                .clk            = &mstp_clks[MSTP008],
 154        }, {
 155                /* TMU2 */
 156                .dev_id         = "sh_tmu.2",
 157                .con_id         = "tmu_fck",
 158                .clk            = &mstp_clks[MSTP008],
 159        }, {
 160                /* TMU3 */
 161                .dev_id         = "sh_tmu.3",
 162                .con_id         = "tmu_fck",
 163                .clk            = &mstp_clks[MSTP009],
 164        }, {
 165                /* TMU4 */
 166                .dev_id         = "sh_tmu.4",
 167                .con_id         = "tmu_fck",
 168                .clk            = &mstp_clks[MSTP009],
 169        }, {
 170                /* TMU5 */
 171                .dev_id         = "sh_tmu.5",
 172                .con_id         = "tmu_fck",
 173                .clk            = &mstp_clks[MSTP009],
 174        },
 175        CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]),
 176        CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
 177        CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
 178};
 179
 180int __init arch_clk_init(void)
 181{
 182        int i, ret = 0;
 183
 184        for (i = 0; i < ARRAY_SIZE(clks); i++)
 185                ret |= clk_register(clks[i]);
 186        for (i = 0; i < ARRAY_SIZE(lookups); i++)
 187                clkdev_add(&lookups[i]);
 188
 189        if (!ret)
 190                ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
 191                                           &div4_table);
 192        if (!ret)
 193                ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 194
 195        return ret;
 196}
 197