Commit 4980f9bc2cec0f8ff0e0f2b021d46c7606ae1849

Authored by Linus Walleij
Committed by Russell King
1 parent dc81df520b

ARM: 7517/1: integrator: initial device tree support

This is initial device tree support for the ARM Integrator family,
we create a very basic device tree, #ifdef out the non-DT machines
when compiling for device tree.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Showing 6 changed files with 360 additions and 68 deletions Side-by-side Diff

Documentation/devicetree/bindings/arm/arm-boards
  1 +ARM Integrator/AP (Application Platform) and Integrator/CP (Compact Platform)
  2 +-----------------------------------------------------------------------------
  3 +ARM's oldest Linux-supported platform with connectors for different core
  4 +tiles of ARMv4, ARMv5 and ARMv6 type.
  5 +
  6 +Required properties (in root node):
  7 + compatible = "arm,integrator-ap"; /* Application Platform */
  8 + compatible = "arm,integrator-cp"; /* Compact Platform */
  9 +
  10 +FPGA type interrupt controllers, see the versatile-fpga-irq binding doc.
  11 +
  12 +
1 13 ARM Versatile Application and Platform Baseboards
2 14 -------------------------------------------------
3 15 ARM's development hardware platform with connectors for customizable
arch/arm/boot/dts/integrator.dtsi
  1 +/*
  2 + * SoC core Device Tree for the ARM Integrator platforms
  3 + */
  4 +
  5 +/include/ "skeleton.dtsi"
  6 +
  7 +/ {
  8 + timer@13000000 {
  9 + reg = <0x13000000 0x100>;
  10 + interrupt-parent = <&pic>;
  11 + interrupts = <5>;
  12 + };
  13 +
  14 + timer@13000100 {
  15 + reg = <0x13000100 0x100>;
  16 + interrupt-parent = <&pic>;
  17 + interrupts = <6>;
  18 + };
  19 +
  20 + timer@13000200 {
  21 + reg = <0x13000200 0x100>;
  22 + interrupt-parent = <&pic>;
  23 + interrupts = <7>;
  24 + };
  25 +
  26 + pic@14000000 {
  27 + compatible = "arm,versatile-fpga-irq";
  28 + #interrupt-cells = <1>;
  29 + interrupt-controller;
  30 + reg = <0x14000000 0x100>;
  31 + clear-mask = <0xffffffff>;
  32 + };
  33 +};
arch/arm/boot/dts/integratorap.dts
  1 +/*
  2 + * Device Tree for the ARM Integrator/AP platform
  3 + */
  4 +
  5 +/dts-v1/;
  6 +/include/ "integrator.dtsi"
  7 +
  8 +/ {
  9 + model = "ARM Integrator/AP";
  10 + compatible = "arm,integrator-ap";
  11 +
  12 + aliases {
  13 + arm,timer-primary = &timer2;
  14 + arm,timer-secondary = &timer1;
  15 + };
  16 +
  17 + chosen {
  18 + bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";
  19 + };
  20 +
  21 + timer0: timer@13000000 {
  22 + compatible = "arm,integrator-timer";
  23 + };
  24 +
  25 + timer1: timer@13000100 {
  26 + compatible = "arm,integrator-timer";
  27 + };
  28 +
  29 + timer2: timer@13000200 {
  30 + compatible = "arm,integrator-timer";
  31 + };
  32 +
  33 + pic: pic@14000000 {
  34 + valid-mask = <0x003fffff>;
  35 + };
  36 +};
arch/arm/boot/dts/integratorcp.dts
  1 +/*
  2 + * Device Tree for the ARM Integrator/CP platform
  3 + */
  4 +
  5 +/dts-v1/;
  6 +/include/ "integrator.dtsi"
  7 +
  8 +/ {
  9 + model = "ARM Integrator/CP";
  10 + compatible = "arm,integrator-cp";
  11 +
  12 + aliases {
  13 + arm,timer-primary = &timer2;
  14 + arm,timer-secondary = &timer1;
  15 + };
  16 +
  17 + chosen {
  18 + bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
  19 + };
  20 +
  21 + timer0: timer@13000000 {
  22 + compatible = "arm,sp804", "arm,primecell";
  23 + };
  24 +
  25 + timer1: timer@13000100 {
  26 + compatible = "arm,sp804", "arm,primecell";
  27 + };
  28 +
  29 + timer2: timer@13000200 {
  30 + compatible = "arm,sp804", "arm,primecell";
  31 + };
  32 +
  33 + pic: pic@14000000 {
  34 + valid-mask = <0x1fc003ff>;
  35 + };
  36 +
  37 + cic: cic@10000040 {
  38 + compatible = "arm,versatile-fpga-irq";
  39 + #interrupt-cells = <1>;
  40 + interrupt-controller;
  41 + reg = <0x10000040 0x100>;
  42 + clear-mask = <0xffffffff>;
  43 + valid-mask = <0x00000007>;
  44 + };
  45 +
  46 + sic: sic@ca000000 {
  47 + compatible = "arm,versatile-fpga-irq";
  48 + #interrupt-cells = <1>;
  49 + interrupt-controller;
  50 + reg = <0xca000000 0x100>;
  51 + clear-mask = <0x00000fff>;
  52 + valid-mask = <0x00000fff>;
  53 + };
  54 +};
