import hh.org
[hh.org.git] / arch / arm / mach-pxa / generic.c
blob10194b8b69ec9e25cd3380a10ccc8e837d7f28c0
1 /*
2 * linux/arch/arm/mach-pxa/generic.c
4 * Author: Nicolas Pitre
5 * Created: Jun 15, 2001
6 * Copyright: MontaVista Software Inc.
8 * Code common to all PXA machines.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
14 * Since this file should be linked before any other machine specific file,
15 * the __initcall() here will be executed first. This serves as default
16 * initialization stuff for PXA machines which can be overridden later if
17 * need be.
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
23 #include <linux/platform_device.h>
24 #include <linux/ioport.h>
25 #include <linux/pm.h>
26 #include <linux/string.h>
28 #include <asm/hardware.h>
29 #include <asm/irq.h>
30 #include <asm/system.h>
31 #include <asm/pgtable.h>
32 #include <asm/mach/map.h>
34 #include <asm/arch/pxa-regs.h>
35 #include <asm/arch/udc.h>
36 #include <asm/arch/pxafb.h>
37 #include <asm/arch/mmc.h>
38 #include <asm/arch/irda.h>
39 #include <asm/arch/i2c.h>
41 #include "generic.h"
44 * Handy function to set GPIO alternate functions.
46 * It can be used to set / clear GPIO bits as well as change their alt-fn,
47 * but it can also do one of those things without doing the other.
49 * Parameters:
51 * gpio: the pin number (integer between 1 and e.g. 86 for pxa-263)
53 * mask_ops: (GPIO_MD_MASK_DIR) ORed with Alt-GPIO selection (GPIO_MD_MASK_NR)
55 * set GPIO_MD_MASK_DIR for the gpio pin to be input or output.
56 * set GPIO_MD_MASK_NR for function (alt-gpio) to be changed.
57 * set GPIO_MD_MASK_SET for the gpio pin to be set or cleared.
59 * ops_fn : the actual operations you want to be carried out.
61 * e.g. if you want the gpio pin to be an output, set GPIO_OUT
62 * (and obviously set mask_ops = GPIO_MD_MASK_DIR).
64 * but if you want the gpio pin to be an input, CLEAR GPIO_MD_MASK_DIR in
65 * the ops_fn argument but *set* the GPIO_MD_MASK_DIR bit in mask_ops
67 * e.g. if you want the gpio pin to be high, set GPIO_MD_MASK_SET
68 * (and obviously set mask_ops = GPIO_MD_HIGH).
70 * but if you want the gpio pin to be low, CLEAR GPIO_MD_HIGH in
71 * the ops_fn argument but *set* the GPIO_MD_MASK_SET bit in mask_ops
73 * e.g. if you want the alt-gpio to be set to ALT_FN_1_OUT
74 * then set ops_fn = GPIO_ALT_FN_1_OUT (and obviously also
75 * set bits GPIO_MD_MASK_NR in mask_ops.
77 * to use this function in the same way as the legacy pxa_gpio_mode,
78 * pxa_gpio_op(gpio_ops,
79 * GPIO_MD_MASK_DIR | GPIO_MD_MASK_NR | GPIO_MD_MASK_SET,
80 * gpio_ops)
81 * will do the trick.
85 void pxa_gpio_op(int gpio, int mask_ops, int ops_fn)
87 unsigned long flags;
88 int fn = (ops_fn & GPIO_MD_MASK_FN) >> 8;
89 int gafr;
91 gpio = gpio & GPIO_MD_MASK_NR; // mask out gpio number in case someone
92 // gets confused between this and the
93 // older function, pxa_gpio_mode
95 local_irq_save(flags);
97 // did you want to raise or lower the state of a GPIO pin? if so,
98 // set any bit in the mask_ops that matches GPIO_MD_MASK_SET.
100 if (mask_ops & GPIO_MD_MASK_SET)
102 if (ops_fn & GPIO_MD_HIGH)
103 GPSR(gpio) |= GPIO_bit(gpio);
104 else
105 GPCR(gpio) |= GPIO_bit(gpio);
108 // did you want to change the direction (in/out) of a GPIO pin? if so,
109 // set any bit in the mask_ops that matches GPIO_MD_MASK_DIR.
111 if (mask_ops & GPIO_MD_MASK_DIR)
113 if (ops_fn & GPIO_MD_MASK_DIR) {
114 /* if output and active low, then first set the bit to make it inactive */
115 if (ops_fn & GPIO_ACTIVE_LOW)
116 GPSR(gpio) |= GPIO_bit(gpio);
117 GPDR(gpio) |= GPIO_bit(gpio);
118 } else
119 GPDR(gpio) &= ~GPIO_bit(gpio);
122 // did you want to set (or clear) alt-io? if so, set any bit
123 // in the mask_ops that matches GPIO_MD_MASK_NR e.g OR in the
124 // gpio number itself would do the trick
126 if (mask_ops & GPIO_MD_MASK_NR)
128 gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
129 GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
132 local_irq_restore(flags);
135 EXPORT_SYMBOL(pxa_gpio_op);
138 * Handy function to set GPIO alternate functions
141 void pxa_gpio_mode(int gpio_mode)
143 unsigned long flags;
144 int gpio = gpio_mode & GPIO_MD_MASK_NR;
145 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
146 int gafr;
148 local_irq_save(flags);
149 if (gpio_mode & GPIO_DFLT_LOW)
150 GPCR(gpio) = GPIO_bit(gpio);
151 else if (gpio_mode & GPIO_DFLT_HIGH)
152 GPSR(gpio) = GPIO_bit(gpio);
153 if (gpio_mode & GPIO_MD_MASK_DIR)
154 GPDR(gpio) |= GPIO_bit(gpio);
155 else
156 GPDR(gpio) &= ~GPIO_bit(gpio);
157 gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
158 GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
159 local_irq_restore(flags);
162 EXPORT_SYMBOL(pxa_gpio_mode);
165 * Routine to safely enable or disable a clock in the CKEN
167 void pxa_set_cken(int clock, int enable)
169 unsigned long flags;
170 local_irq_save(flags);
172 if (enable)
173 CKEN |= clock;
174 else
175 CKEN &= ~clock;
177 local_irq_restore(flags);
180 EXPORT_SYMBOL(pxa_set_cken);
183 * Intel PXA2xx internal register mapping.
185 * Note 1: not all PXA2xx variants implement all those addresses.
187 * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table
188 * and cache flush area.
190 static struct map_desc standard_io_desc[] __initdata = {
191 { /* Devs */
192 .virtual = 0xf2000000,
193 .pfn = __phys_to_pfn(0x40000000),
194 .length = 0x02000000,
195 .type = MT_DEVICE
196 }, { /* LCD */
197 .virtual = 0xf4000000,
198 .pfn = __phys_to_pfn(0x44000000),
199 .length = 0x00100000,
200 .type = MT_DEVICE
201 }, { /* Mem Ctl */
202 .virtual = 0xf6000000,
203 .pfn = __phys_to_pfn(0x48000000),
204 .length = 0x00100000,
205 .type = MT_DEVICE
206 }, { /* USB host */
207 .virtual = 0xf8000000,
208 .pfn = __phys_to_pfn(0x4c000000),
209 .length = 0x00100000,
210 .type = MT_DEVICE
211 }, { /* Camera */
212 .virtual = 0xfa000000,
213 .pfn = __phys_to_pfn(0x50000000),
214 .length = 0x00100000,
215 .type = MT_DEVICE
216 }, { /* IMem ctl */
217 .virtual = 0xfe000000,
218 .pfn = __phys_to_pfn(0x58000000),
219 .length = 0x00100000,
220 .type = MT_DEVICE
221 }, { /* UNCACHED_PHYS_0 */
222 .virtual = 0xff000000,
223 .pfn = __phys_to_pfn(0x00000000),
224 .length = 0x00100000,
225 .type = MT_DEVICE
229 void __init pxa_map_io(void)
231 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
232 get_clk_frequency_khz(1);
236 static struct resource pxamci_resources[] = {
237 [0] = {
238 .start = 0x41100000,
239 .end = 0x41100fff,
240 .flags = IORESOURCE_MEM,
242 [1] = {
243 .start = IRQ_MMC,
244 .end = IRQ_MMC,
245 .flags = IORESOURCE_IRQ,
249 static u64 pxamci_dmamask = 0xffffffffUL;
251 static struct platform_device pxamci_device = {
252 .name = "pxa2xx-mci",
253 .id = -1,
254 .dev = {
255 .dma_mask = &pxamci_dmamask,
256 .coherent_dma_mask = 0xffffffff,
258 .num_resources = ARRAY_SIZE(pxamci_resources),
259 .resource = pxamci_resources,
262 void __init pxa_set_mci_info(struct pxamci_platform_data *info)
264 pxamci_device.dev.platform_data = info;
268 static struct pxa2xx_udc_mach_info pxa_udc_info;
270 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
272 memcpy(&pxa_udc_info, info, sizeof *info);
274 EXPORT_SYMBOL(pxa_set_udc_info);
276 static struct resource pxa2xx_udc_resources[] = {
277 [0] = {
278 .start = 0x40600000,
279 .end = 0x4060ffff,
280 .flags = IORESOURCE_MEM,
282 [1] = {
283 .start = IRQ_USB,
284 .end = IRQ_USB,
285 .flags = IORESOURCE_IRQ,
289 static u64 udc_dma_mask = ~(u32)0;
291 static struct platform_device udc_device = {
292 .name = "pxa2xx-udc",
293 .id = -1,
294 .resource = pxa2xx_udc_resources,
295 .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
296 .dev = {
297 .platform_data = &pxa_udc_info,
298 .dma_mask = &udc_dma_mask,
302 static struct resource pxafb_resources[] = {
303 [0] = {
304 .start = 0x44000000,
305 .end = 0x4400ffff,
306 .flags = IORESOURCE_MEM,
308 [1] = {
309 .start = IRQ_LCD,
310 .end = IRQ_LCD,
311 .flags = IORESOURCE_IRQ,
315 static u64 fb_dma_mask = ~(u64)0;
317 static struct platform_device pxafb_device = {
318 .name = "pxa2xx-fb",
319 .id = -1,
320 .dev = {
321 .dma_mask = &fb_dma_mask,
322 .coherent_dma_mask = 0xffffffff,
324 .num_resources = ARRAY_SIZE(pxafb_resources),
325 .resource = pxafb_resources,
328 void __init set_pxa_fb_info(struct pxafb_mach_info *info)
330 pxafb_device.dev.platform_data = info;
332 EXPORT_SYMBOL(set_pxa_fb_info);
334 void __init set_pxa_fb_parent(struct device *parent_dev)
336 pxafb_device.dev.parent = parent_dev;
339 struct platform_device ffuart_device = {
340 .name = "pxa2xx-uart",
341 .id = 0,
343 EXPORT_SYMBOL(ffuart_device);
344 struct platform_device btuart_device = {
345 .name = "pxa2xx-uart",
346 .id = 1,
348 EXPORT_SYMBOL(btuart_device);
349 struct platform_device stuart_device = {
350 .name = "pxa2xx-uart",
351 .id = 2,
353 EXPORT_SYMBOL(stuart_device);
354 struct platform_device hwuart_device = {
355 .name = "pxa2xx-uart",
356 .id = 3,
358 EXPORT_SYMBOL(hwuart_device);
360 static struct resource i2c_resources[] = {
362 .start = 0x40301680,
363 .end = 0x403016a3,
364 .flags = IORESOURCE_MEM,
365 }, {
366 .start = IRQ_I2C,
367 .end = IRQ_I2C,
368 .flags = IORESOURCE_IRQ,
372 static struct platform_device i2c_device = {
373 .name = "pxa2xx-i2c",
374 .id = 0,
375 .resource = i2c_resources,
376 .num_resources = ARRAY_SIZE(i2c_resources),
379 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
381 i2c_device.dev.platform_data = info;
384 static struct resource i2s_resources[] = {
386 .start = 0x40400000,
387 .end = 0x40400083,
388 .flags = IORESOURCE_MEM,
389 }, {
390 .start = IRQ_I2S,
391 .end = IRQ_I2S,
392 .flags = IORESOURCE_IRQ,
396 static struct platform_device i2s_device = {
397 .name = "pxa2xx-i2s",
398 .id = -1,
399 .resource = i2s_resources,
400 .num_resources = ARRAY_SIZE(i2s_resources),
403 static u64 pxaficp_dmamask = ~(u32)0;
405 static struct platform_device pxaficp_device = {
406 .name = "pxa2xx-ir",
407 .id = -1,
408 .dev = {
409 .dma_mask = &pxaficp_dmamask,
410 .coherent_dma_mask = 0xffffffff,
414 void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
416 pxaficp_device.dev.platform_data = info;
419 static struct platform_device pxartc_device = {
420 .name = "sa1100-rtc",
421 .id = -1,
424 static struct platform_device *devices[] __initdata = {
425 &pxamci_device,
426 &udc_device,
427 &pxafb_device,
428 &ffuart_device,
429 &btuart_device,
430 &stuart_device,
431 &pxaficp_device,
432 &i2c_device,
433 &i2s_device,
434 &pxartc_device,
437 static int __init pxa_init(void)
439 int cpuid, ret;
441 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
442 if (ret)
443 return ret;
445 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
446 cpuid = read_cpuid(CPUID_ID);
447 if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
448 ((cpuid >> 4) & 0xfff) == 0x290)
449 ret = platform_device_register(&hwuart_device);
451 return ret;
454 subsys_initcall(pxa_init);