diff options
author | Ben Dooks <ben-linux@fluff.org> | 2006-03-20 21:00:12 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-03-21 22:06:19 +0000 |
commit | e44c03960f232e0f9bd2f6bcffccf83770757a8e (patch) | |
tree | f14012b8224dd45dc7f0c4c9abeea05287b6feec /arch/arm/mach-s3c2410 | |
parent | 6e8908edd5a140f4f0cc4338fa0420b0bb0f8efa (diff) | |
download | linux-e44c03960f232e0f9bd2f6bcffccf83770757a8e.tar.gz linux-e44c03960f232e0f9bd2f6bcffccf83770757a8e.tar.bz2 linux-e44c03960f232e0f9bd2f6bcffccf83770757a8e.zip |
[ARM] 3360/1: S3C2440 - add set rate methods and camera clock
Patch from Ben Dooks
Add set_rate methods for the extra clocks on the S3C2440
and add the camera UPLL clock source
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-s3c2410')
-rw-r--r-- | arch/arm/mach-s3c2410/s3c2440-clock.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c index 2d0fa03a257a..7bca0be87384 100644 --- a/arch/arm/mach-s3c2410/s3c2440-clock.c +++ b/arch/arm/mach-s3c2410/s3c2440-clock.c @@ -45,6 +45,48 @@ /* S3C2440 extended clock support */ +static unsigned long s3c2440_camif_upll_round(struct clk *clk, + unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + int div; + + if (rate > parent_rate) + return parent_rate; + + /* note, we remove the +/- 1 calculations for the divisor */ + + div = (parent_rate / rate) / 2; + + if (div < 1) + div = 1; + else if (div > 16) + div = 16; + + return parent_rate / (div * 2); +} + +static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); + + rate = s3c2440_camif_upll_round(clk, rate); + + camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK); + + if (rate != parent_rate) { + camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL; + camdivn |= (((parent_rate / rate) / 2) - 1); + } + + __raw_writel(camdivn, S3C2440_CAMDIVN); + + return 0; +} + +/* Extra S3C2440 clocks */ + static struct clk s3c2440_clk_cam = { .name = "camif", .id = -1, @@ -52,6 +94,13 @@ static struct clk s3c2440_clk_cam = { .ctrlbit = S3C2440_CLKCON_CAMERA, }; +static struct clk s3c2440_clk_cam_upll = { + .name = "camif-upll", + .id = -1, + .set_rate = s3c2440_camif_upll_setrate, + .round_rate = s3c2440_camif_upll_round, +}; + static struct clk s3c2440_clk_ac97 = { .name = "ac97", .id = -1, @@ -78,9 +127,11 @@ static int s3c2440_clk_add(struct sys_device *sysdev) s3c2440_clk_cam.parent = clk_h; s3c2440_clk_ac97.parent = clk_p; + s3c2440_clk_cam_upll.parent = clk_upll; s3c24xx_register_clock(&s3c2440_clk_ac97); s3c24xx_register_clock(&s3c2440_clk_cam); + s3c24xx_register_clock(&s3c2440_clk_cam_upll); clk_disable(&s3c2440_clk_ac97); clk_disable(&s3c2440_clk_cam); |