diff options
Diffstat (limited to 'arch/arm/mach-pxa/pxa3xx.c')
-rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 234 |
1 files changed, 28 insertions, 206 deletions
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index d1c747cdacf8..e14818f5d950 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -22,6 +22,7 @@ #include <linux/io.h> #include <linux/sysdev.h> +#include <asm/mach/map.h> #include <mach/hardware.h> #include <mach/gpio.h> #include <mach/pxa3xx-regs.h> @@ -30,193 +31,16 @@ #include <mach/pm.h> #include <mach/dma.h> #include <mach/regs-intc.h> +#include <mach/smemc.h> #include <plat/i2c.h> #include "generic.h" #include "devices.h" #include "clock.h" -/* Crystal clock: 13MHz */ -#define BASE_CLK 13000000 - -/* Ring Oscillator Clock: 60MHz */ -#define RO_CLK 60000000 - -#define ACCR_D0CS (1 << 26) -#define ACCR_PCCE (1 << 11) - #define PECR_IE(n) ((1 << ((n) * 2)) << 28) #define PECR_IS(n) ((1 << ((n) * 2)) << 29) -/* 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 }; - -/* - * Get the clock frequency as reflected by CCSR and the turbo flag. - * We assume these values have been applied via a fcs. - * If info is not 0 we also display the current settings. - */ -unsigned int pxa3xx_get_clk_frequency_khz(int info) -{ - unsigned long acsr, xclkcfg; - unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; - - /* Read XCLKCFG register turbo bit */ - __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); - t = xclkcfg & 0x1; - - acsr = ACSR; - - xl = acsr & 0x1f; - xn = (acsr >> 8) & 0x7; - hss = (acsr >> 14) & 0x3; - - XL = xl * BASE_CLK; - XN = xn * XL; - - ro = acsr & ACCR_D0CS; - - CLK = (ro) ? RO_CLK : ((t) ? XN : XL); - HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; - - if (info) { - pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", - RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, - (ro) ? "" : "in"); - pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", - XL / 1000000, (XL % 1000000) / 10000, xl); - pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", - XN / 1000000, (XN % 1000000) / 10000, xn, - (t) ? "" : "in"); - pr_info("HSIO bus clock: %d.%02dMHz\n", - HSS / 1000000, (HSS % 1000000) / 10000); - } - - return CLK / 1000; -} - -void pxa3xx_clear_reset_status(unsigned int mask) -{ - /* RESET_STATUS_* has a 1:1 mapping with ARSR */ - ARSR = mask; -} - -/* - * Return the current AC97 clock frequency. - */ -static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) -{ - unsigned long rate = 312000000; - unsigned long ac97_div; - - ac97_div = AC97_DIV; - - /* This may loose precision for some rates but won't for the - * standard 24.576MHz. - */ - rate /= (ac97_div >> 12) & 0x7fff; - rate *= (ac97_div & 0xfff); - - return rate; -} - -/* - * Return the current HSIO bus clock frequency - */ -static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) -{ - unsigned long acsr; - unsigned int hss, hsio_clk; - - acsr = ACSR; - - hss = (acsr >> 14) & 0x3; - hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; - - return hsio_clk; -} - -void clk_pxa3xx_cken_enable(struct clk *clk) -{ - unsigned long mask = 1ul << (clk->cken & 0x1f); - - if (clk->cken < 32) - CKENA |= mask; - else - CKENB |= mask; -} - -void clk_pxa3xx_cken_disable(struct clk *clk) -{ - unsigned long mask = 1ul << (clk->cken & 0x1f); - - if (clk->cken < 32) - CKENA &= ~mask; - else - CKENB &= ~mask; -} - -const struct clkops clk_pxa3xx_cken_ops = { - .enable = clk_pxa3xx_cken_enable, - .disable = clk_pxa3xx_cken_disable, -}; - -static const struct clkops clk_pxa3xx_hsio_ops = { - .enable = clk_pxa3xx_cken_enable, - .disable = clk_pxa3xx_cken_disable, - .getrate = clk_pxa3xx_hsio_getrate, -}; - -static const struct clkops clk_pxa3xx_ac97_ops = { - .enable = clk_pxa3xx_cken_enable, - .disable = clk_pxa3xx_cken_disable, - .getrate = clk_pxa3xx_ac97_getrate, -}; - -static void clk_pout_enable(struct clk *clk) -{ - OSCC |= OSCC_PEN; -} - -static void clk_pout_disable(struct clk *clk) -{ - OSCC &= ~OSCC_PEN; -} - -static const struct clkops clk_pout_ops = { - .enable = clk_pout_enable, - .disable = clk_pout_disable, -}; - -static void clk_dummy_enable(struct clk *clk) -{ -} - -static void clk_dummy_disable(struct clk *clk) -{ -} - -static const struct clkops clk_dummy_ops = { - .enable = clk_dummy_enable, - .disable = clk_dummy_disable, -}; - -static struct clk clk_pxa3xx_pout = { - .ops = &clk_pout_ops, - .rate = 13000000, - .delay = 70, -}; - -static struct clk clk_dummy = { - .ops = &clk_dummy_ops, -}; - -static DEFINE_PXA3_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); -static DEFINE_PXA3_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); -static DEFINE_PXA3_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); @@ -234,6 +58,12 @@ static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); 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); + static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), /* Power I2C clock is always on */ @@ -258,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 @@ -268,30 +99,6 @@ static struct clk_lookup pxa3xx_clkregs[] = { static void __iomem *sram; static unsigned long wakeup_src; -#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x -#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] - -enum { SLEEP_SAVE_CKENA, - SLEEP_SAVE_CKENB, - SLEEP_SAVE_ACCR, - - SLEEP_SAVE_COUNT, -}; - -static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) -{ - SAVE(CKENA); - SAVE(CKENB); - SAVE(ACCR); -} - -static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) -{ - RESTORE(ACCR); - RESTORE(CKENA); - RESTORE(CKENB); -} - /* * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic * memory controller has to be reinitialised, so we place some code @@ -390,9 +197,6 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { - .save_count = SLEEP_SAVE_COUNT, - .save = pxa3xx_cpu_pm_save, - .restore = pxa3xx_cpu_pm_restore, .valid = pxa3xx_cpu_pm_valid, .enter = pxa3xx_cpu_pm_enter, }; @@ -580,6 +384,22 @@ void __init pxa3xx_init_irq(void) pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); } +static struct map_desc pxa3xx_io_desc[] __initdata = { + { /* Mem Ctl */ + .virtual = SMEMC_VIRT, + .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE), + .length = 0x00200000, + .type = MT_DEVICE + } +}; + +void __init pxa3xx_map_io(void) +{ + pxa_map_io(); + iotable_init(ARRAY_AND_SIZE(pxa3xx_io_desc)); + pxa3xx_get_clk_frequency_khz(1); +} + /* * device registration specific to PXA3xx. */ @@ -615,7 +435,9 @@ static struct sys_device pxa3xx_sysdev[] = { .cls = &pxa3xx_mfp_sysclass, }, { .cls = &pxa_gpio_sysclass, - }, + }, { + .cls = &pxa3xx_clock_sysclass, + } }; static int __init pxa3xx_init(void) |