aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-integrator/integrator_cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-integrator/integrator_cp.c')
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c331
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
146static 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
219static 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
225static 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
235static 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
248static struct platform_device smc91x_device = {
249 .name = "smc91x",
250 .id = 0,
251 .num_resources = ARRAY_SIZE(smc91x_resources),
252 .resource = smc91x_resources,
253};
254
255static 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 */
266static unsigned int mmc_status(struct device *dev) 190static 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
284static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
285 INTEGRATOR_CP_MMC_IRQS, &mmc_data);
286
287static 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
341static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
342 { IRQ_CP_CLCDCINT }, &clcd_data);
343
344static 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
352static void __init intcp_init_early(void) 257static 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
359static void __init intcp_init(void) 264static 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)); 296static 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); 302static 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
307static 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 */
317static 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
339static void __init intcp_init_of(void)
340{
341 of_platform_populate(NULL, of_default_bus_match_table,
342 intcp_auxdata_lookup, NULL);
343}
344
345static const char * intcp_dt_board_compat[] = {
346 "arm,integrator-cp",
347 NULL,
348};
349
350DT_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,
361MACHINE_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
374static 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
380static 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
392static 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
405static struct platform_device smc91x_device = {
406 .name = "smc91x",
407 .id = 0,
408 .num_resources = ARRAY_SIZE(smc91x_resources),
409 .resource = smc91x_resources,
410};
411
412static 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
421static 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
474static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
475 INTEGRATOR_CP_MMC_IRQS, &mmc_data);
476
477static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
478 INTEGRATOR_CP_AACI_IRQS, NULL);
479
480static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
481 { IRQ_CP_CLCDCINT }, &clcd_data);
482
483static struct amba_device *amba_devs[] __initdata = {
484 &mmc_device,
485 &aaci_device,
486 &clcd_device,
487};
488
489static 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
389MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") 502MACHINE_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,
401MACHINE_END 514MACHINE_END
515
516#endif