From 853bcb0afc3f4403ba33c06ae76693fec330457b Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 Subject: [PATCH 1/2] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. Signed-off-by: Noralf Tronnes --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/bcm2708-rpi-b.dts | 8 ++++++++ arch/arm/boot/dts/bcm2708.dtsi | 27 +++++++++++++++++++++++++++ arch/arm/mach-bcm2708/Kconfig | 8 ++++++++ arch/arm/mach-bcm2708/bcm2708.c | 24 ++++++++++++++++++++++++ 5 files changed, 68 insertions(+) create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts create mode 100644 arch/arm/boot/dts/bcm2708.dtsi diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 377b7c3640337e..c118dc88eb8510 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \ diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts new file mode 100644 index 00000000000000..e319c8e3c99f93 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +/include/ "bcm2708.dtsi" + +/ { + compatible = "brcm,bcm2708"; + model = "Raspberry Pi"; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi new file mode 100644 index 00000000000000..d8f73ddacc9a89 --- /dev/null +++ b/arch/arm/boot/dts/bcm2708.dtsi @@ -0,0 +1,27 @@ +/include/ "skeleton.dtsi" + +/ { + compatible = "brcm,bcm2708"; + model = "BCM2708"; + + chosen { + /* + bootargs must be 1024 characters long because the + VC bootloader can't expand it + */ + bootargs = "console=ttyAMA0 "; + }; + + axi { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x7e000000 0x20000000 0x02000000>; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig index e151ed4efbbb38..182e7bafbfe388 100644 --- a/arch/arm/mach-bcm2708/Kconfig +++ b/arch/arm/mach-bcm2708/Kconfig @@ -9,6 +9,14 @@ config MACH_BCM2708 help Include support for the Broadcom(R) BCM2708 platform. +config BCM2708_DT + bool "BCM2708 Device Tree support" + depends on MACH_BCM2708 + default n + select USE_OF + help + Enable Device Tree support for BCM2708 + config BCM2708_GPIO bool "BCM2708 gpio support" depends on MACH_BCM2708 diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c index 9bf25082c91fd7..6929e2e5f59060 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -762,6 +763,22 @@ static void bcm2708_power_off(void) } } +#ifdef CONFIG_OF +static void __init bcm2708_dt_init(void) +{ + int ret; + + of_clk_init(NULL); + ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (ret) { + pr_err("of_platform_populate failed: %d\n", ret); + BUG(); + } +} +#else +static void __init bcm2708_dt_init(void) { } +#endif /* CONFIG_OF */ + void __init bcm2708_init(void) { int i; @@ -773,6 +790,7 @@ void __init bcm2708_init(void) pm_power_off = bcm2708_power_off; bcm2708_init_clocks(); + bcm2708_dt_init(); bcm_register_device(&bcm2708_dmaman_device); bcm_register_device(&bcm2708_vcio_device); @@ -996,6 +1014,11 @@ static void __init board_reserve(void) #endif } +static const char * const bcm2708_compat[] = { + "brcm,bcm2708", + NULL +}; + MACHINE_START(BCM2708, "BCM2708") /* Maintainer: Broadcom Europe Ltd. */ .map_io = bcm2708_map_io, @@ -1005,6 +1028,7 @@ MACHINE_START(BCM2708, "BCM2708") .init_early = bcm2708_init_early, .reserve = board_reserve, .restart = bcm2708_restart, + .dt_compat = bcm2708_compat, MACHINE_END module_param(boardrev, uint, 0644); From ba97112380cbecc90c14af939f33b1dfc5c19990 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:47:48 +0200 Subject: [PATCH 2/2] BCM2708: armctrl: Add IRQ Device Tree support Add Device Tree IRQ support for BCM2708. Usage is the same as for irq-bcm2835. See binding document: brcm,bcm2835-armctrl-ic.txt A bank 3 is added to handle GPIO interrupts. This is done because armctrl also handles GPIO interrupts. Signed-off-by: Noralf Tronnes --- arch/arm/boot/dts/bcm2708.dtsi | 9 +++ arch/arm/mach-bcm2708/armctrl.c | 97 +++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi index d8f73ddacc9a89..39fbf9c3f3d008 100644 --- a/arch/arm/boot/dts/bcm2708.dtsi +++ b/arch/arm/boot/dts/bcm2708.dtsi @@ -4,6 +4,8 @@ compatible = "brcm,bcm2708"; model = "BCM2708"; + interrupt-parent = <&intc>; + chosen { /* bootargs must be 1024 characters long because the @@ -17,6 +19,13 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x7e000000 0x20000000 0x02000000>; + + intc: interrupt-controller { + compatible = "brcm,bcm2708-armctrl-ic"; + reg = <0x7e00b200 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; }; clocks { diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c index d4c53336d7840c..42f5e1c951b300 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -79,6 +81,100 @@ static void armctrl_unmask_irq(struct irq_data *d) } } +#ifdef CONFIG_OF + +#define NR_IRQS_BANK0 21 +#define NR_BANKS 3 + 1 /* bank 3 is used for GPIO interrupts */ +#define IRQS_PER_BANK 32 + +/* from drivers/irqchip/irq-bcm2835.c */ +static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + if (WARN_ON(intsize != 2)) + return -EINVAL; + + if (WARN_ON(intspec[0] >= NR_BANKS)) + return -EINVAL; + + if (WARN_ON(intspec[1] >= IRQS_PER_BANK)) + return -EINVAL; + + if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0)) + return -EINVAL; + + if (intspec[0] == 0) + *out_hwirq = ARM_IRQ0_BASE + intspec[1]; + else if (intspec[0] == 1) + *out_hwirq = ARM_IRQ1_BASE + intspec[1]; + else if (intspec[0] == 2) + *out_hwirq = ARM_IRQ2_BASE + intspec[1]; + else + *out_hwirq = GPIO_IRQ_START + intspec[1]; + + /* reverse remap_irqs[] */ + switch (*out_hwirq) { + case INTERRUPT_VC_JPEG: + *out_hwirq = INTERRUPT_JPEG; + break; + case INTERRUPT_VC_USB: + *out_hwirq = INTERRUPT_USB; + break; + case INTERRUPT_VC_3D: + *out_hwirq = INTERRUPT_3D; + break; + case INTERRUPT_VC_DMA2: + *out_hwirq = INTERRUPT_DMA2; + break; + case INTERRUPT_VC_DMA3: + *out_hwirq = INTERRUPT_DMA3; + break; + case INTERRUPT_VC_I2C: + *out_hwirq = INTERRUPT_I2C; + break; + case INTERRUPT_VC_SPI: + *out_hwirq = INTERRUPT_SPI; + break; + case INTERRUPT_VC_I2SPCM: + *out_hwirq = INTERRUPT_I2SPCM; + break; + case INTERRUPT_VC_SDIO: + *out_hwirq = INTERRUPT_SDIO; + break; + case INTERRUPT_VC_UART: + *out_hwirq = INTERRUPT_UART; + break; + case INTERRUPT_VC_ARASANSDIO: + *out_hwirq = INTERRUPT_ARASANSDIO; + break; + } + + *out_type = IRQ_TYPE_NONE; + return 0; +} + +static struct irq_domain_ops armctrl_ops = { + .xlate = armctrl_xlate +}; + +void __init armctrl_dt_init(void) +{ + struct device_node *np; + struct irq_domain *domain; + + np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic"); + if (!np) + return; + + domain = irq_domain_add_legacy(np, NR_IRQS, IRQ_ARMCTRL_START, 0, + &armctrl_ops, NULL); + WARN_ON(!domain); +} +#else +void __init armctrl_dt_init(void) { } +#endif /* CONFIG_OF */ + #if defined(CONFIG_PM) /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ @@ -215,5 +311,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, armctrl_pm_register(base, irq_start, resume_sources); init_FIQ(FIQ_START); + armctrl_dt_init(); return 0; }