diff options
-rw-r--r-- | arch/arm/mach-pxa/clock-pxa3xx.c | 25 | ||||
-rw-r--r-- | arch/arm/mach-pxa/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 2 |
3 files changed, 25 insertions, 3 deletions
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c index 25be4adf6f4..1b08a34ab23 100644 --- a/arch/arm/mach-pxa/clock-pxa3xx.c +++ b/arch/arm/mach-pxa/clock-pxa3xx.c @@ -9,7 +9,9 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/io.h> +#include <mach/smemc.h> #include <mach/pxa3xx-regs.h> #include "clock.h" @@ -23,9 +25,6 @@ #define ACCR_D0CS (1 << 26) #define ACCR_PCCE (1 << 11) -/* crystal frequency to static memory controller multiplier (SMCFS) */ -static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; - /* crystal frequency to HSIO bus frequency multiplier (HSS) */ static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; @@ -108,6 +107,20 @@ static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) return hsio_clk; } +/* crystal frequency to static memory controller multiplier (SMCFS) */ +static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; +static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 }; + +static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk) +{ + unsigned long acsr = ACSR; + unsigned long memclkcfg = __raw_readl(MEMCLKCFG); + unsigned int smcfs = (acsr >> 23) & 0x7; + + return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] / + df_clkdiv[(memclkcfg >> 16) & 0x3]; +} + void clk_pxa3xx_cken_enable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); @@ -145,6 +158,12 @@ const struct clkops clk_pxa3xx_ac97_ops = { .getrate = clk_pxa3xx_ac97_getrate, }; +const struct clkops clk_pxa3xx_smemc_ops = { + .enable = clk_pxa3xx_cken_enable, + .disable = clk_pxa3xx_cken_disable, + .getrate = clk_pxa3xx_smemc_getrate, +}; + static void clk_pout_enable(struct clk *clk) { OSCC |= OSCC_PEN; diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index 3a607521dc2..6e949944f2e 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -69,6 +69,7 @@ extern const struct clkops clk_pxa3xx_cken_ops; extern const struct clkops clk_pxa3xx_hsio_ops; extern const struct clkops clk_pxa3xx_ac97_ops; extern const struct clkops clk_pxa3xx_pout_ops; +extern const struct clkops clk_pxa3xx_smemc_ops; extern void clk_pxa3xx_cken_enable(struct clk *); extern void clk_pxa3xx_cken_disable(struct clk *); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index da3edcc9ac7..e14818f5d95 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -59,6 +59,7 @@ static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); +static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70); @@ -87,6 +88,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), + INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), }; #ifdef CONFIG_PM |