aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-s3c2443/clock.c54
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
225static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) 224static 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
257static 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
269static 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
286static 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
941void __init s3c2443_init_clocks(int xtal) 991void __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",