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 @@ | |||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/sysdev.h> | 23 | #include <linux/sysdev.h> |
24 | 24 | ||
25 | #include <asm/mach/map.h> | ||
25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
26 | #include <mach/gpio.h> | 27 | #include <mach/gpio.h> |
27 | #include <mach/pxa3xx-regs.h> | 28 | #include <mach/pxa3xx-regs.h> |
@@ -30,193 +31,16 @@ | |||
30 | #include <mach/pm.h> | 31 | #include <mach/pm.h> |
31 | #include <mach/dma.h> | 32 | #include <mach/dma.h> |
32 | #include <mach/regs-intc.h> | 33 | #include <mach/regs-intc.h> |
34 | #include <mach/smemc.h> | ||
33 | #include <plat/i2c.h> | 35 | #include <plat/i2c.h> |
34 | 36 | ||
35 | #include "generic.h" | 37 | #include "generic.h" |
36 | #include "devices.h" | 38 | #include "devices.h" |
37 | #include "clock.h" | 39 | #include "clock.h" |
38 | 40 | ||
39 | /* Crystal clock: 13MHz */ | ||
40 | #define BASE_CLK 13000000 | ||
41 | |||
42 | /* Ring Oscillator Clock: 60MHz */ | ||
43 | #define RO_CLK 60000000 | ||
44 | |||
45 | #define ACCR_D0CS (1 << 26) | ||
46 | #define ACCR_PCCE (1 << 11) | ||
47 | |||
48 | #define PECR_IE(n) ((1 << ((n) * 2)) << 28) | 41 | #define PECR_IE(n) ((1 << ((n) * 2)) << 28) |
49 | #define PECR_IS(n) ((1 << ((n) * 2)) << 29) | 42 | #define PECR_IS(n) ((1 << ((n) * 2)) << 29) |
50 | 43 | ||
51 | /* crystal frequency to static memory controller multiplier (SMCFS) */ | ||
52 | static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; | ||
53 | |||
54 | /* crystal frequency to HSIO bus frequency multiplier (HSS) */ | ||
55 | static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; | ||
56 | |||
57 | /* | ||
58 | * Get the clock frequency as reflected by CCSR and the turbo flag. | ||
59 | * We assume these values have been applied via a fcs. | ||
60 | * If info is not 0 we also display the current settings. | ||
61 | */ | ||
62 | unsigned int pxa3xx_get_clk_frequency_khz(int info) | ||
63 | { | ||
64 | unsigned long acsr, xclkcfg; | ||
65 | unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; | ||
66 | |||
67 | /* Read XCLKCFG register turbo bit */ | ||
68 | __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); | ||
69 | t = xclkcfg & 0x1; | ||
70 | |||
71 | acsr = ACSR; | ||
72 | |||
73 | xl = acsr & 0x1f; | ||
74 | xn = (acsr >> 8) & 0x7; | ||
75 | hss = (acsr >> 14) & 0x3; | ||
76 | |||
77 | XL = xl * BASE_CLK; | ||
78 | XN = xn * XL; | ||
79 | |||
80 | ro = acsr & ACCR_D0CS; | ||
81 | |||
82 | CLK = (ro) ? RO_CLK : ((t) ? XN : XL); | ||
83 | HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; | ||
84 | |||
85 | if (info) { | ||
86 | pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", | ||
87 | RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, | ||
88 | (ro) ? "" : "in"); | ||
89 | pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", | ||
90 | XL / 1000000, (XL % 1000000) / 10000, xl); | ||
91 | pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", | ||
92 | XN / 1000000, (XN % 1000000) / 10000, xn, | ||
93 | (t) ? "" : "in"); | ||
94 | pr_info("HSIO bus clock: %d.%02dMHz\n", | ||
95 | HSS / 1000000, (HSS % 1000000) / 10000); | ||
96 | } | ||
97 | |||
98 | return CLK / 1000; | ||
99 | } | ||
100 | |||
101 | void pxa3xx_clear_reset_status(unsigned int mask) | ||
102 | { | ||
103 | /* RESET_STATUS_* has a 1:1 mapping with ARSR */ | ||
104 | ARSR = mask; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Return the current AC97 clock frequency. | ||
109 | */ | ||
110 | static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) | ||
111 | { | ||
112 | unsigned long rate = 312000000; | ||
113 | unsigned long ac97_div; | ||
114 | |||
115 | ac97_div = AC97_DIV; | ||
116 | |||
117 | /* This may loose precision for some rates but won't for the | ||
118 | * standard 24.576MHz. | ||
119 | */ | ||
120 | rate /= (ac97_div >> 12) & 0x7fff; | ||
121 | rate *= (ac97_div & 0xfff); | ||
122 | |||
123 | return rate; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Return the current HSIO bus clock frequency | ||
128 | */ | ||
129 | static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) | ||
130 | { | ||
131 | unsigned long acsr; | ||
132 | unsigned int hss, hsio_clk; | ||
133 | |||
134 | acsr = ACSR; | ||
135 | |||
136 | hss = (acsr >> 14) & 0x3; | ||
137 | hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; | ||
138 | |||
139 | return hsio_clk; | ||
140 | } | ||
141 | |||
142 | void clk_pxa3xx_cken_enable(struct clk *clk) | ||
143 | { | ||
144 | unsigned long mask = 1ul << (clk->cken & 0x1f); | ||
145 | |||
146 | if (clk->cken < 32) | ||
147 | CKENA |= mask; | ||
148 | else | ||
149 | CKENB |= mask; | ||
150 | } | ||
151 | |||
152 | void clk_pxa3xx_cken_disable(struct clk *clk) | ||
153 | { | ||
154 | unsigned long mask = 1ul << (clk->cken & 0x1f); | ||
155 | |||
156 | if (clk->cken < 32) | ||
157 | CKENA &= ~mask; | ||
158 | else | ||
159 | CKENB &= ~mask; | ||
160 | } | ||
161 | |||
162 | const struct clkops clk_pxa3xx_cken_ops = { | ||
163 | .enable = clk_pxa3xx_cken_enable, | ||
164 | .disable = clk_pxa3xx_cken_disable, | ||
165 | }; | ||
166 | |||
167 | static const struct clkops clk_pxa3xx_hsio_ops = { | ||
168 | .enable = clk_pxa3xx_cken_enable, | ||
169 | .disable = clk_pxa3xx_cken_disable, | ||
170 | .getrate = clk_pxa3xx_hsio_getrate, | ||
171 | }; | ||
172 | |||
173 | static const struct clkops clk_pxa3xx_ac97_ops = { | ||
174 | .enable = clk_pxa3xx_cken_enable, | ||
175 | .disable = clk_pxa3xx_cken_disable, | ||
176 | .getrate = clk_pxa3xx_ac97_getrate, | ||
177 | }; | ||
178 | |||
179 | static void clk_pout_enable(struct clk *clk) | ||
180 | { | ||
181 | OSCC |= OSCC_PEN; | ||
182 | } | ||
183 | |||
184 | static void clk_pout_disable(struct clk *clk) | ||
185 | { | ||
186 | OSCC &= ~OSCC_PEN; | ||
187 | } | ||
188 | |||
189 | static const struct clkops clk_pout_ops = { | ||
190 | .enable = clk_pout_enable, | ||
191 | .disable = clk_pout_disable, | ||
192 | }; | ||
193 | |||
194 | static void clk_dummy_enable(struct clk *clk) | ||
195 | { | ||
196 | } | ||
197 | |||
198 | static void clk_dummy_disable(struct clk *clk) | ||
199 | { | ||
200 | } | ||
201 | |||
202 | static const struct clkops clk_dummy_ops = { | ||
203 | .enable = clk_dummy_enable, | ||
204 | .disable = clk_dummy_disable, | ||
205 | }; | ||
206 | |||
207 | static struct clk clk_pxa3xx_pout = { | ||
208 | .ops = &clk_pout_ops, | ||
209 | .rate = 13000000, | ||
210 | .delay = 70, | ||
211 | }; | ||
212 | |||
213 | static struct clk clk_dummy = { | ||
214 | .ops = &clk_dummy_ops, | ||
215 | }; | ||
216 | |||
217 | static DEFINE_PXA3_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); | ||
218 | static DEFINE_PXA3_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); | ||
219 | static DEFINE_PXA3_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); | ||
220 | static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); | 44 | static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); |
221 | static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); | 45 | static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); |
222 | static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); | 46 | static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); |
@@ -234,6 +58,12 @@ static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); | |||
234 | static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); | 58 | static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); |
235 | static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); | 59 | static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); |
236 | 60 | ||
61 | static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); | ||
62 | static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); | ||
63 | static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); | ||
64 | static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); | ||
65 | static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70); | ||
66 | |||
237 | static struct clk_lookup pxa3xx_clkregs[] = { | 67 | static struct clk_lookup pxa3xx_clkregs[] = { |
238 | INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), | 68 | INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), |
239 | /* Power I2C clock is always on */ | 69 | /* Power I2C clock is always on */ |
@@ -258,6 +88,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { | |||
258 | INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), | 88 | INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), |
259 | INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), | 89 | INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), |
260 | INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), | 90 | INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), |
91 | INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), | ||
261 | }; | 92 | }; |
262 | 93 | ||
263 | #ifdef CONFIG_PM | 94 | #ifdef CONFIG_PM |
@@ -268,30 +99,6 @@ static struct clk_lookup pxa3xx_clkregs[] = { | |||
268 | static void __iomem *sram; | 99 | static void __iomem *sram; |
269 | static unsigned long wakeup_src; | 100 | static unsigned long wakeup_src; |
270 | 101 | ||
271 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | ||
272 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | ||
273 | |||
274 | enum { SLEEP_SAVE_CKENA, | ||
275 | SLEEP_SAVE_CKENB, | ||
276 | SLEEP_SAVE_ACCR, | ||
277 | |||
278 | SLEEP_SAVE_COUNT, | ||
279 | }; | ||
280 | |||
281 | static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) | ||
282 | { | ||
283 | SAVE(CKENA); | ||
284 | SAVE(CKENB); | ||
285 | SAVE(ACCR); | ||
286 | } | ||
287 | |||
288 | static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) | ||
289 | { | ||
290 | RESTORE(ACCR); | ||
291 | RESTORE(CKENA); | ||
292 | RESTORE(CKENB); | ||
293 | } | ||
294 | |||
295 | /* | 102 | /* |
296 | * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic | 103 | * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic |
297 | * memory controller has to be reinitialised, so we place some code | 104 | * 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) | |||
390 | } | 197 | } |
391 | 198 | ||
392 | static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { | 199 | static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { |
393 | .save_count = SLEEP_SAVE_COUNT, | ||
394 | .save = pxa3xx_cpu_pm_save, | ||
395 | .restore = pxa3xx_cpu_pm_restore, | ||
396 | .valid = pxa3xx_cpu_pm_valid, | 200 | .valid = pxa3xx_cpu_pm_valid, |
397 | .enter = pxa3xx_cpu_pm_enter, | 201 | .enter = pxa3xx_cpu_pm_enter, |
398 | }; | 202 | }; |
@@ -580,6 +384,22 @@ void __init pxa3xx_init_irq(void) | |||
580 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); | 384 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); |
581 | } | 385 | } |
582 | 386 | ||
387 | static struct map_desc pxa3xx_io_desc[] __initdata = { | ||
388 | { /* Mem Ctl */ | ||
389 | .virtual = SMEMC_VIRT, | ||
390 | .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE), | ||
391 | .length = 0x00200000, | ||
392 | .type = MT_DEVICE | ||
393 | } | ||
394 | }; | ||
395 | |||
396 | void __init pxa3xx_map_io(void) | ||
397 | { | ||
398 | pxa_map_io(); | ||
399 | iotable_init(ARRAY_AND_SIZE(pxa3xx_io_desc)); | ||
400 | pxa3xx_get_clk_frequency_khz(1); | ||
401 | } | ||
402 | |||
583 | /* | 403 | /* |
584 | * device registration specific to PXA3xx. | 404 | * device registration specific to PXA3xx. |
585 | */ | 405 | */ |
@@ -615,7 +435,9 @@ static struct sys_device pxa3xx_sysdev[] = { | |||
615 | .cls = &pxa3xx_mfp_sysclass, | 435 | .cls = &pxa3xx_mfp_sysclass, |
616 | }, { | 436 | }, { |
617 | .cls = &pxa_gpio_sysclass, | 437 | .cls = &pxa_gpio_sysclass, |
618 | }, | 438 | }, { |
439 | .cls = &pxa3xx_clock_sysclass, | ||
440 | } | ||
619 | }; | 441 | }; |
620 | 442 | ||
621 | static int __init pxa3xx_init(void) | 443 | static int __init pxa3xx_init(void) |