diff options
Diffstat (limited to 'arch/arm/mach-pxa/generic.c')
-rw-r--r-- | arch/arm/mach-pxa/generic.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c new file mode 100644 index 000000000000..b1575b8dc1cd --- /dev/null +++ b/arch/arm/mach-pxa/generic.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/generic.c | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: Jun 15, 2001 | ||
6 | * Copyright: MontaVista Software Inc. | ||
7 | * | ||
8 | * Code common to all PXA machines. | ||
9 | * | ||
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. | ||
13 | * | ||
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. | ||
18 | */ | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/pm.h> | ||
26 | |||
27 | #include <asm/hardware.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/system.h> | ||
30 | #include <asm/pgtable.h> | ||
31 | #include <asm/mach/map.h> | ||
32 | |||
33 | #include <asm/arch/pxa-regs.h> | ||
34 | #include <asm/arch/udc.h> | ||
35 | #include <asm/arch/pxafb.h> | ||
36 | #include <asm/arch/mmc.h> | ||
37 | |||
38 | #include "generic.h" | ||
39 | |||
40 | /* | ||
41 | * Handy function to set GPIO alternate functions | ||
42 | */ | ||
43 | |||
44 | void pxa_gpio_mode(int gpio_mode) | ||
45 | { | ||
46 | unsigned long flags; | ||
47 | int gpio = gpio_mode & GPIO_MD_MASK_NR; | ||
48 | int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; | ||
49 | int gafr; | ||
50 | |||
51 | local_irq_save(flags); | ||
52 | if (gpio_mode & GPIO_DFLT_LOW) | ||
53 | GPCR(gpio) = GPIO_bit(gpio); | ||
54 | else if (gpio_mode & GPIO_DFLT_HIGH) | ||
55 | GPSR(gpio) = GPIO_bit(gpio); | ||
56 | if (gpio_mode & GPIO_MD_MASK_DIR) | ||
57 | GPDR(gpio) |= GPIO_bit(gpio); | ||
58 | else | ||
59 | GPDR(gpio) &= ~GPIO_bit(gpio); | ||
60 | gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); | ||
61 | GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); | ||
62 | local_irq_restore(flags); | ||
63 | } | ||
64 | |||
65 | EXPORT_SYMBOL(pxa_gpio_mode); | ||
66 | |||
67 | /* | ||
68 | * Routine to safely enable or disable a clock in the CKEN | ||
69 | */ | ||
70 | void pxa_set_cken(int clock, int enable) | ||
71 | { | ||
72 | unsigned long flags; | ||
73 | local_irq_save(flags); | ||
74 | |||
75 | if (enable) | ||
76 | CKEN |= clock; | ||
77 | else | ||
78 | CKEN &= ~clock; | ||
79 | |||
80 | local_irq_restore(flags); | ||
81 | } | ||
82 | |||
83 | EXPORT_SYMBOL(pxa_set_cken); | ||
84 | |||
85 | /* | ||
86 | * Intel PXA2xx internal register mapping. | ||
87 | * | ||
88 | * Note 1: not all PXA2xx variants implement all those addresses. | ||
89 | * | ||
90 | * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table | ||
91 | * and cache flush area. | ||
92 | */ | ||
93 | static struct map_desc standard_io_desc[] __initdata = { | ||
94 | /* virtual physical length type */ | ||
95 | { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */ | ||
96 | { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */ | ||
97 | { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */ | ||
98 | { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */ | ||
99 | { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */ | ||
100 | { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */ | ||
101 | { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */ | ||
102 | }; | ||
103 | |||
104 | void __init pxa_map_io(void) | ||
105 | { | ||
106 | iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); | ||
107 | get_clk_frequency_khz(1); | ||
108 | } | ||
109 | |||
110 | |||
111 | static struct resource pxamci_resources[] = { | ||
112 | [0] = { | ||
113 | .start = 0x41100000, | ||
114 | .end = 0x41100fff, | ||
115 | .flags = IORESOURCE_MEM, | ||
116 | }, | ||
117 | [1] = { | ||
118 | .start = IRQ_MMC, | ||
119 | .end = IRQ_MMC, | ||
120 | .flags = IORESOURCE_IRQ, | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | static u64 pxamci_dmamask = 0xffffffffUL; | ||
125 | |||
126 | static struct platform_device pxamci_device = { | ||
127 | .name = "pxa2xx-mci", | ||
128 | .id = -1, | ||
129 | .dev = { | ||
130 | .dma_mask = &pxamci_dmamask, | ||
131 | .coherent_dma_mask = 0xffffffff, | ||
132 | }, | ||
133 | .num_resources = ARRAY_SIZE(pxamci_resources), | ||
134 | .resource = pxamci_resources, | ||
135 | }; | ||
136 | |||
137 | void __init pxa_set_mci_info(struct pxamci_platform_data *info) | ||
138 | { | ||
139 | pxamci_device.dev.platform_data = info; | ||
140 | } | ||
141 | |||
142 | |||
143 | static struct pxa2xx_udc_mach_info pxa_udc_info; | ||
144 | |||
145 | void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) | ||
146 | { | ||
147 | memcpy(&pxa_udc_info, info, sizeof *info); | ||
148 | } | ||
149 | |||
150 | static struct resource pxa2xx_udc_resources[] = { | ||
151 | [0] = { | ||
152 | .start = 0x40600000, | ||
153 | .end = 0x4060ffff, | ||
154 | .flags = IORESOURCE_MEM, | ||
155 | }, | ||
156 | [1] = { | ||
157 | .start = IRQ_USB, | ||
158 | .end = IRQ_USB, | ||
159 | .flags = IORESOURCE_IRQ, | ||
160 | }, | ||
161 | }; | ||
162 | |||
163 | static u64 udc_dma_mask = ~(u32)0; | ||
164 | |||
165 | static struct platform_device udc_device = { | ||
166 | .name = "pxa2xx-udc", | ||
167 | .id = -1, | ||
168 | .resource = pxa2xx_udc_resources, | ||
169 | .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), | ||
170 | .dev = { | ||
171 | .platform_data = &pxa_udc_info, | ||
172 | .dma_mask = &udc_dma_mask, | ||
173 | } | ||
174 | }; | ||
175 | |||
176 | static struct pxafb_mach_info pxa_fb_info; | ||
177 | |||
178 | void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info) | ||
179 | { | ||
180 | memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info)); | ||
181 | } | ||
182 | |||
183 | static struct resource pxafb_resources[] = { | ||
184 | [0] = { | ||
185 | .start = 0x44000000, | ||
186 | .end = 0x4400ffff, | ||
187 | .flags = IORESOURCE_MEM, | ||
188 | }, | ||
189 | [1] = { | ||
190 | .start = IRQ_LCD, | ||
191 | .end = IRQ_LCD, | ||
192 | .flags = IORESOURCE_IRQ, | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static u64 fb_dma_mask = ~(u64)0; | ||
197 | |||
198 | static struct platform_device pxafb_device = { | ||
199 | .name = "pxa2xx-fb", | ||
200 | .id = -1, | ||
201 | .dev = { | ||
202 | .platform_data = &pxa_fb_info, | ||
203 | .dma_mask = &fb_dma_mask, | ||
204 | .coherent_dma_mask = 0xffffffff, | ||
205 | }, | ||
206 | .num_resources = ARRAY_SIZE(pxafb_resources), | ||
207 | .resource = pxafb_resources, | ||
208 | }; | ||
209 | |||
210 | static struct platform_device ffuart_device = { | ||
211 | .name = "pxa2xx-uart", | ||
212 | .id = 0, | ||
213 | }; | ||
214 | static struct platform_device btuart_device = { | ||
215 | .name = "pxa2xx-uart", | ||
216 | .id = 1, | ||
217 | }; | ||
218 | static struct platform_device stuart_device = { | ||
219 | .name = "pxa2xx-uart", | ||
220 | .id = 2, | ||
221 | }; | ||
222 | |||
223 | static struct platform_device *devices[] __initdata = { | ||
224 | &pxamci_device, | ||
225 | &udc_device, | ||
226 | &pxafb_device, | ||
227 | &ffuart_device, | ||
228 | &btuart_device, | ||
229 | &stuart_device, | ||
230 | }; | ||
231 | |||
232 | static int __init pxa_init(void) | ||
233 | { | ||
234 | return platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
235 | } | ||
236 | |||
237 | subsys_initcall(pxa_init); | ||