aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2006-03-20 16:00:12 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-03-21 17:06:19 -0500
commite44c03960f232e0f9bd2f6bcffccf83770757a8e (patch)
treef14012b8224dd45dc7f0c4c9abeea05287b6feec /arch/arm
parent6e8908edd5a140f4f0cc4338fa0420b0bb0f8efa (diff)
[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')
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-clock.c51
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 @@
45 45
46/* S3C2440 extended clock support */ 46/* S3C2440 extended clock support */
47 47
48static unsigned long s3c2440_camif_upll_round(struct clk *clk,
49 unsigned long rate)
50{
51 unsigned long parent_rate = clk_get_rate(clk->parent);
52 int div;
53
54 if (rate > parent_rate)
55 return parent_rate;
56
57 /* note, we remove the +/- 1 calculations for the divisor */
58
59 div = (parent_rate / rate) / 2;
60
61 if (div < 1)
62 div = 1;
63 else if (div > 16)
64 div = 16;
65
66 return parent_rate / (div * 2);
67}
68
69static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
70{
71 unsigned long parent_rate = clk_get_rate(clk->parent);
72 unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
73
74 rate = s3c2440_camif_upll_round(clk, rate);
75
76 camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
77
78 if (rate != parent_rate) {
79 camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
80 camdivn |= (((parent_rate / rate) / 2) - 1);
81 }
82
83 __raw_writel(camdivn, S3C2440_CAMDIVN);
84
85 return 0;
86}
87
88/* Extra S3C2440 clocks */
89
48static struct clk s3c2440_clk_cam = { 90static struct clk s3c2440_clk_cam = {
49 .name = "camif", 91 .name = "camif",
50 .id = -1, 92 .id = -1,
@@ -52,6 +94,13 @@ static struct clk s3c2440_clk_cam = {
52 .ctrlbit = S3C2440_CLKCON_CAMERA, 94 .ctrlbit = S3C2440_CLKCON_CAMERA,
53}; 95};
54 96
97static struct clk s3c2440_clk_cam_upll = {
98 .name = "camif-upll",
99 .id = -1,
100 .set_rate = s3c2440_camif_upll_setrate,
101 .round_rate = s3c2440_camif_upll_round,
102};
103
55static struct clk s3c2440_clk_ac97 = { 104static struct clk s3c2440_clk_ac97 = {
56 .name = "ac97", 105 .name = "ac97",
57 .id = -1, 106 .id = -1,
@@ -78,9 +127,11 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
78 127
79 s3c2440_clk_cam.parent = clk_h; 128 s3c2440_clk_cam.parent = clk_h;
80 s3c2440_clk_ac97.parent = clk_p; 129 s3c2440_clk_ac97.parent = clk_p;
130 s3c2440_clk_cam_upll.parent = clk_upll;
81 131
82 s3c24xx_register_clock(&s3c2440_clk_ac97); 132 s3c24xx_register_clock(&s3c2440_clk_ac97);
83 s3c24xx_register_clock(&s3c2440_clk_cam); 133 s3c24xx_register_clock(&s3c2440_clk_cam);
134 s3c24xx_register_clock(&s3c2440_clk_cam_upll);
84 135
85 clk_disable(&s3c2440_clk_ac97); 136 clk_disable(&s3c2440_clk_ac97);
86 clk_disable(&s3c2440_clk_cam); 137 clk_disable(&s3c2440_clk_cam);