arch/arm/mach-integrator/integrator_ap.c
... ... @@ -34,6 +34,8 @@
34 34 #include <linux/mtd/physmap.h>
35 35 #include <linux/clk.h>
36 36 #include <linux/platform_data/clk-integrator.h>
  37 +#include <linux/of_irq.h>
  38 +#include <linux/of_address.h>
37 39 #include <video/vga.h>
38 40  
39 41 #include <mach/hardware.h>
... ... @@ -161,23 +163,6 @@
161 163 vga_base = PCI_MEMORY_VADDR;
162 164 }
163 165  
164   -#define INTEGRATOR_SC_VALID_INT 0x003fffff
165   -
166   -static void __init ap_init_irq(void)
167   -{
168   - /* Disable all interrupts initially. */
169   - /* Do the core module ones */
170   - writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
171   -
172   - /* do the header card stuff next */
173   - writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
174   - writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
175   -
176   - fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
177   - -1, INTEGRATOR_SC_VALID_INT, NULL);
178   - integrator_clk_init(false);
179   -}
180   -
181 166 #ifdef CONFIG_PM
182 167 static unsigned long ic_irq_enable;
183 168  
184 169  
... ... @@ -330,9 +315,9 @@
330 315 return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
331 316 }
332 317  
333   -static void integrator_clocksource_init(unsigned long inrate)
  318 +static void integrator_clocksource_init(unsigned long inrate,
  319 + void __iomem *base)
334 320 {
335   - void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
336 321 u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
337 322 unsigned long rate = inrate;
338 323  
... ... @@ -349,7 +334,7 @@
349 334 setup_sched_clock(integrator_read_sched_clock, 16, rate);
350 335 }
351 336  
352   -static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
  337 +static void __iomem * clkevt_base;
