diff options
Diffstat (limited to 'arch/arm/mach-integrator/integrator_cp.c')
-rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 331 |
1 files changed, 223 insertions, 108 deletions
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 82d5c837cc74..6870a1fbcd78 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/gfp.h> | 23 | #include <linux/gfp.h> |
24 | #include <linux/mtd/physmap.h> | 24 | #include <linux/mtd/physmap.h> |
25 | #include <linux/platform_data/clk-integrator.h> | 25 | #include <linux/platform_data/clk-integrator.h> |
26 | #include <linux/of_irq.h> | ||
27 | #include <linux/of_address.h> | ||
28 | #include <linux/of_platform.h> | ||
26 | 29 | ||
27 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
28 | #include <mach/platform.h> | 31 | #include <mach/platform.h> |
@@ -49,17 +52,10 @@ | |||
49 | #include "common.h" | 52 | #include "common.h" |
50 | 53 | ||
51 | #define INTCP_PA_FLASH_BASE 0x24000000 | 54 | #define INTCP_PA_FLASH_BASE 0x24000000 |
52 | #define INTCP_FLASH_SIZE SZ_32M | ||
53 | 55 | ||
54 | #define INTCP_PA_CLCD_BASE 0xc0000000 | 56 | #define INTCP_PA_CLCD_BASE 0xc0000000 |
55 | 57 | ||
56 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) | 58 | #define INTCP_VA_CTRL_BASE __io_address(INTEGRATOR_CP_CTL_BASE) |
57 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) | ||
58 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) | ||
59 | |||
60 | #define INTCP_ETH_SIZE 0x10 | ||
61 | |||
62 | #define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) | ||
63 | #define INTCP_FLASHPROG 0x04 | 59 | #define INTCP_FLASHPROG 0x04 |
64 | #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) | 60 | #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) |
65 | #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) | 61 | #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) |
@@ -143,37 +139,6 @@ static void __init intcp_map_io(void) | |||
143 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); | 139 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); |
144 | } | 140 | } |
145 | 141 | ||
146 | static void __init intcp_init_irq(void) | ||
147 | { | ||
148 | u32 pic_mask, cic_mask, sic_mask; | ||
149 | |||
150 | /* These masks are for the HW IRQ registers */ | ||
151 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
152 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
153 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
154 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
155 | |||
156 | /* | ||
157 | * Disable all interrupt sources | ||
158 | */ | ||
159 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | ||
160 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | ||
161 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
162 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
163 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
164 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
165 | |||
166 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, | ||
167 | -1, pic_mask, NULL); | ||
168 | |||
169 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, | ||
170 | -1, cic_mask, NULL); | ||
171 | |||
172 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | ||
173 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
174 | integrator_clk_init(true); | ||
175 | } | ||
176 | |||
177 | /* | 142 | /* |
178 | * Flash handling. | 143 | * Flash handling. |
179 | */ | 144 | */ |
@@ -216,47 +181,6 @@ static struct physmap_flash_data intcp_flash_data = { | |||
216 | .set_vpp = intcp_flash_set_vpp, | 181 | .set_vpp = intcp_flash_set_vpp, |
217 | }; | 182 | }; |
218 | 183 | ||
219 | static struct resource intcp_flash_resource = { | ||
220 | .start = INTCP_PA_FLASH_BASE, | ||
221 | .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, | ||
222 | .flags = IORESOURCE_MEM, | ||
223 | }; | ||
224 | |||
225 | static struct platform_device intcp_flash_device = { | ||
226 | .name = "physmap-flash", | ||
227 | .id = 0, | ||
228 | .dev = { | ||
229 | .platform_data = &intcp_flash_data, | ||
230 | }, | ||
231 | .num_resources = 1, | ||
232 | .resource = &intcp_flash_resource, | ||
233 | }; | ||
234 | |||
235 | static struct resource smc91x_resources[] = { | ||
236 | [0] = { | ||
237 | .start = INTEGRATOR_CP_ETH_BASE, | ||
238 | .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, | ||
239 | .flags = IORESOURCE_MEM, | ||
240 | }, | ||
241 | [1] = { | ||
242 | .start = IRQ_CP_ETHINT, | ||
243 | .end = IRQ_CP_ETHINT, | ||
244 | .flags = IORESOURCE_IRQ, | ||
245 | }, | ||
246 | }; | ||
247 | |||
248 | static struct platform_device smc91x_device = { | ||
249 | .name = "smc91x", | ||
250 | .id = 0, | ||
251 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
252 | .resource = smc91x_resources, | ||
253 | }; | ||
254 | |||
255 | static struct platform_device *intcp_devs[] __initdata = { | ||
256 | &intcp_flash_device, | ||
257 | &smc91x_device, | ||
258 | }; | ||
259 | |||
260 | /* | 184 | /* |
261 | * It seems that the card insertion interrupt remains active after | 185 | * It seems that the card insertion interrupt remains active after |
262 | * we've acknowledged it. We therefore ignore the interrupt, and | 186 | * we've acknowledged it. We therefore ignore the interrupt, and |
@@ -265,8 +189,8 @@ static struct platform_device *intcp_devs[] __initdata = { | |||
265 | */ | 189 | */ |
266 | static unsigned int mmc_status(struct device *dev) | 190 | static unsigned int mmc_status(struct device *dev) |
267 | { | 191 | { |
268 | unsigned int status = readl(IO_ADDRESS(0xca000000 + 4)); | 192 | unsigned int status = readl(__io_address(0xca000000 + 4)); |
269 | writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8)); | 193 | writel(8, __io_address(INTEGRATOR_CP_CTL_BASE + 8)); |
270 | 194 | ||
271 | return status & 8; | 195 | return status & 8; |
272 | } | 196 | } |
@@ -278,16 +202,6 @@ static struct mmci_platform_data mmc_data = { | |||
278 | .gpio_cd = -1, | 202 | .gpio_cd = -1, |
279 | }; | 203 | }; |
280 | 204 | ||
281 | #define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } | ||
282 | #define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } | ||
283 | |||
284 | static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, | ||
285 | INTEGRATOR_CP_MMC_IRQS, &mmc_data); | ||
286 | |||
287 | static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, | ||
288 | INTEGRATOR_CP_AACI_IRQS, NULL); | ||
289 | |||
290 | |||
291 | /* | 205 | /* |
292 | * CLCD support | 206 | * CLCD support |
293 | */ | 207 | */ |
@@ -338,15 +252,6 @@ static struct clcd_board clcd_data = { | |||
338 | .remove = versatile_clcd_remove_dma, | 252 | .remove = versatile_clcd_remove_dma, |
339 | }; | 253 | }; |
340 | 254 | ||
341 | static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, | ||
342 | { IRQ_CP_CLCDCINT }, &clcd_data); | ||
343 | |||
344 | static struct amba_device *amba_devs[] __initdata = { | ||
345 | &mmc_device, | ||
346 | &aaci_device, | ||
347 | &clcd_device, | ||
348 | }; | ||
349 | |||
350 | #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28) | 255 | #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28) |
351 | 256 | ||
352 | static void __init intcp_init_early(void) | 257 | static void __init intcp_init_early(void) |
@@ -356,16 +261,193 @@ static void __init intcp_init_early(void) | |||
356 | #endif | 261 | #endif |
357 | } | 262 | } |
358 | 263 | ||
359 | static void __init intcp_init(void) | 264 | static void __init intcp_timer_init_of(void) |
360 | { | 265 | { |
361 | int i; | 266 | struct device_node *node; |
267 | const char *path; | ||
268 | void __iomem *base; | ||
269 | int err; | ||
270 | int irq; | ||
271 | |||
272 | err = of_property_read_string(of_aliases, | ||
273 | "arm,timer-primary", &path); | ||
274 | if (WARN_ON(err)) | ||
275 | return; | ||
276 | node = of_find_node_by_path(path); | ||
277 | base = of_iomap(node, 0); | ||
278 | if (WARN_ON(!base)) | ||
279 | return; | ||
280 | writel(0, base + TIMER_CTRL); | ||
281 | sp804_clocksource_init(base, node->name); | ||
282 | |||
283 | err = of_property_read_string(of_aliases, | ||
284 | "arm,timer-secondary", &path); | ||
285 | if (WARN_ON(err)) | ||
286 | return; | ||
287 | node = of_find_node_by_path(path); | ||
288 | base = of_iomap(node, 0); | ||
289 | if (WARN_ON(!base)) | ||
290 | return; | ||
291 | irq = irq_of_parse_and_map(node, 0); | ||
292 | writel(0, base + TIMER_CTRL); | ||
293 | sp804_clockevents_init(base, irq, node->name); | ||
294 | } | ||
362 | 295 | ||
363 | platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); | 296 | static struct sys_timer cp_of_timer = { |
297 | .init = intcp_timer_init_of, | ||
298 | }; | ||
364 | 299 | ||
365 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 300 | #ifdef CONFIG_OF |
366 | struct amba_device *d = amba_devs[i]; | 301 | |
367 | amba_device_register(d, &iomem_resource); | 302 | static const struct of_device_id fpga_irq_of_match[] __initconst = { |
368 | } | 303 | { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, |
304 | { /* Sentinel */ } | ||
305 | }; | ||
306 | |||
307 | static void __init intcp_init_irq_of(void) | ||
308 | { | ||
309 | of_irq_init(fpga_irq_of_match); | ||
310 | integrator_clk_init(true); | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA | ||
315 | * and enforce the bus names since these are used for clock lookups. | ||
316 | */ | ||
317 | static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { | ||
318 | OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, | ||
319 | "rtc", NULL), | ||
320 | OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, | ||
321 | "uart0", &integrator_uart_data), | ||
322 | OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, | ||
323 | "uart1", &integrator_uart_data), | ||
324 | OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, | ||
325 | "kmi0", NULL), | ||
326 | OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, | ||
327 | "kmi1", NULL), | ||
328 | OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE, | ||
329 | "mmci", &mmc_data), | ||
330 | OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_AACI_BASE, | ||
331 | "aaci", &mmc_data), | ||
332 | OF_DEV_AUXDATA("arm,primecell", INTCP_PA_CLCD_BASE, | ||
333 | "clcd", &clcd_data), | ||
334 | OF_DEV_AUXDATA("cfi-flash", INTCP_PA_FLASH_BASE, | ||
335 | "physmap-flash", &intcp_flash_data), | ||
336 | { /* sentinel */ }, | ||
337 | }; | ||
338 | |||
339 | static void __init intcp_init_of(void) | ||
340 | { | ||
341 | of_platform_populate(NULL, of_default_bus_match_table, | ||
342 | intcp_auxdata_lookup, NULL); | ||
343 | } | ||
344 | |||
345 | static const char * intcp_dt_board_compat[] = { | ||
346 | "arm,integrator-cp", | ||
347 | NULL, | ||
348 | }; | ||
349 | |||
350 | DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") | ||
351 | .reserve = integrator_reserve, | ||
352 | .map_io = intcp_map_io, | ||
353 | .nr_irqs = NR_IRQS_INTEGRATOR_CP, | ||
354 | .init_early = intcp_init_early, | ||
355 | .init_irq = intcp_init_irq_of, | ||
356 | .handle_irq = fpga_handle_irq, | ||
357 | .timer = &cp_of_timer, | ||
358 | .init_machine = intcp_init_of, | ||
359 | .restart = integrator_restart, | ||
360 | .dt_compat = intcp_dt_board_compat, | ||
361 | MACHINE_END | ||
362 | |||
363 | #endif | ||
364 | |||
365 | #ifdef CONFIG_ATAGS | ||
366 | |||
367 | /* | ||
368 | * This is where non-devicetree initialization code is collected and stashed | ||
369 | * for eventual deletion. | ||
370 | */ | ||
371 | |||
372 | #define INTCP_FLASH_SIZE SZ_32M | ||
373 | |||
374 | static struct resource intcp_flash_resource = { | ||
375 | .start = INTCP_PA_FLASH_BASE, | ||
376 | .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, | ||
377 | .flags = IORESOURCE_MEM, | ||
378 | }; | ||
379 | |||
380 | static struct platform_device intcp_flash_device = { | ||
381 | .name = "physmap-flash", | ||
382 | .id = 0, | ||
383 | .dev = { | ||
384 | .platform_data = &intcp_flash_data, | ||
385 | }, | ||
386 | .num_resources = 1, | ||
387 | .resource = &intcp_flash_resource, | ||
388 | }; | ||
389 | |||
390 | #define INTCP_ETH_SIZE 0x10 | ||
391 | |||
392 | static struct resource smc91x_resources[] = { | ||
393 | [0] = { | ||
394 | .start = INTEGRATOR_CP_ETH_BASE, | ||
395 | .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, | ||
396 | .flags = IORESOURCE_MEM, | ||
397 | }, | ||
398 | [1] = { | ||
399 | .start = IRQ_CP_ETHINT, | ||
400 | .end = IRQ_CP_ETHINT, | ||
401 | .flags = IORESOURCE_IRQ, | ||
402 | }, | ||
403 | }; | ||
404 | |||
405 | static struct platform_device smc91x_device = { | ||
406 | .name = "smc91x", | ||
407 | .id = 0, | ||
408 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
409 | .resource = smc91x_resources, | ||
410 | }; | ||
411 | |||
412 | static struct platform_device *intcp_devs[] __initdata = { | ||
413 | &intcp_flash_device, | ||
414 | &smc91x_device, | ||
415 | }; | ||
416 | |||
417 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) | ||
418 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) | ||
419 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) | ||
420 | |||
421 | static void __init intcp_init_irq(void) | ||
422 | { | ||
423 | u32 pic_mask, cic_mask, sic_mask; | ||
424 | |||
425 | /* These masks are for the HW IRQ registers */ | ||
426 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
427 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
428 | cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); | ||
429 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
430 | |||
431 | /* | ||
432 | * Disable all interrupt sources | ||
433 | */ | ||
434 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | ||
435 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | ||
436 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
437 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
438 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
439 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
440 | |||
441 | fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, | ||
442 | -1, pic_mask, NULL); | ||
443 | |||
444 | fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, | ||
445 | -1, cic_mask, NULL); | ||
446 | |||
447 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | ||
448 | IRQ_CP_CPPLDINT, sic_mask, NULL); | ||
449 | |||
450 | integrator_clk_init(true); | ||
369 | } | 451 | } |
370 | 452 | ||
371 | #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) | 453 | #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) |
@@ -386,6 +468,37 @@ static struct sys_timer cp_timer = { | |||
386 | .init = intcp_timer_init, | 468 | .init = intcp_timer_init, |
387 | }; | 469 | }; |
388 | 470 | ||
471 | #define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } | ||
472 | #define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } | ||
473 | |||
474 | static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, | ||
475 | INTEGRATOR_CP_MMC_IRQS, &mmc_data); | ||
476 | |||
477 | static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, | ||
478 | INTEGRATOR_CP_AACI_IRQS, NULL); | ||
479 | |||
480 | static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, | ||
481 | { IRQ_CP_CLCDCINT }, &clcd_data); | ||
482 | |||
483 | static struct amba_device *amba_devs[] __initdata = { | ||
484 | &mmc_device, | ||
485 | &aaci_device, | ||
486 | &clcd_device, | ||
487 | }; | ||
488 | |||
489 | static void __init intcp_init(void) | ||
490 | { | ||
491 | int i; | ||
492 | |||
493 | platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); | ||
494 | |||
495 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | ||
496 | struct amba_device *d = amba_devs[i]; | ||
497 | amba_device_register(d, &iomem_resource); | ||
498 | } | ||
499 | integrator_init(true); | ||
500 | } | ||
501 | |||
389 | MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") | 502 | MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") |
390 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 503 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
391 | .atag_offset = 0x100, | 504 | .atag_offset = 0x100, |
@@ -399,3 +512,5 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") | |||
399 | .init_machine = intcp_init, | 512 | .init_machine = intcp_init, |
400 | .restart = integrator_restart, | 513 | .restart = integrator_restart, |
401 | MACHINE_END | 514 | MACHINE_END |
515 | |||
516 | #endif | ||