From 6247cea2b9c193a845a01381c36e18f11676fdfb Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 12 Oct 2011 21:34:12 +0900 Subject: ARM: SAMSUNG: Add support s3c2443-adc for S3C2443 The S3C2443-adc is 10 bit wide and has its mux-select in an extra register at base+0x18 Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2443/s3c2443.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-s3c2443') diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c index 5df6458ddd42..a22b771b0f36 100644 --- a/arch/arm/mach-s3c2443/s3c2443.c +++ b/arch/arm/mach-s3c2443/s3c2443.c @@ -41,6 +41,7 @@ #include #include #include +#include static struct map_desc s3c2443_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), @@ -70,6 +71,8 @@ int __init s3c2443_init(void) s3c_nand_setname("s3c2412-nand"); s3c_fb_setname("s3c2443-fb"); + s3c_adc_setname("s3c2443-adc"); + /* change WDT IRQ number */ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT; -- cgit v1.2.3 From d9a3bfbd7e80ecf24d2322659d5c0542f9d95e78 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 14 Oct 2011 15:08:56 +0900 Subject: ARM: S3C24XX: Add infrastructure to transmit armdiv to common code This is needed for making the armdiv clock common to S3C2443 and S3C2416/2450. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2416/clock.c | 4 +++- arch/arm/mach-s3c2443/clock.c | 4 +++- arch/arm/plat-s3c24xx/s3c2443-clock.c | 12 +++++++++++- arch/arm/plat-samsung/include/plat/s3c2443.h | 4 +++- 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-s3c2443') diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c index 5569def1a107..3060796b0e7d 100644 --- a/arch/arm/mach-s3c2416/clock.c +++ b/arch/arm/mach-s3c2416/clock.c @@ -158,7 +158,9 @@ void __init s3c2416_init_clocks(int xtal) clk_epll.parent = &clk_epllref.clk; - s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div); + s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div, + armdiv, ARRAY_SIZE(armdiv), + S3C2416_CLKDIV0_ARMDIV_MASK); for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_register_clksrc(clksrcs[ptr], 1); diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index cd51d04e1de7..88edc55838a1 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -283,7 +283,9 @@ void __init s3c2443_init_clocks(int xtal) clk_epll.rate = s3c2443_get_epll(epllcon, xtal); clk_epll.parent = &clk_epllref.clk; - s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div); + s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div, + armdiv, ARRAY_SIZE(armdiv), + S3C2443_CLKDIV0_ARMDIV_MASK); s3c2443_setup_clocks(); diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index 07a4c81587ac..3f2117b8c0d4 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c @@ -160,6 +160,10 @@ static struct clk clk_prediv = { }, }; +static unsigned int *armdiv; +static int nr_armdiv; +static int armdivmask; + /* usbhost * * usb host bus-clock, usually 48MHz to provide USB bus clock timing @@ -470,10 +474,16 @@ static struct clksrc_clk *clksrcs[] __initdata = { }; void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, - fdiv_fn get_fdiv) + fdiv_fn get_fdiv, + unsigned int *divs, int nr_divs, + int divmask) { int ptr; + armdiv = divs; + nr_armdiv = nr_divs; + armdivmask = divmask; + /* s3c2443 parents h and p clocks from prediv */ clk_h.parent = &clk_prediv; clk_p.parent = &clk_prediv; diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h index 4b2ac9a272b2..5fc4ad0fd756 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ b/arch/arm/plat-samsung/include/plat/s3c2443.h @@ -40,7 +40,9 @@ typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); typedef unsigned int (*fdiv_fn)(unsigned long clkcon0); extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv); -extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv, + unsigned int *divs, int nr_divs, + int divmask); extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); -- cgit v1.2.3 From aab08eebdf87d3e6eda5c81f119423af63f5aee1 Mon Sep 17 00:00:00 2001 From: Heiko St?bner Date: Fri, 14 Oct 2011 15:08:56 +0900 Subject: ARM: S3C2443: Move clk_arm and clk_armdiv to common code The system-layout of the armdiv and armclk is common to S3C2443/S3C2416/S3C2450 and only differs in the array of possible dividers. Therefore it is possible to reuse the clock definitions for all of these SoCs. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2443/clock.c | 85 +--------------------------------- arch/arm/plat-s3c24xx/s3c2443-clock.c | 87 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 83 deletions(-) (limited to 'arch/arm/mach-s3c2443') diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 88edc55838a1..6fda4bf09cdd 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -61,10 +61,10 @@ * * this clock is sourced from msysclk and can have a number of * divider values applied to it to then be fed into armclk. + * The real clock definition is done in s3c2443-clock.c, + * only the armdiv divisor table must be defined here. */ -/* armdiv divisor table */ - static unsigned int armdiv[16] = { [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, @@ -83,85 +83,6 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; } -static unsigned long s3c2443_armclk_roundrate(struct clk *clk, - unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - unsigned long calc; - unsigned best = 256; /* bigger than any value */ - unsigned div; - int ptr; - - for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) { - div = armdiv[ptr]; - calc = parent / div; - if (calc <= rate && div < best) - best = div; - } - - return parent / best; -} - -static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - unsigned long calc; - unsigned div; - unsigned best = 256; /* bigger than any value */ - int ptr; - int val = -1; - - for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) { - div = armdiv[ptr]; - calc = parent / div; - if (calc <= rate && div < best) { - best = div; - val = ptr; - } - } - - if (val >= 0) { - unsigned long clkcon0; - - clkcon0 = __raw_readl(S3C2443_CLKDIV0); - clkcon0 &= ~S3C2443_CLKDIV0_ARMDIV_MASK; - clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT; - __raw_writel(clkcon0, S3C2443_CLKDIV0); - } - - return (val == -1) ? -EINVAL : 0; -} - -static struct clk clk_armdiv = { - .name = "armdiv", - .parent = &clk_msysclk.clk, - .ops = &(struct clk_ops) { - .round_rate = s3c2443_armclk_roundrate, - .set_rate = s3c2443_armclk_setrate, - }, -}; - -/* armclk - * - * this is the clock fed into the ARM core itself, from armdiv or from hclk. - */ - -static struct clk *clk_arm_sources[] = { - [0] = &clk_armdiv, - [1] = &clk_h, -}; - -static struct clksrc_clk clk_arm = { - .clk = { - .name = "armclk", - }, - .sources = &(struct clksrc_sources) { - .sources = clk_arm_sources, - .nr_sources = ARRAY_SIZE(clk_arm_sources), - }, - .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, -}; - /* hsspi * * high-speed spi clock, sourced from esysclk @@ -260,14 +181,12 @@ static struct clk init_clocks[] = { /* clocks to add straight away */ static struct clksrc_clk *clksrcs[] __initdata = { - &clk_arm, &clk_hsspi, &clk_hsmmc_div, }; static struct clk *clks[] __initdata = { &clk_hsmmc, - &clk_armdiv, }; void __init_or_cpufreq s3c2443_setup_clocks(void) diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index 3f2117b8c0d4..f9c5b0343cf3 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c @@ -160,10 +160,95 @@ static struct clk clk_prediv = { }, }; +/* armdiv + * + * this clock is sourced from msysclk and can have a number of + * divider values applied to it to then be fed into armclk. +*/ + static unsigned int *armdiv; static int nr_armdiv; static int armdivmask; +static unsigned long s3c2443_armclk_roundrate(struct clk *clk, + unsigned long rate) +{ + unsigned long parent = clk_get_rate(clk->parent); + unsigned long calc; + unsigned best = 256; /* bigger than any value */ + unsigned div; + int ptr; + + for (ptr = 0; ptr < nr_armdiv; ptr++) { + div = armdiv[ptr]; + calc = parent / div; + if (calc <= rate && div < best) + best = div; + } + + return parent / best; +} + +static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) +{ + unsigned long parent = clk_get_rate(clk->parent); + unsigned long calc; + unsigned div; + unsigned best = 256; /* bigger than any value */ + int ptr; + int val = -1; + + for (ptr = 0; ptr < nr_armdiv; ptr++) { + div = armdiv[ptr]; + calc = parent / div; + if (calc <= rate && div < best) { + best = div; + val = ptr; + } + } + + if (val >= 0) { + unsigned long clkcon0; + + clkcon0 = __raw_readl(S3C2443_CLKDIV0); + clkcon0 &= ~armdivmask; + clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT; + __raw_writel(clkcon0, S3C2443_CLKDIV0); + } + + return (val == -1) ? -EINVAL : 0; +} + +static struct clk clk_armdiv = { + .name = "armdiv", + .parent = &clk_msysclk.clk, + .ops = &(struct clk_ops) { + .round_rate = s3c2443_armclk_roundrate, + .set_rate = s3c2443_armclk_setrate, + }, +}; + +/* armclk + * + * this is the clock fed into the ARM core itself, from armdiv or from hclk. + */ + +static struct clk *clk_arm_sources[] = { + [0] = &clk_armdiv, + [1] = &clk_h, +}; + +static struct clksrc_clk clk_arm = { + .clk = { + .name = "armclk", + }, + .sources = &(struct clksrc_sources) { + .sources = clk_arm_sources, + .nr_sources = ARRAY_SIZE(clk_arm_sources), + }, + .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, +}; + /* usbhost * * usb host bus-clock, usually 48MHz to provide USB bus clock timing @@ -462,6 +547,7 @@ static struct clk *clks[] __initdata = { &clk_ext, &clk_epll, &clk_usb_bus, + &clk_armdiv, }; static struct clksrc_clk *clksrcs[] __initdata = { @@ -471,6 +557,7 @@ static struct clksrc_clk *clksrcs[] __initdata = { &clk_epllref, &clk_esysclk, &clk_msysclk, + &clk_arm, }; void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, -- cgit v1.2.3 From 33ccedfd1b79a7cf649b2991e95bae415c013240 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 14 Oct 2011 15:08:57 +0900 Subject: ARM: S3C24XX: use clk_get_rate to init fclk in common_setup_clocks Previously the fclk rate was calculated by dividing the pll through the divider value of the armdiv. With a real armdiv clk in place it's possible to simply read its value, which does essentially the same. This change makes the whole fdiv_fn function pointers supplied to s3c2443_common_init_clocks and s3c2443_common_setup_clocks obsolete, so remove it too. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2416/clock.c | 11 ++--------- arch/arm/mach-s3c2443/clock.c | 11 ++--------- arch/arm/plat-s3c24xx/s3c2443-clock.c | 8 +++----- arch/arm/plat-samsung/include/plat/s3c2443.h | 5 ++--- 4 files changed, 9 insertions(+), 26 deletions(-) (limited to 'arch/arm/mach-s3c2443') diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c index 7aa0cfa2f9bd..afbbe8bc21d1 100644 --- a/arch/arm/mach-s3c2416/clock.c +++ b/arch/arm/mach-s3c2416/clock.c @@ -133,16 +133,9 @@ static struct clk hsmmc0_clk = { .ctrlbit = S3C2416_HCLKCON_HSMMC0, }; -static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0) -{ - clkcon0 &= S3C2416_CLKDIV0_ARMDIV_MASK; - - return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; -} - void __init_or_cpufreq s3c2416_setup_clocks(void) { - s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div); + s3c2443_common_setup_clocks(s3c2416_get_pll); } @@ -166,7 +159,7 @@ void __init s3c2416_init_clocks(int xtal) clk_epll.parent = &clk_epllref.clk; - s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div, + s3c2443_common_init_clocks(xtal, s3c2416_get_pll, armdiv, ARRAY_SIZE(armdiv), S3C2416_CLKDIV0_ARMDIV_MASK); diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 6fda4bf09cdd..b93cb96f57a5 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -76,13 +76,6 @@ static unsigned int armdiv[16] = { [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16, }; -static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) -{ - clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK; - - return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; -} - /* hsspi * * high-speed spi clock, sourced from esysclk @@ -191,7 +184,7 @@ static struct clk *clks[] __initdata = { void __init_or_cpufreq s3c2443_setup_clocks(void) { - s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div); + s3c2443_common_setup_clocks(s3c2443_get_mpll); } void __init s3c2443_init_clocks(int xtal) @@ -202,7 +195,7 @@ void __init s3c2443_init_clocks(int xtal) clk_epll.rate = s3c2443_get_epll(epllcon, xtal); clk_epll.parent = &clk_epllref.clk; - s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div, + s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, armdiv, ARRAY_SIZE(armdiv), S3C2443_CLKDIV0_ARMDIV_MASK); diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index 40a87206400f..d3ebbeedf6d9 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c @@ -520,8 +520,7 @@ static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) /* EPLLCON compatible enough to get on/off information */ -void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll, - fdiv_fn get_fdiv) +void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) { unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); @@ -541,7 +540,7 @@ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll, pll = get_mpll(mpllcon, xtal); clk_msysclk.clk.rate = pll; - fclk = pll / get_fdiv(clkdiv0); + fclk = clk_get_rate(&clk_armdiv); hclk = s3c2443_prediv_getrate(&clk_prediv); hclk /= s3c2443_get_hdiv(clkdiv0); pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); @@ -590,7 +589,6 @@ static struct clksrc_clk *clksrcs[] __initdata = { }; void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, - fdiv_fn get_fdiv, unsigned int *divs, int nr_divs, int divmask) { @@ -620,5 +618,5 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c2443_common_setup_clocks(get_mpll, get_fdiv); + s3c2443_common_setup_clocks(get_mpll); } diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h index 5fc4ad0fd756..7fae1a050694 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ b/arch/arm/plat-samsung/include/plat/s3c2443.h @@ -37,10 +37,9 @@ extern int s3c2443_baseclk_add(void); struct clk; /* some files don't need clk.h otherwise */ typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); -typedef unsigned int (*fdiv_fn)(unsigned long clkcon0); -extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv); -extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv, +extern void s3c2443_common_setup_clocks(pll_fn get_mpll); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, unsigned int *divs, int nr_divs, int divmask); -- cgit v1.2.3 From ec4f5423b5b63b1a92bce375ed242d2c19767995 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 14 Oct 2011 15:41:36 +0900 Subject: ARM: S3C2443: Remove redundant s3c_register_clocks call for init_clocks Since commit af337f3e633a198034a99450416257ddf2307497 "ARM: S3C2443: Move parts of the clock code to common clock file", the init_clocks array is moved to arch/arm/plat-s3c24xx/s3c2443-clock.c. Now we call s3c_register_clocks for init_clocks in s3c2443_common_init_clocks. Thus we can remove the empty init_clocks array here and remove the redundant s3c_register_clocks call for init_clocks in s3c2443_init_clocks. Signed-off-by: Axel Lin Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2443/clock.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/arm/mach-s3c2443') diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index b93cb96f57a5..1c2c088aa2e8 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -168,9 +168,6 @@ static struct clk init_clocks_off[] = { } }; -static struct clk init_clocks[] = { -}; - /* clocks to add straight away */ static struct clksrc_clk *clksrcs[] __initdata = { @@ -206,10 +203,6 @@ void __init s3c2443_init_clocks(int xtal) for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_register_clksrc(clksrcs[ptr], 1); - /* register clocks from clock array */ - - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - /* We must be careful disabling the clocks we are not intending to * be using at boot time, as subsystems such as the LCD which do * their own DMA requests to the bus can cause the system to lockup -- cgit v1.2.3