353 338  
354 339 /*
355 340 * IRQ handler for the timer
356 341  
... ... @@ -421,11 +406,13 @@
421 406 .dev_id = &integrator_clockevent,
422 407 };
423 408  
424   -static void integrator_clockevent_init(unsigned long inrate)
  409 +static void integrator_clockevent_init(unsigned long inrate,
  410 + void __iomem *base, int irq)
425 411 {
426 412 unsigned long rate = inrate;
427 413 unsigned int ctrl = 0;
428 414  
  415 + clkevt_base = base;
429 416 /* Calculate and program a divisor */
430 417 if (rate > 0x100000 * HZ) {
431 418 rate /= 256;
... ... @@ -437,7 +424,7 @@
437 424 timer_reload = rate / HZ;
438 425 writel(ctrl, clkevt_base + TIMER_CTRL);
439 426  
440   - setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
  427 + setup_irq(irq, &integrator_timer_irq);
441 428 clockevents_config_and_register(&integrator_clockevent,
442 429 rate,
443 430 1,
444 431  
445 432  
... ... @@ -448,9 +435,91 @@
448 435 {
449 436 }
450 437  
  438 +#ifdef CONFIG_OF
  439 +
  440 +static void __init ap_init_timer_of(void)
  441 +{
  442 + struct device_node *node;
  443 + const char *path;
  444 + void __iomem *base;
  445 + int err;
  446 + int irq;
  447 + struct clk *clk;
  448 + unsigned long rate;
  449 +
  450 + clk = clk_get_sys("ap_timer", NULL);
  451 + BUG_ON(IS_ERR(clk));
  452 + clk_prepare_enable(clk);
  453 + rate = clk_get_rate(clk);
  454 +
  455 + err = of_property_read_string(of_aliases,
  456 + "arm,timer-primary", &path);
  457 + if (WARN_ON(err))
  458 + return;
  459 + node = of_find_node_by_path(path);
  460 + base = of_iomap(node, 0);
  461 + if (WARN_ON(!base))
  462 + return;
  463 + writel(0, base + TIMER_CTRL);
  464 + integrator_clocksource_init(rate, base);
  465 +
  466 + err = of_property_read_string(of_aliases,
  467 + "arm,timer-secondary", &path);
  468 + if (WARN_ON(err))
  469 + return;
  470 + node = of_find_node_by_path(path);
  471 + base = of_iomap(node, 0);
  472 + if (WARN_ON(!base))
  473 + return;
  474 + irq = irq_of_parse_and_map(node, 0);
  475 + writel(0, base + TIMER_CTRL);
  476 + integrator_clockevent_init(rate, base, irq);
  477 +}
  478 +
  479 +static struct sys_timer ap_of_timer = {
  480 + .init = ap_init_timer_of,
  481 +};
  482 +
  483 +static const struct of_device_id fpga_irq_of_match[] __initconst = {
  484 + { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
  485 + { /* Sentinel */ }
  486 +};
  487 +
  488 +static void __init ap_init_irq_of(void)
  489 +{
  490 + /* disable core module IRQs */
  491 + writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
  492 + of_irq_init(fpga_irq_of_match);
  493 + integrator_clk_init(false);
  494 +}
  495 +
  496 +static const char * ap_dt_board_compat[] = {
  497 + "arm,integrator-ap",
  498 + NULL,
  499 +};
  500 +
  501 +DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
  502 + .reserve = integrator_reserve,
  503 + .map_io = ap_map_io,
  504 + .nr_irqs = NR_IRQS_INTEGRATOR_AP,
  505 + .init_early = ap_init_early,
  506 + .init_irq = ap_init_irq_of,
  507 + .handle_irq = fpga_handle_irq,
  508 + .timer = &ap_of_timer,
  509 + .init_machine = ap_init,
  510 + .restart = integrator_restart,
  511 + .dt_compat = ap_dt_board_compat,
  512 +MACHINE_END
  513 +
  514 +#endif
  515 +
  516 +#ifdef CONFIG_ATAGS
  517 +
451 518 /*
452   - * Set up timer(s).
  519 + * This is where non-devicetree initialization code is collected and stashed
  520 + * for eventual deletion.
453 521 */
  522 +
454 523 static void __init ap_init_timer(void)
455 524 {
456 525 struct clk *clk;
457 526  
... ... @@ -465,14 +534,32 @@
465 534 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
466 535 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
467 536  
468   - integrator_clocksource_init(rate);
469   - integrator_clockevent_init(rate);
  537 + integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
  538 + integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
  539 + IRQ_TIMERINT1);
470 540 }
471 541  
472 542 static struct sys_timer ap_timer = {
473 543 .init = ap_init_timer,
474 544 };
475 545  
  546 +#define INTEGRATOR_SC_VALID_INT 0x003fffff
  547 +
  548 +static void __init ap_init_irq(void)
  549 +{
  550 + /* Disable all interrupts initially. */
  551 + /* Do the core module ones */
  552 + writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
  553 +
  554 + /* do the header card stuff next */
  555 + writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
  556 + writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
  557 +
  558 + fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
  559 + -1, INTEGRATOR_SC_VALID_INT, NULL);
  560 + integrator_clk_init(false);
  561 +}
  562 +
476 563 MACHINE_START(INTEGRATOR, "ARM-Integrator")
477 564 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
478 565 .atag_offset = 0x100,
... ... @@ -486,4 +573,6 @@
486 573 .init_machine = ap_init,
487 574 .restart = integrator_restart,
488 575 MACHINE_END
  576 +
  577 +#endif
arch/arm/mach-integrator/integrator_cp.c
... ... @@ -23,6 +23,8 @@
23 23 #include <linux/gfp.h>
24 24 #include <linux/mtd/physmap.h>
25 25 #include <linux/platform_data/clk-integrator.h>
  26 +#include <linux/of_irq.h>
  27 +#include <linux/of_address.h>
26 28  
27 29 #include <mach/hardware.h>
28 30 #include <mach/platform.h>
... ... @@ -53,10 +55,6 @@
53 55  
54 56 #define INTCP_PA_CLCD_BASE 0xc0000000
55 57  
56   -#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
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 58 #define INTCP_ETH_SIZE 0x10
61 59  
62 60 #define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE)
... ... @@ -143,37 +141,6 @@
143 141 iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
144 142 }
145 143  
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 144 /*
178 145 * Flash handling.
179 146 */
180 147  
181 148  
182 149  
183 150  
... ... @@ -356,19 +323,118 @@
356 323 #endif
357 324 }
358 325  
359   -static void __init intcp_init(void)
  326 +static void __init intcp_timer_init_of(void)
