diff options
Diffstat (limited to 'arch/arm/mach-shmobile/clock-sh73a0.c')
| -rw-r--r-- | arch/arm/mach-shmobile/clock-sh73a0.c | 149 | 
1 files changed, 71 insertions, 78 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 516ff7f3e43..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; + +	return -ETIMEDOUT; +} -	/* set KICK bit in FRQCRB to update hardware setting */ -	value = __raw_readl(FRQCRB); -	value |= (1 << 31); -	__raw_writel(value, FRQCRB); +static void div4_kick(struct clk *clk) +{ +	frqcr_kick();  }  static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, @@ -258,23 +221,35 @@ 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, 0xfff, CLK_ENABLE_ON_INIT), -	[DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT), -	[DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT), -	[DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT), -	[DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0), -	[DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0), -	[DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0), -	[DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0), -	[DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0), -	[DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0), -	[DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0), +	[DIV4_I] = DIV4(FRQCRA, 20, 0xdff, 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] = 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, @@ -471,6 +446,7 @@ static struct clk dsi1phy_clk = {  static struct clk *late_main_clks[] = {  	&dsi0phy_clk,  	&dsi1phy_clk, +	&twd_clk,  };  enum { MSTP001, @@ -525,9 +501,17 @@ static struct clk mstp_clks[MSTP_NR] = {  	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */  }; +/* The lookups structure below includes duplicate entries for some clocks + * with alternate names. + * - The traditional name used when a device is initialised with platform data + * - The name used when a device is initialised using device tree + * The longer-term aim is to remove these duplicates, and indeed the + * lookups table entirely, by describing clocks using device tree. + */  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]), @@ -545,6 +529,7 @@ static struct clk_lookup lookups[] = {  	/* MSTP32 clocks */  	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ +	CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */  	CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */  	CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */  	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */ @@ -553,6 +538,7 @@ static struct clk_lookup lookups[] = {  	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */  	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */  	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ +	CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */  	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */  	CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */  	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ @@ -569,17 +555,24 @@ static struct clk_lookup lookups[] = {  	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */  	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */  	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ +	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 */  	CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */  	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ +	CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */  	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ +	CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */  	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */  };  |