Add support for reconfiguring the clock for the ARM core, enabling CPUfreq support. Currently only the divider for ARMCLK may be changed, ARMPLL is left static. Signed-off-by: Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx> --- arch/arm/plat-s3c64xx/s3c6400-clock.c | 71 +++++++++++++++++++++++++++++++++ 1 files changed, 71 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c index 05b1752..e05ed02 100644 --- a/arch/arm/plat-s3c64xx/s3c6400-clock.c +++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c @@ -88,6 +88,76 @@ static struct clksrc_clk clk_mout_apll = { .sources = &clk_src_apll, }; +#ifdef CONFIG_CPU_S3C6400 +#define CLKDIV0_ARM_MASK S3C6400_CLKDIV0_ARM_MASK +#endif +#ifdef CONFIG_CPU_S3C6410 +#define CLKDIV0_ARM_MASK S3C6410_CLKDIV0_ARM_MASK +#endif + +static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + u32 val; + + val = __raw_readl(S3C_CLK_DIV0); + val &= CLKDIV0_ARM_MASK; + + return rate / (val + 1); +} + +static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk, + unsigned long rate) +{ + unsigned long parent = clk_get_rate(clk->parent); + int div; + int max = CLKDIV0_ARM_MASK + 1; + + if (parent < rate) + return parent; + + div = parent / rate; + + if (div < 1) + div = 1; + if (div > max) + div = max; + + return parent / div; +} + +static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int div; + u32 val; + unsigned long flags; + + div = (clk_get_rate(clk->parent) / rate) - 1; + + if (div > CLKDIV0_ARM_MASK) + return -EINVAL; + + local_irq_save(flags); + + val = __raw_readl(S3C_CLK_DIV0); + val &= ~CLKDIV0_ARM_MASK; + val |= div; + + __raw_writel(val, S3C_CLK_DIV0); + local_irq_restore(flags); + + return 0; +} + +static struct clk clk_arm = { + .name = "armclk", + .id = -1, + .parent = &clk_mout_apll.clk, + .round_rate = &s3c64xx_clk_arm_round_rate, + .get_rate = s3c64xx_clk_arm_get_rate, + .set_rate = s3c64xx_clk_arm_set_rate, +}; + static struct clk clk_fout_epll = { .name = "fout_epll", .id = -1, @@ -635,6 +705,7 @@ static struct clk *clks[] __initdata = { &clk_audio0.clk, &clk_audio1.clk, &clk_irda.clk, + &clk_arm, }; void __init s3c6400_register_clocks(void) -- 1.6.2.2 -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html