360 327 {
361   - int i;
  328 + struct device_node *node;
  329 + const char *path;
  330 + void __iomem *base;
  331 + int err;
  332 + int irq;
362 333  
363   - platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
  334 + err = of_property_read_string(of_aliases,
  335 + "arm,timer-primary", &path);
  336 + if (WARN_ON(err))
  337 + return;
  338 + node = of_find_node_by_path(path);
  339 + base = of_iomap(node, 0);
  340 + if (WARN_ON(!base))
  341 + return;
  342 + writel(0, base + TIMER_CTRL);
  343 + sp804_clocksource_init(base, node->name);
364 344  
365   - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
366   - struct amba_device *d = amba_devs[i];
367   - amba_device_register(d, &iomem_resource);
368   - }
369   - integrator_init(true);
  345 + err = of_property_read_string(of_aliases,
  346 + "arm,timer-secondary", &path);
  347 + if (WARN_ON(err))
  348 + return;
  349 + node = of_find_node_by_path(path);
  350 + base = of_iomap(node, 0);
  351 + if (WARN_ON(!base))
  352 + return;
  353 + irq = irq_of_parse_and_map(node, 0);
  354 + writel(0, base + TIMER_CTRL);
  355 + sp804_clockevents_init(base, irq, node->name);
370 356 }
371 357  
  358 +static struct sys_timer cp_of_timer = {
  359 + .init = intcp_timer_init_of,
  360 +};
  361 +
  362 +#ifdef CONFIG_OF
  363 +
  364 +static const struct of_device_id fpga_irq_of_match[] __initconst = {
  365 + { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
  366 + { /* Sentinel */ }
  367 +};
  368 +
  369 +static void __init intcp_init_irq_of(void)
  370 +{
  371 + of_irq_init(fpga_irq_of_match);
  372 + integrator_clk_init(true);
  373 +}
  374 +
  375 +static const char * intcp_dt_board_compat[] = {
  376 + "arm,integrator-cp",
  377 + NULL,
  378 +};
  379 +
  380 +DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
  381 + .reserve = integrator_reserve,
  382 + .map_io = intcp_map_io,
  383 + .nr_irqs = NR_IRQS_INTEGRATOR_CP,
  384 + .init_early = intcp_init_early,
  385 + .init_irq = intcp_init_irq_of,
  386 + .handle_irq = fpga_handle_irq,
  387 + .timer = &cp_of_timer,
  388 + .init_machine = intcp_init,
  389 + .restart = integrator_restart,
  390 + .dt_compat = intcp_dt_board_compat,
  391 +MACHINE_END
  392 +
  393 +#endif
  394 +
  395 +#ifdef CONFIG_ATAGS
  396 +
  397 +/*
  398 + * This is where non-devicetree initialization code is collected and stashed
  399 + * for eventual deletion.
  400 + */
  401 +
  402 +#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
  403 +#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
  404 +#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
  405 +
  406 +static void __init intcp_init_irq(void)
  407 +{
  408 + u32 pic_mask, cic_mask, sic_mask;
  409 +
  410 + /* These masks are for the HW IRQ registers */
  411 + pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
  412 + pic_mask |= (~((~0u) << (29 - 22))) << 22;
  413 + cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
  414 + sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
  415 +
  416 + /*
  417 + * Disable all interrupt sources
  418 + */
  419 + writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
  420 + writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
  421 + writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
  422 + writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
  423 + writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
  424 + writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
  425 +
  426 + fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
  427 + -1, pic_mask, NULL);
  428 +
  429 + fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
  430 + -1, cic_mask, NULL);
  431 +
  432 + fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
  433 + IRQ_CP_CPPLDINT, sic_mask, NULL);
  434 +
  435 + integrator_clk_init(true);
  436 +}
  437 +
372 438 #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
373 439 #define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
374 440 #define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
... ... @@ -400,4 +466,6 @@
400 466 .init_machine = intcp_init,
401 467 .restart = integrator_restart,
402 468 MACHINE_END
  469 +
  470 +#endif