diff options
Diffstat (limited to 'arch/arm/mach-iop13xx/setup.c')
-rw-r--r-- | arch/arm/mach-iop13xx/setup.c | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c new file mode 100644 index 000000000000..3756d2ccb1a7 --- /dev/null +++ b/arch/arm/mach-iop13xx/setup.c | |||
@@ -0,0 +1,406 @@ | |||
1 | /* | ||
2 | * iop13xx platform Initialization | ||
3 | * Copyright (c) 2005-2006, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
16 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/serial_8250.h> | ||
21 | #ifdef CONFIG_MTD_PHYSMAP | ||
22 | #include <linux/mtd/physmap.h> | ||
23 | #endif | ||
24 | #include <asm/mach/map.h> | ||
25 | #include <asm/hardware.h> | ||
26 | #include <asm/irq.h> | ||
27 | |||
28 | #define IOP13XX_UART_XTAL 33334000 | ||
29 | #define IOP13XX_SETUP_DEBUG 0 | ||
30 | #define PRINTK(x...) ((void)(IOP13XX_SETUP_DEBUG && printk(x))) | ||
31 | |||
32 | /* Standard IO mapping for all IOP13XX based systems | ||
33 | */ | ||
34 | static struct map_desc iop13xx_std_desc[] __initdata = { | ||
35 | { /* mem mapped registers */ | ||
36 | .virtual = IOP13XX_PMMR_VIRT_MEM_BASE, | ||
37 | .pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE), | ||
38 | .length = IOP13XX_PMMR_SIZE, | ||
39 | .type = MT_DEVICE, | ||
40 | }, { /* PCIE IO space */ | ||
41 | .virtual = IOP13XX_PCIE_LOWER_IO_VA, | ||
42 | .pfn = __phys_to_pfn(IOP13XX_PCIE_LOWER_IO_PA), | ||
43 | .length = IOP13XX_PCIX_IO_WINDOW_SIZE, | ||
44 | .type = MT_DEVICE, | ||
45 | }, { /* PCIX IO space */ | ||
46 | .virtual = IOP13XX_PCIX_LOWER_IO_VA, | ||
47 | .pfn = __phys_to_pfn(IOP13XX_PCIX_LOWER_IO_PA), | ||
48 | .length = IOP13XX_PCIX_IO_WINDOW_SIZE, | ||
49 | .type = MT_DEVICE, | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | static struct resource iop13xx_uart0_resources[] = { | ||
54 | [0] = { | ||
55 | .start = IOP13XX_UART0_PHYS, | ||
56 | .end = IOP13XX_UART0_PHYS + 0x3f, | ||
57 | .flags = IORESOURCE_MEM, | ||
58 | }, | ||
59 | [1] = { | ||
60 | .start = IRQ_IOP13XX_UART0, | ||
61 | .end = IRQ_IOP13XX_UART0, | ||
62 | .flags = IORESOURCE_IRQ | ||
63 | } | ||
64 | }; | ||
65 | |||
66 | static struct resource iop13xx_uart1_resources[] = { | ||
67 | [0] = { | ||
68 | .start = IOP13XX_UART1_PHYS, | ||
69 | .end = IOP13XX_UART1_PHYS + 0x3f, | ||
70 | .flags = IORESOURCE_MEM, | ||
71 | }, | ||
72 | [1] = { | ||
73 | .start = IRQ_IOP13XX_UART1, | ||
74 | .end = IRQ_IOP13XX_UART1, | ||
75 | .flags = IORESOURCE_IRQ | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | static struct plat_serial8250_port iop13xx_uart0_data[] = { | ||
80 | { | ||
81 | .membase = (char*)(IOP13XX_UART0_VIRT), | ||
82 | .mapbase = (IOP13XX_UART0_PHYS), | ||
83 | .irq = IRQ_IOP13XX_UART0, | ||
84 | .uartclk = IOP13XX_UART_XTAL, | ||
85 | .regshift = 2, | ||
86 | .iotype = UPIO_MEM, | ||
87 | .flags = UPF_SKIP_TEST, | ||
88 | }, | ||
89 | { }, | ||
90 | }; | ||
91 | |||
92 | static struct plat_serial8250_port iop13xx_uart1_data[] = { | ||
93 | { | ||
94 | .membase = (char*)(IOP13XX_UART1_VIRT), | ||
95 | .mapbase = (IOP13XX_UART1_PHYS), | ||
96 | .irq = IRQ_IOP13XX_UART1, | ||
97 | .uartclk = IOP13XX_UART_XTAL, | ||
98 | .regshift = 2, | ||
99 | .iotype = UPIO_MEM, | ||
100 | .flags = UPF_SKIP_TEST, | ||
101 | }, | ||
102 | { }, | ||
103 | }; | ||
104 | |||
105 | /* The ids are fixed up later in iop13xx_platform_init */ | ||
106 | static struct platform_device iop13xx_uart0 = { | ||
107 | .name = "serial8250", | ||
108 | .id = 0, | ||
109 | .dev.platform_data = iop13xx_uart0_data, | ||
110 | .num_resources = 2, | ||
111 | .resource = iop13xx_uart0_resources, | ||
112 | }; | ||
113 | |||
114 | static struct platform_device iop13xx_uart1 = { | ||
115 | .name = "serial8250", | ||
116 | .id = 0, | ||
117 | .dev.platform_data = iop13xx_uart1_data, | ||
118 | .num_resources = 2, | ||
119 | .resource = iop13xx_uart1_resources | ||
120 | }; | ||
121 | |||
122 | static struct resource iop13xx_i2c_0_resources[] = { | ||
123 | [0] = { | ||
124 | .start = IOP13XX_I2C0_PHYS, | ||
125 | .end = IOP13XX_I2C0_PHYS + 0x18, | ||
126 | .flags = IORESOURCE_MEM, | ||
127 | }, | ||
128 | [1] = { | ||
129 | .start = IRQ_IOP13XX_I2C_0, | ||
130 | .end = IRQ_IOP13XX_I2C_0, | ||
131 | .flags = IORESOURCE_IRQ | ||
132 | } | ||
133 | }; | ||
134 | |||
135 | static struct resource iop13xx_i2c_1_resources[] = { | ||
136 | [0] = { | ||
137 | .start = IOP13XX_I2C1_PHYS, | ||
138 | .end = IOP13XX_I2C1_PHYS + 0x18, | ||
139 | .flags = IORESOURCE_MEM, | ||
140 | }, | ||
141 | [1] = { | ||
142 | .start = IRQ_IOP13XX_I2C_1, | ||
143 | .end = IRQ_IOP13XX_I2C_1, | ||
144 | .flags = IORESOURCE_IRQ | ||
145 | } | ||
146 | }; | ||
147 | |||
148 | static struct resource iop13xx_i2c_2_resources[] = { | ||
149 | [0] = { | ||
150 | .start = IOP13XX_I2C2_PHYS, | ||
151 | .end = IOP13XX_I2C2_PHYS + 0x18, | ||
152 | .flags = IORESOURCE_MEM, | ||
153 | }, | ||
154 | [1] = { | ||
155 | .start = IRQ_IOP13XX_I2C_2, | ||
156 | .end = IRQ_IOP13XX_I2C_2, | ||
157 | .flags = IORESOURCE_IRQ | ||
158 | } | ||
159 | }; | ||
160 | |||
161 | /* I2C controllers. The IOP13XX uses the same block as the IOP3xx, so | ||
162 | * we just use the same device name. | ||
163 | */ | ||
164 | |||
165 | /* The ids are fixed up later in iop13xx_platform_init */ | ||
166 | static struct platform_device iop13xx_i2c_0_controller = { | ||
167 | .name = "IOP3xx-I2C", | ||
168 | .id = 0, | ||
169 | .num_resources = 2, | ||
170 | .resource = iop13xx_i2c_0_resources | ||
171 | }; | ||
172 | |||
173 | static struct platform_device iop13xx_i2c_1_controller = { | ||
174 | .name = "IOP3xx-I2C", | ||
175 | .id = 0, | ||
176 | .num_resources = 2, | ||
177 | .resource = iop13xx_i2c_1_resources | ||
178 | }; | ||
179 | |||
180 | static struct platform_device iop13xx_i2c_2_controller = { | ||
181 | .name = "IOP3xx-I2C", | ||
182 | .id = 0, | ||
183 | .num_resources = 2, | ||
184 | .resource = iop13xx_i2c_2_resources | ||
185 | }; | ||
186 | |||
187 | #ifdef CONFIG_MTD_PHYSMAP | ||
188 | /* PBI Flash Device | ||
189 | */ | ||
190 | static struct physmap_flash_data iq8134x_flash_data = { | ||
191 | .width = 2, | ||
192 | }; | ||
193 | |||
194 | static struct resource iq8134x_flash_resource = { | ||
195 | .start = IQ81340_FLASHBASE, | ||
196 | .end = 0, | ||
197 | .flags = IORESOURCE_MEM, | ||
198 | }; | ||
199 | |||
200 | static struct platform_device iq8134x_flash = { | ||
201 | .name = "physmap-flash", | ||
202 | .id = 0, | ||
203 | .dev = { .platform_data = &iq8134x_flash_data, }, | ||
204 | .num_resources = 1, | ||
205 | .resource = &iq8134x_flash_resource, | ||
206 | }; | ||
207 | |||
208 | static unsigned long iq8134x_probe_flash_size(void) | ||
209 | { | ||
210 | uint8_t __iomem *flash_addr = ioremap(IQ81340_FLASHBASE, PAGE_SIZE); | ||
211 | int i; | ||
212 | char query[3]; | ||
213 | unsigned long size = 0; | ||
214 | int width = iq8134x_flash_data.width; | ||
215 | |||
216 | if (flash_addr) { | ||
217 | /* send CFI 'query' command */ | ||
218 | writew(0x98, flash_addr); | ||
219 | |||
220 | /* check for CFI compliance */ | ||
221 | for (i = 0; i < 3 * width; i += width) | ||
222 | query[i / width] = readb(flash_addr + (0x10 * width) + i); | ||
223 | |||
224 | /* read the size */ | ||
225 | if (memcmp(query, "QRY", 3) == 0) | ||
226 | size = 1 << readb(flash_addr + (0x27 * width)); | ||
227 | |||
228 | /* send CFI 'read array' command */ | ||
229 | writew(0xff, flash_addr); | ||
230 | |||
231 | iounmap(flash_addr); | ||
232 | } | ||
233 | |||
234 | return size; | ||
235 | } | ||
236 | #endif | ||
237 | |||
238 | void __init iop13xx_map_io(void) | ||
239 | { | ||
240 | /* Initialize the Static Page Table maps */ | ||
241 | iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc)); | ||
242 | } | ||
243 | |||
244 | static int init_uart = 0; | ||
245 | static int init_i2c = 0; | ||
246 | |||
247 | void __init iop13xx_platform_init(void) | ||
248 | { | ||
249 | int i; | ||
250 | u32 uart_idx, i2c_idx, plat_idx; | ||
251 | struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES]; | ||
252 | |||
253 | /* set the bases so we can read the device id */ | ||
254 | iop13xx_set_atu_mmr_bases(); | ||
255 | |||
256 | memset(iop13xx_devices, 0, sizeof(iop13xx_devices)); | ||
257 | |||
258 | if (init_uart == IOP13XX_INIT_UART_DEFAULT) { | ||
259 | switch (iop13xx_dev_id()) { | ||
260 | /* enable both uarts on iop341 and iop342 */ | ||
261 | case 0x3380: | ||
262 | case 0x3384: | ||
263 | case 0x3388: | ||
264 | case 0x338c: | ||
265 | case 0x3382: | ||
266 | case 0x3386: | ||
267 | case 0x338a: | ||
268 | case 0x338e: | ||
269 | init_uart |= IOP13XX_INIT_UART_0; | ||
270 | init_uart |= IOP13XX_INIT_UART_1; | ||
271 | break; | ||
272 | /* only enable uart 1 */ | ||
273 | default: | ||
274 | init_uart |= IOP13XX_INIT_UART_1; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | if (init_i2c == IOP13XX_INIT_I2C_DEFAULT) { | ||
279 | switch (iop13xx_dev_id()) { | ||
280 | /* enable all i2c units on iop341 and iop342 */ | ||
281 | case 0x3380: | ||
282 | case 0x3384: | ||
283 | case 0x3388: | ||
284 | case 0x338c: | ||
285 | case 0x3382: | ||
286 | case 0x3386: | ||
287 | case 0x338a: | ||
288 | case 0x338e: | ||
289 | init_i2c |= IOP13XX_INIT_I2C_0; | ||
290 | init_i2c |= IOP13XX_INIT_I2C_1; | ||
291 | init_i2c |= IOP13XX_INIT_I2C_2; | ||
292 | break; | ||
293 | /* only enable i2c 1 and 2 */ | ||
294 | default: | ||
295 | init_i2c |= IOP13XX_INIT_I2C_1; | ||
296 | init_i2c |= IOP13XX_INIT_I2C_2; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | plat_idx = 0; | ||
301 | uart_idx = 0; | ||
302 | i2c_idx = 0; | ||
303 | |||
304 | /* uart 1 (if enabled) is ttyS0 */ | ||
305 | if (init_uart & IOP13XX_INIT_UART_1) { | ||
306 | PRINTK("Adding uart1 to platform device list\n"); | ||
307 | iop13xx_uart1.id = uart_idx++; | ||
308 | iop13xx_devices[plat_idx++] = &iop13xx_uart1; | ||
309 | } | ||
310 | if (init_uart & IOP13XX_INIT_UART_0) { | ||
311 | PRINTK("Adding uart0 to platform device list\n"); | ||
312 | iop13xx_uart0.id = uart_idx++; | ||
313 | iop13xx_devices[plat_idx++] = &iop13xx_uart0; | ||
314 | } | ||
315 | |||
316 | for(i = 0; i < IQ81340_NUM_I2C; i++) { | ||
317 | if ((init_i2c & (1 << i)) && IOP13XX_SETUP_DEBUG) | ||
318 | printk("Adding i2c%d to platform device list\n", i); | ||
319 | switch(init_i2c & (1 << i)) { | ||
320 | case IOP13XX_INIT_I2C_0: | ||
321 | iop13xx_i2c_0_controller.id = i2c_idx++; | ||
322 | iop13xx_devices[plat_idx++] = | ||
323 | &iop13xx_i2c_0_controller; | ||
324 | break; | ||
325 | case IOP13XX_INIT_I2C_1: | ||
326 | iop13xx_i2c_1_controller.id = i2c_idx++; | ||
327 | iop13xx_devices[plat_idx++] = | ||
328 | &iop13xx_i2c_1_controller; | ||
329 | break; | ||
330 | case IOP13XX_INIT_I2C_2: | ||
331 | iop13xx_i2c_2_controller.id = i2c_idx++; | ||
332 | iop13xx_devices[plat_idx++] = | ||
333 | &iop13xx_i2c_2_controller; | ||
334 | break; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | #ifdef CONFIG_MTD_PHYSMAP | ||
339 | iq8134x_flash_resource.end = iq8134x_flash_resource.start + | ||
340 | iq8134x_probe_flash_size(); | ||
341 | if (iq8134x_flash_resource.end > iq8134x_flash_resource.start) | ||
342 | iop13xx_devices[plat_idx++] = &iq8134x_flash; | ||
343 | else | ||
344 | printk(KERN_ERR "%s: Failed to probe flash size\n", __FUNCTION__); | ||
345 | #endif | ||
346 | |||
347 | platform_add_devices(iop13xx_devices, plat_idx); | ||
348 | } | ||
349 | |||
350 | static int __init iop13xx_init_uart_setup(char *str) | ||
351 | { | ||
352 | if (str) { | ||
353 | while (*str != '\0') { | ||
354 | switch(*str) { | ||
355 | case '0': | ||
356 | init_uart |= IOP13XX_INIT_UART_0; | ||
357 | break; | ||
358 | case '1': | ||
359 | init_uart |= IOP13XX_INIT_UART_1; | ||
360 | break; | ||
361 | case ',': | ||
362 | case '=': | ||
363 | break; | ||
364 | default: | ||
365 | PRINTK("\"iop13xx_init_uart\" malformed" | ||
366 | " at character: \'%c\'", *str); | ||
367 | *(str + 1) = '\0'; | ||
368 | init_uart = IOP13XX_INIT_UART_DEFAULT; | ||
369 | } | ||
370 | str++; | ||
371 | } | ||
372 | } | ||
373 | return 1; | ||
374 | } | ||
375 | |||
376 | static int __init iop13xx_init_i2c_setup(char *str) | ||
377 | { | ||
378 | if (str) { | ||
379 | while (*str != '\0') { | ||
380 | switch(*str) { | ||
381 | case '0': | ||
382 | init_i2c |= IOP13XX_INIT_I2C_0; | ||
383 | break; | ||
384 | case '1': | ||
385 | init_i2c |= IOP13XX_INIT_I2C_1; | ||
386 | break; | ||
387 | case '2': | ||
388 | init_i2c |= IOP13XX_INIT_I2C_2; | ||
389 | break; | ||
390 | case ',': | ||
391 | case '=': | ||
392 | break; | ||
393 | default: | ||
394 | PRINTK("\"iop13xx_init_i2c\" malformed" | ||
395 | " at character: \'%c\'", *str); | ||
396 | *(str + 1) = '\0'; | ||
397 | init_i2c = IOP13XX_INIT_I2C_DEFAULT; | ||
398 | } | ||
399 | str++; | ||
400 | } | ||
401 | } | ||
402 | return 1; | ||
403 | } | ||
404 | |||
405 | __setup("iop13xx_init_uart", iop13xx_init_uart_setup); | ||
406 | __setup("iop13xx_init_i2c", iop13xx_init_i2c_setup); | ||