diff options
author | Ben Dooks <ben-linux@fluff.org> | 2006-03-20 16:00:12 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-03-21 17:06:19 -0500 |
commit | e44c03960f232e0f9bd2f6bcffccf83770757a8e (patch) | |
tree | f14012b8224dd45dc7f0c4c9abeea05287b6feec /arch/arm | |
parent | 6e8908edd5a140f4f0cc4338fa0420b0bb0f8efa (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.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 @@ | |||
45 | 45 | ||
46 | /* S3C2440 extended clock support */ | 46 | /* S3C2440 extended clock support */ |
47 | 47 | ||
48 | static 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 | |||
69 | static 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 | |||
48 | static struct clk s3c2440_clk_cam = { | 90 | static 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 | ||
97 | static 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 | |||
55 | static struct clk s3c2440_clk_ac97 = { | 104 | static 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); |