diff options
Diffstat (limited to 'arch/arm/mach-shmobile/clock-sh73a0.c')
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh73a0.c | 122 |
1 files changed, 51 insertions, 71 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index afa5423a0f9..784fbaa4cc5 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -21,6 +21,8 @@ #include <linux/io.h> #include <linux/sh_clk.h> #include <linux/clkdev.h> +#include <asm/processor.h> +#include <mach/clock.h> #include <mach/common.h> #define FRQCRA IOMEM(0xe6150000) @@ -82,61 +84,16 @@ struct clk sh73a0_extal2_clk = { .rate = 48000000, }; -/* A fixed divide-by-2 block */ -static unsigned long div2_recalc(struct clk *clk) -{ - return clk->parent->rate / 2; -} - -static struct sh_clk_ops div2_clk_ops = { - .recalc = div2_recalc, -}; - -static unsigned long div7_recalc(struct clk *clk) -{ - return clk->parent->rate / 7; -} - -static struct sh_clk_ops div7_clk_ops = { - .recalc = div7_recalc, -}; - -static unsigned long div13_recalc(struct clk *clk) -{ - return clk->parent->rate / 13; -} - -static struct sh_clk_ops div13_clk_ops = { - .recalc = div13_recalc, -}; - -/* Divide extal1 by two */ -static struct clk extal1_div2_clk = { - .ops = &div2_clk_ops, - .parent = &sh73a0_extal1_clk, -}; - -/* Divide extal2 by two */ -static struct clk extal2_div2_clk = { - .ops = &div2_clk_ops, - .parent = &sh73a0_extal2_clk, -}; - static struct sh_clk_ops main_clk_ops = { .recalc = followparent_recalc, }; /* Main clock */ static struct clk main_clk = { + /* .parent wll be set on sh73a0_clock_init() */ .ops = &main_clk_ops, }; -/* Divide Main clock by two */ -static struct clk main_div2_clk = { - .ops = &div2_clk_ops, - .parent = &main_clk, -}; - /* PLL0, PLL1, PLL2, PLL3 */ static unsigned long pll_recalc(struct clk *clk) { @@ -192,21 +149,17 @@ static struct clk pll3_clk = { .enable_bit = 3, }; -/* Divide PLL */ -static struct clk pll1_div2_clk = { - .ops = &div2_clk_ops, - .parent = &pll1_clk, -}; - -static struct clk pll1_div7_clk = { - .ops = &div7_clk_ops, - .parent = &pll1_clk, -}; +/* A fixed divide block */ +SH_CLK_RATIO(div2, 1, 2); +SH_CLK_RATIO(div7, 1, 7); +SH_CLK_RATIO(div13, 1, 13); -static struct clk pll1_div13_clk = { - .ops = &div13_clk_ops, - .parent = &pll1_clk, -}; +SH_FIXED_RATIO_CLK(extal1_div2_clk, sh73a0_extal1_clk, div2); +SH_FIXED_RATIO_CLK(extal2_div2_clk, sh73a0_extal2_clk, div2); +SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2); +SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2); +SH_FIXED_RATIO_CLK(pll1_div7_clk, pll1_clk, div7); +SH_FIXED_RATIO_CLK(pll1_div13_clk, pll1_clk, div13); /* External input clock */ struct clk sh73a0_extcki_clk = { @@ -234,14 +187,24 @@ static struct clk *main_clks[] = { &sh73a0_extalr_clk, }; -static void div4_kick(struct clk *clk) +static int frqcr_kick(void) { - unsigned long value; + int i; + + /* set KICK bit in FRQCRB to update hardware setting, check success */ + __raw_writel(__raw_readl(FRQCRB) | (1 << 31), FRQCRB); + for (i = 1000; i; i--) + if (__raw_readl(FRQCRB) & (1 << 31)) + cpu_relax(); + else + return i; - /* set KICK bit in FRQCRB to update hardware setting */ - value = __raw_readl(FRQCRB); - value |= (1 << 31); - __raw_writel(value, FRQCRB); + return -ETIMEDOUT; +} + +static void div4_kick(struct clk *clk) +{ + frqcr_kick(); } static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, @@ -258,25 +221,37 @@ static struct clk_div4_table div4_table = { }; enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, - DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR }; + DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR }; #define DIV4(_reg, _bit, _mask, _flags) \ SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags) static struct clk div4_clks[DIV4_NR] = { [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT), - [DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), + [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT), [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0), [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0), - [DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0), - [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0), - [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0), + [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0), [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0), [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0), }; +static unsigned long twd_recalc(struct clk *clk) +{ + return clk_get_rate(clk->parent) / 4; +} + +static struct sh_clk_ops twd_clk_ops = { + .recalc = twd_recalc, +}; + +static struct clk twd_clk = { + .parent = &div4_clks[DIV4_Z], + .ops = &twd_clk_ops, +}; + enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2, DIV6_FSIA, DIV6_FSIB, DIV6_SUB, @@ -471,6 +446,7 @@ static struct clk dsi1phy_clk = { static struct clk *late_main_clks[] = { &dsi0phy_clk, &dsi1phy_clk, + &twd_clk, }; enum { MSTP001, @@ -535,6 +511,7 @@ static struct clk mstp_clks[MSTP_NR] = { static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */ /* DIV6 clocks */ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), @@ -581,10 +558,13 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ + CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */ CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ |