aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2443
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-07-07 13:12:40 -0400
committerBen Dooks <ben-linux@fluff.org>2008-07-07 13:13:02 -0400
commit2e16c27aa379793c354012e5fae0aae89103b19b (patch)
treed196dbbcb6ba6f1257391b1ae7a4aa3594679338 /arch/arm/mach-s3c2443
parentba7622a19fabb853b8bbb918a5d76557f88e4274 (diff)
[ARM] S3C2443: Add prediv clk and fix setting of h and p clocks
Update the S3C2443 clock support to add the prediv clock that is sourced via a divider from msysclk. Also fix the setting of p and h clocks from this prediv clock. Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/mach-s3c2443')
-rw-r--r--arch/arm/mach-s3c2443/clock.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index d34f3d32eba5..17f064fabdaf 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -678,6 +678,29 @@ static struct clk clk_display = {
678 .round_rate = s3c2443_roundrate_clksrc256, 678 .round_rate = s3c2443_roundrate_clksrc256,
679}; 679};
680 680
681/* prediv
682 *
683 * this divides the msysclk down to pass to h/p/etc.
684 */
685
686static unsigned long s3c2443_prediv_getrate(struct clk *clk)
687{
688 unsigned long rate = clk_get_rate(clk->parent);
689 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
690
691 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
692 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
693
694 return rate / (clkdiv0 + 1);
695}
696
697static struct clk clk_prediv = {
698 .name = "prediv",
699 .id = -1,
700 .parent = &clk_msysclk,
701 .get_rate = s3c2443_prediv_getrate,
702};
703
681/* standard clock definitions */ 704/* standard clock definitions */
682 705
683static struct clk init_clocks_disable[] = { 706static struct clk init_clocks_disable[] = {
@@ -957,10 +980,9 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
957 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; 980 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
958} 981}
959 982
960static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0) 983static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
961{ 984{
962 clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK; 985 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
963 clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
964 986
965 return clkcon0 + 1; 987 return clkcon0 + 1;
966} 988}
@@ -986,6 +1008,7 @@ static struct clk *clks[] __initdata = {
986 &clk_hsmmc, 1008 &clk_hsmmc,
987 &clk_armdiv, 1009 &clk_armdiv,
988 &clk_arm, 1010 &clk_arm,
1011 &clk_prediv,
989}; 1012};
990 1013
991void __init s3c2443_init_clocks(int xtal) 1014void __init s3c2443_init_clocks(int xtal)
@@ -1001,15 +1024,19 @@ void __init s3c2443_init_clocks(int xtal)
1001 int ret; 1024 int ret;
1002 int ptr; 1025 int ptr;
1003 1026
1027 /* s3c2443 parents h and p clocks from prediv */
1028 clk_h.parent = &clk_prediv;
1029 clk_p.parent = &clk_prediv;
1030
1004 pll = s3c2443_get_mpll(mpllcon, xtal); 1031 pll = s3c2443_get_mpll(mpllcon, xtal);
1032 clk_msysclk.rate = pll;
1005 1033
1006 fclk = pll / s3c2443_fclk_div(clkdiv0); 1034 fclk = pll / s3c2443_fclk_div(clkdiv0);
1007 hclk = fclk / s3c2443_get_prediv(clkdiv0); 1035 hclk = s3c2443_prediv_getrate(&clk_prediv);
1036 hclk = hclk / s3c2443_get_hdiv(clkdiv0);
1008 hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); 1037 hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
1009 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); 1038 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
1010 1039
1011 clk_armdiv.rate = fclk;
1012
1013 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); 1040 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
1014 1041
1015 printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", 1042 printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",