diff options
Diffstat (limited to 'arch/arm/mach-pxa/pxa27x.c')
-rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 127 |
1 files changed, 112 insertions, 15 deletions
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 203371ab19db..2d7fc39732e4 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include "generic.h" | 28 | #include "generic.h" |
29 | #include "devices.h" | 29 | #include "devices.h" |
30 | #include "clock.h" | ||
30 | 31 | ||
31 | /* Crystal clock: 13MHz */ | 32 | /* Crystal clock: 13MHz */ |
32 | #define BASE_CLK 13000000 | 33 | #define BASE_CLK 13000000 |
@@ -36,7 +37,7 @@ | |||
36 | * We assume these values have been applied via a fcs. | 37 | * We assume these values have been applied via a fcs. |
37 | * If info is not 0 we also display the current settings. | 38 | * If info is not 0 we also display the current settings. |
38 | */ | 39 | */ |
39 | unsigned int get_clk_frequency_khz( int info) | 40 | unsigned int pxa27x_get_clk_frequency_khz(int info) |
40 | { | 41 | { |
41 | unsigned long ccsr, clkcfg; | 42 | unsigned long ccsr, clkcfg; |
42 | unsigned int l, L, m, M, n2, N, S; | 43 | unsigned int l, L, m, M, n2, N, S; |
@@ -79,7 +80,7 @@ unsigned int get_clk_frequency_khz( int info) | |||
79 | * Return the current mem clock frequency in units of 10kHz as | 80 | * Return the current mem clock frequency in units of 10kHz as |
80 | * reflected by CCCR[A], B, and L | 81 | * reflected by CCCR[A], B, and L |
81 | */ | 82 | */ |
82 | unsigned int get_memclk_frequency_10khz(void) | 83 | unsigned int pxa27x_get_memclk_frequency_10khz(void) |
83 | { | 84 | { |
84 | unsigned long ccsr, clkcfg; | 85 | unsigned long ccsr, clkcfg; |
85 | unsigned int l, L, m, M; | 86 | unsigned int l, L, m, M; |
@@ -104,7 +105,7 @@ unsigned int get_memclk_frequency_10khz(void) | |||
104 | /* | 105 | /* |
105 | * Return the current LCD clock frequency in units of 10kHz as | 106 | * Return the current LCD clock frequency in units of 10kHz as |
106 | */ | 107 | */ |
107 | unsigned int get_lcdclk_frequency_10khz(void) | 108 | static unsigned int pxa27x_get_lcdclk_frequency_10khz(void) |
108 | { | 109 | { |
109 | unsigned long ccsr; | 110 | unsigned long ccsr; |
110 | unsigned int l, L, k, K; | 111 | unsigned int l, L, k, K; |
@@ -120,9 +121,47 @@ unsigned int get_lcdclk_frequency_10khz(void) | |||
120 | return (K / 10000); | 121 | return (K / 10000); |
121 | } | 122 | } |
122 | 123 | ||
123 | EXPORT_SYMBOL(get_clk_frequency_khz); | 124 | static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) |
124 | EXPORT_SYMBOL(get_memclk_frequency_10khz); | 125 | { |
125 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | 126 | return pxa27x_get_lcdclk_frequency_10khz() * 10000; |
127 | } | ||
128 | |||
129 | static const struct clkops clk_pxa27x_lcd_ops = { | ||
130 | .enable = clk_cken_enable, | ||
131 | .disable = clk_cken_disable, | ||
132 | .getrate = clk_pxa27x_lcd_getrate, | ||
133 | }; | ||
134 | |||
135 | static struct clk pxa27x_clks[] = { | ||
136 | INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev), | ||
137 | INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL), | ||
138 | |||
139 | INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), | ||
140 | INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), | ||
141 | INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), | ||
142 | |||
143 | INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), | ||
144 | INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), | ||
145 | INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev), | ||
146 | INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), | ||
147 | INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), | ||
148 | |||
149 | INIT_CKEN("USBCLK", USB, 48000000, 0, &pxa27x_device_ohci.dev), | ||
150 | INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), | ||
151 | INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), | ||
152 | |||
153 | /* | ||
154 | INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), | ||
155 | INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL), | ||
156 | INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL), | ||
157 | INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL), | ||
158 | INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), | ||
159 | INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), | ||
160 | INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), | ||
161 | INIT_CKEN("IMCLK", IM, 0, 0, NULL), | ||
162 | INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL), | ||
163 | */ | ||
164 | }; | ||
126 | 165 | ||
127 | #ifdef CONFIG_PM | 166 | #ifdef CONFIG_PM |
128 | 167 | ||
@@ -267,6 +306,69 @@ static void __init pxa27x_init_pm(void) | |||
267 | } | 306 | } |
268 | #endif | 307 | #endif |
269 | 308 | ||
309 | /* PXA27x: Various gpios can issue wakeup events. This logic only | ||
310 | * handles the simple cases, not the WEMUX2 and WEMUX3 options | ||
311 | */ | ||
312 | #define PXA27x_GPIO_NOWAKE_MASK \ | ||
313 | ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) | ||
314 | #define WAKEMASK(gpio) \ | ||
315 | (((gpio) <= 15) \ | ||
316 | ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ | ||
317 | : ((gpio == 35) ? (1 << 24) : 0)) | ||
318 | |||
319 | static int pxa27x_set_wake(unsigned int irq, unsigned int on) | ||
320 | { | ||
321 | int gpio = IRQ_TO_GPIO(irq); | ||
322 | uint32_t mask; | ||
323 | |||
324 | if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) { | ||
325 | if (WAKEMASK(gpio) == 0) | ||
326 | return -EINVAL; | ||
327 | |||
328 | mask = WAKEMASK(gpio); | ||
329 | |||
330 | if (on) { | ||
331 | if (GRER(gpio) | GPIO_bit(gpio)) | ||
332 | PRER |= mask; | ||
333 | else | ||
334 | PRER &= ~mask; | ||
335 | |||
336 | if (GFER(gpio) | GPIO_bit(gpio)) | ||
337 | PFER |= mask; | ||
338 | else | ||
339 | PFER &= ~mask; | ||
340 | } | ||
341 | goto set_pwer; | ||
342 | } | ||
343 | |||
344 | switch (irq) { | ||
345 | case IRQ_RTCAlrm: | ||
346 | mask = PWER_RTC; | ||
347 | break; | ||
348 | case IRQ_USB: | ||
349 | mask = 1u << 26; | ||
350 | break; | ||
351 | default: | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | set_pwer: | ||
356 | if (on) | ||
357 | PWER |= mask; | ||
358 | else | ||
359 | PWER &=~mask; | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | void __init pxa27x_init_irq(void) | ||
365 | { | ||
366 | pxa_init_irq_low(); | ||
367 | pxa_init_irq_high(); | ||
368 | pxa_init_irq_gpio(128); | ||
369 | pxa_init_irq_set_wake(pxa27x_set_wake); | ||
370 | } | ||
371 | |||
270 | /* | 372 | /* |
271 | * device registration specific to PXA27x. | 373 | * device registration specific to PXA27x. |
272 | */ | 374 | */ |
@@ -286,7 +388,7 @@ static struct resource pxa27x_ohci_resources[] = { | |||
286 | }, | 388 | }, |
287 | }; | 389 | }; |
288 | 390 | ||
289 | static struct platform_device pxa27x_device_ohci = { | 391 | struct platform_device pxa27x_device_ohci = { |
290 | .name = "pxa27x-ohci", | 392 | .name = "pxa27x-ohci", |
291 | .id = -1, | 393 | .id = -1, |
292 | .dev = { | 394 | .dev = { |
@@ -314,7 +416,7 @@ static struct resource i2c_power_resources[] = { | |||
314 | }, | 416 | }, |
315 | }; | 417 | }; |
316 | 418 | ||
317 | static struct platform_device pxa27x_device_i2c_power = { | 419 | struct platform_device pxa27x_device_i2c_power = { |
318 | .name = "pxa2xx-i2c", | 420 | .name = "pxa2xx-i2c", |
319 | .id = 1, | 421 | .id = 1, |
320 | .resource = i2c_power_resources, | 422 | .resource = i2c_power_resources, |
@@ -336,17 +438,12 @@ static struct platform_device *devices[] __initdata = { | |||
336 | &pxa27x_device_ohci, | 438 | &pxa27x_device_ohci, |
337 | }; | 439 | }; |
338 | 440 | ||
339 | void __init pxa27x_init_irq(void) | ||
340 | { | ||
341 | pxa_init_irq_low(); | ||
342 | pxa_init_irq_high(); | ||
343 | pxa_init_irq_gpio(128); | ||
344 | } | ||
345 | |||
346 | static int __init pxa27x_init(void) | 441 | static int __init pxa27x_init(void) |
347 | { | 442 | { |
348 | int ret = 0; | 443 | int ret = 0; |
349 | if (cpu_is_pxa27x()) { | 444 | if (cpu_is_pxa27x()) { |
445 | clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); | ||
446 | |||
350 | if ((ret = pxa_init_dma(32))) | 447 | if ((ret = pxa_init_dma(32))) |
351 | return ret; | 448 | return ret; |
352 | #ifdef CONFIG_PM | 449 | #ifdef CONFIG_PM |