diff options
Diffstat (limited to 'arch/arm/mach-s3c2443')
-rw-r--r-- | arch/arm/mach-s3c2443/clock.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 24da92417a16..d34f3d32eba5 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c | |||
@@ -221,7 +221,6 @@ static struct clk clk_mdivclk = { | |||
221 | .get_rate = s3c2443_getrate_mdivclk, | 221 | .get_rate = s3c2443_getrate_mdivclk, |
222 | }; | 222 | }; |
223 | 223 | ||
224 | |||
225 | static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) | 224 | static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) |
226 | { | 225 | { |
227 | unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); | 226 | unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); |
@@ -249,6 +248,46 @@ static struct clk clk_msysclk = { | |||
249 | .set_parent = s3c2443_setparent_msysclk, | 248 | .set_parent = s3c2443_setparent_msysclk, |
250 | }; | 249 | }; |
251 | 250 | ||
251 | /* armdiv | ||
252 | * | ||
253 | * this clock is sourced from msysclk and can have a number of | ||
254 | * divider values applied to it to then be fed into armclk. | ||
255 | */ | ||
256 | |||
257 | static struct clk clk_armdiv = { | ||
258 | .name = "armdiv", | ||
259 | .id = -1, | ||
260 | .parent = &clk_msysclk, | ||
261 | }; | ||
262 | |||
263 | /* armclk | ||
264 | * | ||
265 | * this is the clock fed into the ARM core itself, either from | ||
266 | * armdiv or from hclk. | ||
267 | */ | ||
268 | |||
269 | static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent) | ||
270 | { | ||
271 | unsigned long clkdiv0; | ||
272 | |||
273 | clkdiv0 = __raw_readl(S3C2443_CLKDIV0); | ||
274 | |||
275 | if (parent == &clk_armdiv) | ||
276 | clkdiv0 &= ~S3C2443_CLKDIV0_DVS; | ||
277 | else if (parent == &clk_h) | ||
278 | clkdiv0 |= S3C2443_CLKDIV0_DVS; | ||
279 | else | ||
280 | return -EINVAL; | ||
281 | |||
282 | __raw_writel(clkdiv0, S3C2443_CLKDIV0); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static struct clk clk_arm = { | ||
287 | .name = "armclk", | ||
288 | .id = -1, | ||
289 | .set_parent = s3c2443_setparent_armclk, | ||
290 | }; | ||
252 | 291 | ||
253 | /* esysclk | 292 | /* esysclk |
254 | * | 293 | * |
@@ -887,6 +926,15 @@ static void __init s3c2443_clk_initparents(void) | |||
887 | } | 926 | } |
888 | 927 | ||
889 | clk_init_set_parent(&clk_msysclk, parent); | 928 | clk_init_set_parent(&clk_msysclk, parent); |
929 | |||
930 | /* arm */ | ||
931 | |||
932 | if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS) | ||
933 | parent = &clk_h; | ||
934 | else | ||
935 | parent = &clk_armdiv; | ||
936 | |||
937 | clk_init_set_parent(&clk_arm, parent); | ||
890 | } | 938 | } |
891 | 939 | ||
892 | /* armdiv divisor table */ | 940 | /* armdiv divisor table */ |
@@ -936,6 +984,8 @@ static struct clk *clks[] __initdata = { | |||
936 | &clk_hsspi, | 984 | &clk_hsspi, |
937 | &clk_hsmmc_div, | 985 | &clk_hsmmc_div, |
938 | &clk_hsmmc, | 986 | &clk_hsmmc, |
987 | &clk_armdiv, | ||
988 | &clk_arm, | ||
939 | }; | 989 | }; |
940 | 990 | ||
941 | void __init s3c2443_init_clocks(int xtal) | 991 | void __init s3c2443_init_clocks(int xtal) |
@@ -958,6 +1008,8 @@ void __init s3c2443_init_clocks(int xtal) | |||
958 | hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); | 1008 | hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); |
959 | pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); | 1009 | pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); |
960 | 1010 | ||
1011 | clk_armdiv.rate = fclk; | ||
1012 | |||
961 | s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); | 1013 | s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); |
962 | 1014 | ||
963 | printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", | 1015 | printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", |