Add basic support for Allwinner A1X SoCs
Subsystems (7)
cover Add basic support for Allwinner A1X SoCs
Hi,
You'll find in this patchset the initial support for Allwinner A10 and A13 SoCs from Allwinner. Since the internal name of these SoCs are sun4i and sun5i, the mach- directory is named sunxi.
You can find these SoCs in the Cubieboard, the A13-olinuxino or the Melee A1000.
Both SoCs should work fine, as the A13 is a trimmed down version of the A10, but it has only been tested on a A13-OlinuXino from Olimex.
Support is quite minimal for now, since it only includes timer and IRQ controller drivers, so we can only boot to userspace through initramfs. Support for the other peripherals on these SoCs will come eventually.
Thanks,
Maxime
Maxime Ripard (6):
clocksource: sunxi: Add Allwinner A1X Timer Driver
irqchip: sunxi: Add irq controller driver
ARM: sunxi: Add basic support for Allwinner A1x SoCs
ARM: sunxi: Add earlyprintk support
ARM: sunxi: Add device tree for the A13 and the Olinuxino board
ARM: sunxi: Add entry to MAINTAINERS
.../interrupt-controller/allwinner,sunxi-ic.txt | 104 ++++++++++++ .../bindings/timer/allwinner,sunxi-timer.txt | 15 ++ MAINTAINERS | 6 + arch/arm/Kconfig | 2 + arch/arm/Kconfig.debug | 8 + arch/arm/Makefile | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/sun5i-olinuxino.dts | 30 ++++ arch/arm/boot/dts/sun5i.dtsi | 58 +++++++ arch/arm/include/debug/sunxi.S | 22 +++ arch/arm/mach-sunxi/Kconfig | 9 + arch/arm/mach-sunxi/Makefile | 1 + arch/arm/mach-sunxi/Makefile.boot | 1 + arch/arm/mach-sunxi/sunxi.c | 60 +++++++ arch/arm/mach-sunxi/sunxi.h | 20 +++ drivers/clocksource/Kconfig | 3 + drivers/clocksource/Makefile | 1 + drivers/clocksource/sunxi_timer.c | 160 ++++++++++++++++++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-sunxi.c | 173 ++++++++++++++++++++ include/linux/irqchip/sunxi.h | 27 +++ include/linux/sunxi_timer.h | 24 +++ 22 files changed, 727 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt create mode 100644 Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt create mode 100644 arch/arm/boot/dts/sun5i-olinuxino.dts create mode 100644 arch/arm/boot/dts/sun5i.dtsi create mode 100644 arch/arm/include/debug/sunxi.S create mode 100644 arch/arm/mach-sunxi/Kconfig create mode 100644 arch/arm/mach-sunxi/Makefile create mode 100644 arch/arm/mach-sunxi/Makefile.boot create mode 100644 arch/arm/mach-sunxi/sunxi.c create mode 100644 arch/arm/mach-sunxi/sunxi.h create mode 100644 drivers/clocksource/sunxi_timer.c create mode 100644 drivers/irqchip/irq-sunxi.c create mode 100644 include/linux/irqchip/sunxi.h create mode 100644 include/linux/sunxi_timer.h
Signature · 1 line
1.7.9.5
PATCH 1/6 clocksource: sunxi: Add Allwinner A1X Timer Driver
--- .../bindings/timer/allwinner,sunxi-timer.txt | 15 ++ drivers/clocksource/Kconfig | 3 + drivers/clocksource/Makefile | 1 + drivers/clocksource/sunxi_timer.c | 160 ++++++++++++++++++++ include/linux/sunxi_timer.h | 24 +++ 5 files changed, 203 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt create mode 100644 drivers/clocksource/sunxi_timer.c create mode 100644 include/linux/sunxi_timer.h
Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt new file +15 -0
@@ -0,0 +1,15 @@ +Allwinner A1X SoCs Timer Controller + +Required properties: + +- compatible : should be "allwinner,sunxi-timer" +- reg : Specifies base physical address and size of the registers. +- interrupts : The interrupt of the first timer + +Example: + +timer { + compatible = "allwinner,sunxi-timer"; + reg = <0x01c20c00 0x400>; + interrupts = <22>; +};
drivers/clocksource/Kconfig +3 -0
@@ -22,6 +22,9 @@ config DW_APB_TIMER_OF config ARMADA_370_XP_TIMER bool +config SUNXI_TIMER + bool + config CLKSRC_DBX500_PRCMU bool "Clocksource PRCMU Timer" depends on UX500_SOC_DB8500
drivers/clocksource/Makefile +1 -0
@@ -14,5 +14,6 @@ obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o +obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o
drivers/clocksource/sunxi_timer.c new file +160 -0
160 lines not on this page · raw message
include/linux/sunxi_timer.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +* Copyright 2012 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __SUNXI_TIMER_H +#define __SUNXI_TIMER_H + +#include <asm/mach/time.h> + +extern struct sys_timer sunxi_timer; + +#endif
Signature · 1 line
1.7.9.5
PATCH 1/6 clocksource: sunxi: Add Allwinner A1X Timer Driver
Dear Maxime Ripard,
Quoted 1 line · Maxime Ripard
+#define
TIMER_CLKSRC24000000
You should rather add a DT node for this fixed rate clock, and pass a clocks = <&fooclk> DT property to your timer DT node, and then in your timer driver do an of_clk_get() + clk_get_rate() to get the frequency of this.
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 1/6 clocksource: sunxi: Add Allwinner A1X Timer Driver
In reply to Maxime RipardDear Maxime Ripard,
Quoted 4 lines · Maxime Ripard
drivers/clocksource/sunxi_timer.c new file +4
-0+/* Enable timer0 interrupt */ + val =readl (timer_base +TIMER_CTL_REG ); +writel (val |TIMER_CTL_ENABLE , timer_base +TIMER_CTL_REG ); +
drivers/clocksource/sunxi_timer.c line 155
Quoted 10 lines
drivers/clocksource/sunxi_timer.c new file +10
-0+ sunxi_clockevent.mult =div_sc (TIMER_CLKSRC /TIMER_SCAL , +NSEC_PER_SEC , + sunxi_clockevent.shift); + sunxi_clockevent.max_delta_ns =clockevent_delta2ns (0xff , + &sunxi_clockevent); + sunxi_clockevent.min_delta_ns =clockevent_delta2ns (0x1 , + &sunxi_clockevent); + sunxi_clockevent.cpumask =cpumask_of (0 ); + +clockevents_register_device (&sunxi_clockevent);
I haven't looked in details, but maybe it is possible here to use clockevents_config_and_register() instead of clockevents_register_device(). It would simplify this code a bit if it works.
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 2/6 irqchip: sunxi: Add irq controller driver
In reply to Maxime Ripard--- .../interrupt-controller/allwinner,sunxi-ic.txt | 104 ++++++++++++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-sunxi.c | 173 ++++++++++++++++++++ include/linux/irqchip/sunxi.h | 27 +++ 4 files changed, 305 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt create mode 100644 drivers/irqchip/irq-sunxi.c create mode 100644 include/linux/irqchip/sunxi.h
Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt new file +104 -0
@@ -0,0 +1,104 @@ +Allwinner Sunxi Interrupt Controller + +Required properties: + +- compatible : should be "allwinner,sunxi-ic" +- reg : Specifies base physical address and size of the registers. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 1. + +The interrupt sources are as follows: + +0: ENMI +1: UART0 +2: UART1 +3: UART2 +4: UART3 +5: IR0 +6: IR1 +7: I2C0 +8: I2C1 +9: I2C2 +10: SPI0 +11: SPI1 +12: SPI2 +13: SPDIF +14: AC97 +15: TS +16: I2S +17: UART4 +18: UART5 +19: UART6 +20: UART7 +21: KEYPAD +22: TIMER0 +23: TIMER1 +24: TIMER2 +25: TIMER3 +26: CAN +27: DMA +28: PIO +29: TOUCH_PANEL +30: AUDIO_CODEC +31: LRADC +32: SDMC0 +33: SDMC1 +34: SDMC2 +35: SDMC3 +36: MEMSTICK +37: NAND +38: USB0 +39: USB1 +40: USB2 +41: SCR +42: CSI0 +43: CSI1 +44: LCDCTRL0 +45: LCDCTRL1 +46: MP +47: DEFEBE0 +48: DEFEBE1 +49: PMU +50: SPI3 +51: TZASC +52: PATA +53: VE +54: SS +55: EMAC +56: SATA +57: GPS +58: HDMI +59: TVE +60: ACE +61: TVD +62: PS2_0 +63: PS2_1 +64: USB3 +65: USB4 +66: PLE_PFM +67: TIMER4 +68: TIMER5 +69: GPU_GP +70: GPU_GPMMU +71: GPU_PP0 +72: GPU_PPMMU0 +73: GPU_PMU +74: GPU_RSV0 +75: GPU_RSV1 +76: GPU_RSV2 +77: GPU_RSV3 +78: GPU_RSV4 +79: GPU_RSV5 +80: GPU_RSV6 +82: SYNC_TIMER0 +83: SYNC_TIMER1 + +Example: + +intc: interrupt-controller { + compatible = "allwinner,sunxi-ic"; + reg = <0x01c20400 0x400>; + interrupt-controller; + #interrupt-cells = <2>; +};
drivers/irqchip/Makefile +1 -0
@@ -1 +1,2 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o +obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o
drivers/irqchip/irq-sunxi.c new file +173 -0
173 lines not on this page · raw message
include/linux/irqchip/sunxi.h new file +27 -0
@@ -0,0 +1,27 @@ +/* +* Copyright 2012 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __LINUX_IRQCHIP_SUNXI_H +#define __LINUX_IRQCHIP_SUNXI_H + +#include <asm/exception.h> + +extern void sunxi_init_irq (void ); + +extern asmlinkage void __exception_irq_entry sunxi_handle_irq( +struct pt_regs *regs); + +#endif
Signature · 1 line
1.7.9.5
PATCH 2/6 irqchip: sunxi: Add irq controller driver
On 11/15/2012 11:46 PM, Maxime Ripard wrote:
<snip>
Quoted 48 lines
drivers/irqchip/irq-sunxi.c new file +42
-0@@ -0,0 +1,173 @@ +/* +* Allwinner A1X SoCs IRQ chip driver. +* +* Copyright (C) 2012 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* Based on code from +* Allwinner Technology Co., Ltd. <www.allwinnertech.com> +* Benn Huang <[email protected]> +* +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without any +* warranty of any kind, whether express or implied. +*/ + +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> + +#include <linux/irqchip/sunxi.h> + +#define SUNXI_IRQ_PROTECTION_REG 0x08 +#define SUNXI_IRQ_NMI_CTRL_REG 0x0c +#define SUNXI_IRQ_PENDING_REG (x) (0x10 + 0x4 * x) +#define SUNXI_IRQ_FIQ_PENDING_REG (x) (0x20 + 0x4 * x) +#define SUNXI_IRQ_ENABLE_REG (x) (0x40 + 0x4 * x) +#define SUNXI_IRQ_MASK_REG (x) (0x50 + 0x4 * x) + +static void __iomem *sunxi_irq_base; +static struct irq_domain *sunxi_irq_domain; + +void sunxi_irq_ack (struct irq_data *irqd) +{ +unsigned int irq =irqd_to_hwirq (irqd); +unsigned int irq_off = irq %32 ; +int reg = irq /32 ; +u32 val; + + val =readl (sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg));
drivers/irqchip/irq-sunxi.c line 52
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+writel (val & ~(1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); + + val =readl (sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); + + val =readl (sunxi_irq_base +SUNXI_IRQ_PENDING_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_PENDING_REG (reg));
Are you sure that you need to touch all those 23registers to ack the interrupt? I know that the original code provided by Allwinner does exactly this. My tests have shown though, that writing to the pending reg is enough.
Quoted 6 lines
drivers/irqchip/irq-sunxi.c new file +6
-0+} + +static void sunxi_irq_mask (struct irq_data *irqd) +{ +unsigned int irq =irqd_to_hwirq (irqd); +unsigned int irq_off = irq %32 ;
drivers/irqchip/irq-sunxi.c line 68
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+int reg = irq /32 ; +u32 val; + + val =readl (sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); +writel (val & ~(1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); + + val =readl (sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg));
I unmasked all interrupts in the mask register in the init function. Then only using the enable register for masking/unmasking seems to be enough. What do you think?
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+} + +static void sunxi_irq_unmask (struct irq_data *irqd) +{ +unsigned int irq =irqd_to_hwirq (irqd); +unsigned int irq_off = irq %32 ; +int reg = irq /32 ; +u32 val; + + val =readl (sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg));
drivers/irqchip/irq-sunxi.c line 88
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); + + val =readl (sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); +writel (val & ~(1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); + +/* Must clear pending bit when enabled */ +if (irq ==0 ) +writel (1 , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (0 ));
Again. Might be that one register is enough here.
Quoted 4 lines
drivers/irqchip/irq-sunxi.c new file +4
-0+} + +static struct irq_chip sunxi_irq_chip = { + .name ="sunxi_irq" ,
drivers/irqchip/irq-sunxi.c line 102
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+ .irq_ack = sunxi_irq_ack, + .irq_mask = sunxi_irq_mask, + .irq_unmask = sunxi_irq_unmask, +}; + +static int sunxi_irq_map (struct irq_domain *d,unsigned int virq, +irq_hw_number_t hw) +{ +irq_set_chip (virq, &sunxi_irq_chip); +irq_set_handler (virq, handle_level_irq);
irq_set_chip_and_handler()
Quoted 17 lines
drivers/irqchip/irq-sunxi.c new file +17
-0+set_irq_flags (virq,IRQF_VALID |IRQF_PROBE ); + +return 0 ; +} + +static struct irq_domain_ops sunxi_irq_ops = { + .map = sunxi_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int __init sunxi_of_init (struct device_node *node, +struct device_node *parent) +{ + sunxi_irq_base =of_iomap (node,0 ); +if (!sunxi_irq_base) +panic ("%s: unable to map IC registers\n" , + node->full_name);
drivers/irqchip/irq-sunxi.c line 129
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+ +/* Disable all interrupts */ +writel (0 , sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (0 )); +writel (0 , sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (1 )); +writel (0 , sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (2 )); + +/* Mask all the interrupts */ +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_MASK_REG (0 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_MASK_REG (1 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_MASK_REG (2 ));
Here is where I wrote 0 to the mask registers.
Quoted 32 lines
drivers/irqchip/irq-sunxi.c new file +32
-0+/* Clear all the pending interrupts */ +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (0 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (1 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (2 )); + +/* Enable protection mode */ +writel (0x01 , sunxi_irq_base +SUNXI_IRQ_PROTECTION_REG ); + +/* Configure the external interrupt source type */ +writel (0x00 , sunxi_irq_base +SUNXI_IRQ_NMI_CTRL_REG ); + + sunxi_irq_domain =irq_domain_add_linear (node,3 *32 , + &sunxi_irq_ops,NULL ); +if (!sunxi_irq_domain) +panic ("%s: unable to create IRQ domain\n" , node->full_name); + +return 0 ; +} + +static struct of_device_id sunxi_irq_dt_ids[]__initconst = { + { .compatible ="allwinner,sunxi-ic" , .data = sunxi_of_init } +}; + +void __init sunxi_init_irq (void ) +{ +of_irq_init (sunxi_irq_dt_ids); +} + +asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) +{ +u32 irq, reg; +int i;
drivers/irqchip/irq-sunxi.c line 172
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+ +for (i =0 ; i <3 ; i++) { + reg =readl (sunxi_irq_base +SUNXI_IRQ_PENDING_REG (i)); +if (reg ==0 ) +continue ; + irq =ilog2 (reg); +break ; + } + irq =irq_find_mapping (sunxi_irq_domain, irq); +handle_IRQ (irq, regs);
Why don't you use the interrupt-vector register to get the active interrupt source? Here is my version:
asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs)
{
u32 irq;
irq = readl(int_base + SW_INT_VECTOR_REG) >> 2;
irq = irq_find_mapping(sunxi_vic_domain, irq);
handle_IRQ(irq, regs);
}I suggest you give it a try.
Cheers,
Stefan
PATCH 2/6 irqchip: sunxi: Add irq controller driver
Hi Stefan,
Le 16/11/2012 08:35, Stefan Roese a ?crit :
Quoted 59 lines · Maxime Ripard
<snip>
Quoted 55 lines
drivers/irqchip/irq-sunxi.c new file +49
-0@@ -0,0 +1,173 @@ +/* +* Allwinner A1X SoCs IRQ chip driver. +* +* Copyright (C) 2012 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* Based on code from +* Allwinner Technology Co., Ltd. <www.allwinnertech.com> +* Benn Huang <[email protected]> +* +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without any +* warranty of any kind, whether express or implied. +*/ + +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> + +#include <linux/irqchip/sunxi.h> + +#define SUNXI_IRQ_PROTECTION_REG 0x08 +#define SUNXI_IRQ_NMI_CTRL_REG 0x0c +#define SUNXI_IRQ_PENDING_REG (x) (0x10 + 0x4 * x) +#define SUNXI_IRQ_FIQ_PENDING_REG (x) (0x20 + 0x4 * x) +#define SUNXI_IRQ_ENABLE_REG (x) (0x40 + 0x4 * x) +#define SUNXI_IRQ_MASK_REG (x) (0x50 + 0x4 * x) + +static void __iomem *sunxi_irq_base; +static struct irq_domain *sunxi_irq_domain; + +void sunxi_irq_ack (struct irq_data *irqd) +{ +unsigned int irq =irqd_to_hwirq (irqd); +unsigned int irq_off = irq %32 ; +int reg = irq /32 ; +u32 val; + + val =readl (sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); +writel (val & ~(1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); + + val =readl (sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); +
Quoted 8 lines
drivers/irqchip/irq-sunxi.c line 52
Quoted 3 lines
drivers/irqchip/irq-sunxi.c new file +3
-0+ val =readl (sunxi_irq_base +SUNXI_IRQ_PENDING_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_PENDING_REG (reg));Are you sure that you need to touch all those 23registers to ack the interrupt? I know that the original code provided by Allwinner does exactly this. My tests have shown though, that writing to the pending reg is enough.
Ok, I'll test that and remove the first two writes then.
Quoted 13 lines
Quoted 13 lines
drivers/irqchip/irq-sunxi.c new file +12
-0+} + +static void sunxi_irq_mask (struct irq_data *irqd) +{ +unsigned int irq =irqd_to_hwirq (irqd); +unsigned int irq_off = irq %32 ; +int reg = irq /32 ; +u32 val; + + val =readl (sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); +writel (val & ~(1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg));
Quoted 8 lines
drivers/irqchip/irq-sunxi.c line 48
Quoted 4 lines
drivers/irqchip/irq-sunxi.c new file +4
-0+ + val =readl (sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg));I unmasked all interrupts in the mask register in the init function. Then only using the enable register for masking/unmasking seems to be enough. What do you think?
That's reasonable I guess. It will be in the v2.
Quoted 14 lines
Quoted 14 lines
drivers/irqchip/irq-sunxi.c new file +14
-0+} + +static void sunxi_irq_unmask (struct irq_data *irqd) +{ +unsigned int irq =irqd_to_hwirq (irqd); +unsigned int irq_off = irq %32 ; +int reg = irq /32 ; +u32 val; + + val =readl (sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); +writel (val | (1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (reg)); + + val =readl (sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg));
Quoted 8 lines
drivers/irqchip/irq-sunxi.c line 88
Quoted 6 lines
drivers/irqchip/irq-sunxi.c new file +6
-0+writel (val & ~(1 << irq_off), + sunxi_irq_base +SUNXI_IRQ_MASK_REG (reg)); + +/* Must clear pending bit when enabled */ +if (irq ==0 ) +writel (1 , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (0 ));Again. Might be that one register is enough here.
Ok.
Quoted 8 lines
Quoted 8 lines
drivers/irqchip/irq-sunxi.c new file +8
-0+} + +static struct irq_chip sunxi_irq_chip = { + .name ="sunxi_irq" , + .irq_ack = sunxi_irq_ack, + .irq_mask = sunxi_irq_mask, + .irq_unmask = sunxi_irq_unmask, +};
Quoted 8 lines
drivers/irqchip/irq-sunxi.c line 102
Quoted 6 lines
drivers/irqchip/irq-sunxi.c new file +6
-0+ +static int sunxi_irq_map (struct irq_domain *d,unsigned int virq, +irq_hw_number_t hw) +{ +irq_set_chip (virq, &sunxi_irq_chip); +irq_set_handler (virq, handle_level_irq);
irq_set_chip_and_handler()
Ok.
Quoted 85 lines
Quoted 17 lines
drivers/irqchip/irq-sunxi.c new file +17
-0+set_irq_flags (virq,IRQF_VALID |IRQF_PROBE ); + +return 0 ; +} + +static struct irq_domain_ops sunxi_irq_ops = { + .map = sunxi_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int __init sunxi_of_init (struct device_node *node, +struct device_node *parent) +{ + sunxi_irq_base =of_iomap (node,0 ); +if (!sunxi_irq_base) +panic ("%s: unable to map IC registers\n" , + node->full_name);drivers/irqchip/irq-sunxi.c line 129
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+ +/* Disable all interrupts */ +writel (0 , sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (0 )); +writel (0 , sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (1 )); +writel (0 , sunxi_irq_base +SUNXI_IRQ_ENABLE_REG (2 )); + +/* Mask all the interrupts */ +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_MASK_REG (0 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_MASK_REG (1 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_MASK_REG (2 ));Here is where I wrote 0 to the mask registers.
Quoted 32 lines
drivers/irqchip/irq-sunxi.c new file +32
-0+/* Clear all the pending interrupts */ +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (0 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (1 )); +writel (0xffffffff , sunxi_irq_base +SUNXI_IRQ_PENDING_REG (2 )); + +/* Enable protection mode */ +writel (0x01 , sunxi_irq_base +SUNXI_IRQ_PROTECTION_REG ); + +/* Configure the external interrupt source type */ +writel (0x00 , sunxi_irq_base +SUNXI_IRQ_NMI_CTRL_REG ); + + sunxi_irq_domain =irq_domain_add_linear (node,3 *32 , + &sunxi_irq_ops,NULL ); +if (!sunxi_irq_domain) +panic ("%s: unable to create IRQ domain\n" , node->full_name); + +return 0 ; +} + +static struct of_device_id sunxi_irq_dt_ids[]__initconst = { + { .compatible ="allwinner,sunxi-ic" , .data = sunxi_of_init } +}; + +void __init sunxi_init_irq (void ) +{ +of_irq_init (sunxi_irq_dt_ids); +} + +asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) +{ +u32 irq, reg; +int i;drivers/irqchip/irq-sunxi.c line 172
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+ +for (i =0 ; i <3 ; i++) { + reg =readl (sunxi_irq_base +SUNXI_IRQ_PENDING_REG (i)); +if (reg ==0 ) +continue ; + irq =ilog2 (reg); +break ; + } + irq =irq_find_mapping (sunxi_irq_domain, irq); +handle_IRQ (irq, regs);Why don't you use the interrupt-vector register to get the active interrupt source? Here is my version:
asmlinkage void
__exception_irq_entrysunxi_handle_irq(struct pt_regs *regs){ u32 irq; irq = readl(int_base + SW_INT_VECTOR_REG) >> 2; irq = irq_find_mapping(sunxi_vic_domain, irq); handle_IRQ(irq, regs); }
Quoted 1 line
I suggest you give it a try.
It definitely looks nicer. I'll try that and update.
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 2/6 irqchip: sunxi: Add irq controller driver
Quoted 22 lines · Maxime Ripard
Quoted 22 lines
Quoted 4 lines
drivers/irqchip/irq-sunxi.c new file +4
-0+asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) +{ +u32 irq, reg; +int i;drivers/irqchip/irq-sunxi.c line 172
Quoted 10 lines
drivers/irqchip/irq-sunxi.c new file +10
-0+ +for (i =0 ; i <3 ; i++) { + reg =readl (sunxi_irq_base +SUNXI_IRQ_PENDING_REG (i)); +if (reg ==0 ) +continue ; + irq =ilog2 (reg); +break ; + } + irq =irq_find_mapping (sunxi_irq_domain, irq); +handle_IRQ (irq, regs);Why don't you use the interrupt-vector register to get the active interrupt source? Here is my version:
asmlinkage void
__exception_irq_entrysunxi_handle_irq(struct pt_regs *regs){ u32 irq;
Quoted 8 lines
Quoted 6 lines
irq = readl(int_base + SW_INT_VECTOR_REG) >> 2; irq = irq_find_mapping(sunxi_vic_domain, irq); handle_IRQ(irq, regs); }I suggest you give it a try.
It definitely looks nicer. I'll try that and update.
How does this SW_INT_VECTOR_REG behave when there are multiple interrupts pending? Shouldn't the code be something like:
do {
hwirq = readl(int_base + SW_INT_VECTOR_REG) >> 2;
irq = irq_find_mapping(sunxi_vic_domain, hwirq);
handle_IRQ(irq, regs);
} while(hwirq != 0);Or maybe the != 0 is not the good condition, but the idea is to handle all pending interrupts. That said, the original code from Maxime was not doing that as well.
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 2/6 irqchip: sunxi: Add irq controller driver
Quoted 9 lines · Thomas Petazzoni
Quoted 9 lines
Quoted 9 lines
asmlinkage void
__exception_irq_entrysunxi_handle_irq(struct pt_regs *regs){ u32 irq; irq = readl(int_base + SW_INT_VECTOR_REG) >> 2; irq = irq_find_mapping(sunxi_vic_domain, irq); handle_IRQ(irq, regs); }
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
I suggest you give it a try.
It definitely looks nicer. I'll try that and update.
How does this
SW_INT_VECTOR_REGbehave when there are multiple interrupts pending?
Not 100% sure. Hard to guess with this sparse documentation. I would expect that multiple interrupts would be queued here.
Quoted 11 lines
Shouldn't the code be something like:
do { hwirq = readl(int_base + SW_INT_VECTOR_REG) >> 2; irq = irq_find_mapping(sunxi_vic_domain, hwirq); handle_IRQ(irq, regs); } while(hwirq != 0);Or maybe the != 0 is not the good condition, but the idea is to handle all pending interrupts. That said, the original code from Maxime was not doing that as well.
Yes, that would be a good change.
Thanks,
Stefan
PATCH 3/6 ARM: sunxi: Add basic support for Allwinner A1x SoCs
In reply to Maxime Ripard--- arch/arm/Kconfig | 2 ++ arch/arm/Makefile | 1 + arch/arm/mach-sunxi/Kconfig | 9 ++++++ arch/arm/mach-sunxi/Makefile | 1 + arch/arm/mach-sunxi/Makefile.boot | 1 + arch/arm/mach-sunxi/sunxi.c | 60 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-sunxi/sunxi.h | 20 +++++++++++++ 7 files changed, 94 insertions(+) create mode 100644 arch/arm/mach-sunxi/Kconfig create mode 100644 arch/arm/mach-sunxi/Makefile create mode 100644 arch/arm/mach-sunxi/Makefile.boot create mode 100644 arch/arm/mach-sunxi/sunxi.c create mode 100644 arch/arm/mach-sunxi/sunxi.h
arch/arm/Kconfig +2 -0
@@ -1113,6 +1113,8 @@ source "arch/arm/mach-exynos/Kconfig" source "arch/arm/mach-shmobile/Kconfig" +source "arch/arm/mach-sunxi/Kconfig" + source "arch/arm/mach-prima2/Kconfig" source "arch/arm/mach-tegra/Kconfig"
arch/arm/Makefile +1 -0
@@ -193,6 +193,7 @@ machine-$(CONFIG_ARCH_SPEAR13XX) += spear13xx machine-$(CONFIG_ARCH_SPEAR3XX) += spear3xx machine-$(CONFIG_MACH_SPEAR600) += spear6xx machine-$(CONFIG_ARCH_ZYNQ) += zynq +machine-$(CONFIG_ARCH_SUNXI) += sunxi # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name.
arch/arm/mach-sunxi/Kconfig new file +9 -0
@@ -0,0 +1,9 @@ +config ARCH_SUNXI + bool "Allwinner A1X SOCs" if ARCH_MULTI_V7 + select CLKSRC_MMIO + select COMMON_CLK + select GENERIC_CLOCKEVENTS + select GENERIC_IRQ_CHIP + select PINCTRL + select SPARSE_IRQ + select SUNXI_TIMER
arch/arm/mach-sunxi/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
arch/arm/mach-sunxi/Makefile.boot new file +1 -0
@@ -0,0 +1 @@ +zreladdr-$(CONFIG_ARCH_SUNXI) += 0x40008000
arch/arm/mach-sunxi/sunxi.c new file +60 -0
60 lines not on this page · raw message
arch/arm/mach-sunxi/sunxi.h new file +20 -0
@@ -0,0 +1,20 @@ +/* +* Generic definitions for Allwinner SunXi SoCs +* +* Copyright (C) 2012 Maxime Ripard +* +* Maxime Ripard <[email protected]> +* +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without any +* warranty of any kind, whether express or implied. +*/ + +#ifndef __MACH_SUNXI_H +#define __MACH_SUNXI_H + +#define SUNXI_REGS_PHYS_BASE 0x01c00000 +#define SUNXI_REGS_VIRT_BASE IOMEM(0xf1c00000) +#define SUNXI_REGS_SIZE (SZ_2M + SZ_1M) + +#endif /* __MACH_SUNXI_H */
Signature · 1 line
1.7.9.5
PATCH 3/6 ARM: sunxi: Add basic support for Allwinner A1x SoCs
Quoted 1 line · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>
Looks good. Thanks.
I'll add cubieboard support once this series has stabilized.
Thanks,
Stefan
PATCH 3/6 ARM: sunxi: Add basic support for Allwinner A1x SoCs
Le 16/11/2012 08:42, Stefan Roese a ?crit :
Quoted 8 lines · Maxime Ripard
Quoted 1 line
Signed-off-by Maxime Ripard <[email protected]>Looks good. Thanks.
Acked-by Stefan Roese <[email protected]>I'll add cubieboard support once this series has stabilized.
Great, thanks!
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 4/6 ARM: sunxi: Add earlyprintk support
In reply to Maxime Ripard--- arch/arm/Kconfig.debug | 8 ++++++++ arch/arm/include/debug/sunxi.S | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/arm/include/debug/sunxi.S
arch/arm/Kconfig.debug +8 -0
@@ -345,6 +345,13 @@ choice Say Y here if you want kernel low-level debugging support on SOCFPGA based platforms. + config DEBUG_SUNXI_UART + bool "Kernel low-level debugging messages via sunXi UART" + depends on ARCH_SUNXI + help + Say Y here if you want kernel low-level debugging support + on Allwinner A1X based platforms. + config DEBUG_VEXPRESS_UART0_DETECT bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" depends on ARCH_VEXPRESS && CPU_CP15_MMU
@@ -416,6 +423,7 @@ config DEBUG_LL_INCLUDE default "debug/mvebu.S" if DEBUG_MVEBU_UART default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART default "debug/socfpga.S" if DEBUG_SOCFPGA_UART + default "debug/sunxi.S" if DEBUG_SUNXI_UART default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 default "mach/debug-macro.S"
arch/arm/include/debug/sunxi.S new file +22 -0
@@ -0,0 +1,22 @@ +/* + * Early serial output macro for Allwinner A1X SoCs + * + * Copyright (C) 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#define SUNXI_UART1_PHYS_BASE 0x01c28400 +#define SUNXI_UART1_VIRT_BASE 0xf1c28400 + + .macro addruart, rp, rv, tmp + ldr \rp, =SUNXI_UART1_PHYS_BASE + ldr \rv, =SUNXI_UART1_VIRT_BASE + .endm + +#define UART_SHIFT 2 +#include <asm/hardware/debug-8250.S>
Signature · 1 line
1.7.9.5
PATCH 4/6 ARM: sunxi: Add earlyprintk support
Quoted 51 lines · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>--- arch/arm/Kconfig.debug | 8 ++++++++ arch/arm/include/debug/sunxi.S | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/arm/include/debug/sunxi.Sarch/arm/Kconfig.debug +7
-0@@ -345,6 +345,13 @@ choice Say Y here if you want kernel low-level debugging support on SOCFPGA based platforms. + config DEBUG_SUNXI_UART + bool "Kernel low-level debugging messages via sunXi UART" + depends on ARCH_SUNXI + help + Say Y here if you want kernel low-level debugging support + on Allwinner A1X based platforms. config DEBUG_VEXPRESS_UART0_DETECT bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" depends on ARCH_VEXPRESS && CPU_CP15_MMU@@ -416,6 +423,7 @@ config DEBUG_LL_INCLUDE default "debug/mvebu.S" if DEBUG_MVEBU_UART default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART default "debug/socfpga.S" if DEBUG_SOCFPGA_UART + default "debug/sunxi.S" if DEBUG_SUNXI_UART default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 default "mach/debug-macro.S"arch/arm/include/debug/sunxi.S new file +12
-0@@ -0,0 +1,22 @@ +/* + * Early serial output macro for Allwinner A1X SoCs + * + * Copyright (C) 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ +
arch/arm/include/debug/sunxi.S line 22
Quoted 10 lines
arch/arm/include/debug/sunxi.S new file +10
-0+#define SUNXI_UART1_PHYS_BASE 0x01c28400 +#define SUNXI_UART1_VIRT_BASE 0xf1c28400 + + .macro addruart, rp, rv, tmp + ldr \rp, =SUNXI_UART1_PHYS_BASE + ldr \rv, =SUNXI_UART1_VIRT_BASE + .endm + +#define UART_SHIFT 2 +#include <asm/hardware/debug-8250.S>
A10 (cubieboard) has debug the UART on UART0 instead of UART1 as on A13. So we need support this here as well. I suggest that I add support debug on UART0 with my cubieboard patches.
So:
Thanks,
Stefan
PATCH 4/6 ARM: sunxi: Add earlyprintk support
Le 16/11/2012 08:47, Stefan Roese a ?crit :
Quoted 58 lines · Maxime Ripard
Quoted 57 lines
Signed-off-by Maxime Ripard <[email protected]>--- arch/arm/Kconfig.debug | 8 ++++++++ arch/arm/include/debug/sunxi.S | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/arm/include/debug/sunxi.Sarch/arm/Kconfig.debug +7
-0@@ -345,6 +345,13 @@ choice Say Y here if you want kernel low-level debugging support on SOCFPGA based platforms. + config DEBUG_SUNXI_UART + bool "Kernel low-level debugging messages via sunXi UART" + depends on ARCH_SUNXI + help + Say Y here if you want kernel low-level debugging support + on Allwinner A1X based platforms. config DEBUG_VEXPRESS_UART0_DETECT bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" depends on ARCH_VEXPRESS && CPU_CP15_MMU@@ -416,6 +423,7 @@ config DEBUG_LL_INCLUDE default "debug/mvebu.S" if DEBUG_MVEBU_UART default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART default "debug/socfpga.S" if DEBUG_SOCFPGA_UART + default "debug/sunxi.S" if DEBUG_SUNXI_UART default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 default "mach/debug-macro.S"arch/arm/include/debug/sunxi.S new file +18
-0@@ -0,0 +1,22 @@ +/* + * Early serial output macro for Allwinner A1X SoCs + * + * Copyright (C) 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#define SUNXI_UART1_PHYS_BASE 0x01c28400 +#define SUNXI_UART1_VIRT_BASE 0xf1c28400 + + .macro addruart, rp, rv, tmp + ldr \rp, =SUNXI_UART1_PHYS_BASE + ldr \rv, =SUNXI_UART1_VIRT_BASE
Quoted 8 lines
arch/arm/include/debug/sunxi.S line 22
Quoted 4 lines
arch/arm/include/debug/sunxi.S new file +4
-0+ .endm + +#define UART_SHIFT 2 +#include <asm/hardware/debug-8250.S>A10 (cubieboard) has debug the UART on UART0 instead of UART1 as on A13. So we need support this here as well. I suggest that I add support debug on UART0 with my cubieboard patches.
Ok, we'll do it that way then. Thanks!
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 4/6 ARM: sunxi: Add earlyprintk support
In reply to Maxime RipardDear Maxime Ripard,
Quoted 12 lines · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>--- arch/arm/Kconfig.debug | 8 ++++++++ arch/arm/include/debug/sunxi.S | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/arm/include/debug/sunxi.Sarch/arm/Kconfig.debug +0
-0
arch/arm/Kconfig.debug choice · line 348
Quoted 4 lines
arch/arm/Kconfig.debug +1
-0@@ -345,6 +345,13 @@ choice Say Y here if you want kernel low-level debugging support on SOCFPGA based platforms. + config DEBUG_SUNXI_UART
Should be DEBUG_SUNXI_UART1
arch/arm/Kconfig.debug choice · line 349
Quoted 1 line
arch/arm/Kconfig.debug +1
-0+ bool "Kernel low-level debugging messages via sunXi UART"
UART1.
arch/arm/Kconfig.debug choice · line 353
Quoted 4 lines
arch/arm/Kconfig.debug +4
-0+ depends on ARCH_SUNXI + help + Say Y here if you want kernel low-level debugging support + on Allwinner A1X based platforms.
Say a few words about UART1 here.
arch/arm/Kconfig.debug config DEBUG_LL_INCLUDE · line 426
Quoted 9 lines
arch/arm/Kconfig.debug +2
-0+ config DEBUG_VEXPRESS_UART0_DETECT bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" depends on ARCH_VEXPRESS && CPU_CP15_MMU@@ -416,6 +423,7 @@ config DEBUG_LL_INCLUDE default "debug/mvebu.S" if DEBUG_MVEBU_UART default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART default "debug/socfpga.S" if DEBUG_SOCFPGA_UART + default "debug/sunxi.S" if DEBUG_SUNXI_UART
UART1
Quoted 13 lines
arch/arm/Kconfig.debug +0
-0default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 default "mach/debug-macro.S"arch/arm/include/debug/sunxi.S new file +4
-0@@ -0,0 +1,22 @@ +/* + * Early serial output macro for Allwinner A1X SoCs + * + * Copyright (C) 2012 Maxime Ripard
arch/arm/include/debug/sunxi.S line 14
Quoted 10 lines
arch/arm/include/debug/sunxi.S new file +10
-0+ * + * Maxime Ripard <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#define SUNXI_UART1_PHYS_BASE 0x01c28400 +#define SUNXI_UART1_VIRT_BASE 0xf1c28400
Maybe:
#ifdef CONFIG_DEBUG_SUNXI_UART1
#define SUNXI_UART_DEBUG_PHYS_BASE 0x01c28400
#define SUNXI_UART_DEBUG_VIRT_BASE 0xf1c28400
#endif
arch/arm/include/debug/sunxi.S line 18
Quoted 3 lines
arch/arm/include/debug/sunxi.S new file +3
-0+ .macro addruart, rp, rv, tmp + ldr \rp, =SUNXI_UART1_PHYS_BASE + ldr \rv, =SUNXI_UART1_VIRT_BASE
And use SUNXI_UART_DEBUG_{VIRT,PHYS}_BASE here.
So that people can come and add CONFIG_DEBUG_SUNXI_UART0 for the Cubieboard a bit more easily. Or you can even provision the code for the UART0 as well.
Best regards,
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 5/6 ARM: sunxi: Add device tree for the A13 and the Olinuxino board
In reply to Maxime Ripard--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/sun5i-olinuxino.dts | 30 +++++++++++++++++ arch/arm/boot/dts/sun5i.dtsi | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 arch/arm/boot/dts/sun5i-olinuxino.dts create mode 100644 arch/arm/boot/dts/sun5i.dtsi
arch/arm/boot/dts/Makefile +1 -0
@@ -84,6 +84,7 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ spear310-evb.dtb \ spear320-evb.dtb dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun5i-olinuxino.dtb dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \
arch/arm/boot/dts/sun5i-olinuxino.dts new file +30 -0
@@ -0,0 +1,30 @@ +/* + * Copyright 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "sun5i.dtsi" + +/ { + model = "Olimex A13-Olinuxino"; + compatible = "olimex,a13-olinuxino", "allwinner,sun5i"; + + memory { + reg = <0x40000000 0x40000000>; + }; + + soc { + duart: uart at 01c28400 { + status = "okay"; + }; + }; +};
arch/arm/boot/dts/sun5i.dtsi new file +58 -0
58 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH 5/6 ARM: sunxi: Add device tree for the A13 and the Olinuxino board
Quoted 40 lines · Maxime Ripard
Signed-off-by Maxime Ripard <[email protected]>--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/sun5i-olinuxino.dts | 30 +++++++++++++++++ arch/arm/boot/dts/sun5i.dtsi | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 arch/arm/boot/dts/sun5i-olinuxino.dts create mode 100644 arch/arm/boot/dts/sun5i.dtsiarch/arm/boot/dts/Makefile +1
-0@@ -84,6 +84,7 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ spear310-evb.dtb \ spear320-evb.dtb dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun5i-olinuxino.dtb dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \arch/arm/boot/dts/sun5i-olinuxino.dts new file +13
-0@@ -0,0 +1,30 @@ +/* + * Copyright 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +
arch/arm/boot/dts/sun5i-olinuxino.dts line 23
Quoted 10 lines
arch/arm/boot/dts/sun5i-olinuxino.dts new file +10
-0+/dts-v1/; +/include/ "sun5i.dtsi" + +/ { + model = "Olimex A13-Olinuxino"; + compatible = "olimex,a13-olinuxino", "allwinner,sun5i"; + + memory { + reg = <0x40000000 0x40000000>; + };
Sure that the board support 1GiB of RAM? AFAIK A13 only supports 512MiB. Please re-check.
Quoted 29 lines
arch/arm/boot/dts/sun5i-olinuxino.dts new file +6
-0+ soc { + duart: uart at 01c28400 { + status = "okay"; + }; + }; +};arch/arm/boot/dts/sun5i.dtsi new file +17
-0@@ -0,0 +1,58 @@ +/* + * Copyright 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/include/ "skeleton.dtsi" + +/ { + interrupt-parent = <&intc>;
arch/arm/boot/dts/sun5i.dtsi line 27
Quoted 10 lines
arch/arm/boot/dts/sun5i.dtsi new file +10
-0+ + cpus { + cpu at 0 { + compatible = "arm,cortex-a8"; + }; + }; + + chosen { + bootargs = "earlyprintk console=ttyS0,115200"; + };
No memory node here? My experience is, that the soc.dtsi file should contain a memory node with the max possible memory size of the SoC. Which will be overwritten by the board dts file containing the max memory size of the board.
Quoted 20 lines
arch/arm/boot/dts/sun5i.dtsi new file +20
-0+ soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x01c20000 0x300000>; + ranges; + + timer at 01c20c00 { + compatible = "allwinner,sunxi-timer"; + reg = <0x01c20c00 0x400>; + interrupts = <22>; + }; + + intc: interrupt-controller at 01c20400 { + compatible = "allwinner,sunxi-ic"; + reg = <0x01c20400 0x400>; + interrupt-controller; + #interrupt-cells = <1>; + }; +
arch/arm/boot/dts/sun5i.dtsi line 58
Quoted 10 lines
arch/arm/boot/dts/sun5i.dtsi new file +10
-0+ uart1: uart at 01c28400 { + compatible = "ns8250"; + reg = <0x01c28400 0x400>; + interrupts = <2>; + reg-shift = <2>; + clock-frequency = <24000000>; + status = "disabled"; + }; + }; +};
Looks good so far. I suggest that with the A10/cubieboard support we move to the following dts/dtsi organization:
sunxi.dtsi - Devices common to all Allwinner sunXi SoC's sun4i.dtsi - sun4i Devices, will include sunxi.dtsi sun5i.dtsi - sun5i Devices, will include sunxi.dtsi board.dts - will include either sun4i.dtsi or sun5i.dtsi
If we agree on this, then I'll send a patch with this re-organization with the cubieboard patches.
Thanks,
Stefan
PATCH 5/6 ARM: sunxi: Add device tree for the A13 and the Olinuxino board
Le 16/11/2012 08:57, Stefan Roese a ?crit :
Quoted 46 lines · Maxime Ripard
Quoted 45 lines
Signed-off-by Maxime Ripard <[email protected]>--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/sun5i-olinuxino.dts | 30 +++++++++++++++++ arch/arm/boot/dts/sun5i.dtsi | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 arch/arm/boot/dts/sun5i-olinuxino.dts create mode 100644 arch/arm/boot/dts/sun5i.dtsiarch/arm/boot/dts/Makefile +1
-0@@ -84,6 +84,7 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ spear310-evb.dtb \ spear320-evb.dtb dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun5i-olinuxino.dtb dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \arch/arm/boot/dts/sun5i-olinuxino.dts new file +18
-0@@ -0,0 +1,30 @@ +/* + * Copyright 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "sun5i.dtsi" + +/ { + model = "Olimex A13-Olinuxino";
Quoted 8 lines
arch/arm/boot/dts/sun5i-olinuxino.dts line 23
Quoted 5 lines
arch/arm/boot/dts/sun5i-olinuxino.dts new file +5
-0+ compatible = "olimex,a13-olinuxino", "allwinner,sun5i"; + + memory { + reg = <0x40000000 0x40000000>; + };Sure that the board support 1GiB of RAM? AFAIK A13 only supports 512MiB. Please re-check.
Ah, you're right. Good catch.
Quoted 36 lines
Quoted 36 lines
arch/arm/boot/dts/sun5i-olinuxino.dts new file +6
-0+ soc { + duart: uart at 01c28400 { + status = "okay"; + }; + }; +};arch/arm/boot/dts/sun5i.dtsi new file +24
-0@@ -0,0 +1,58 @@ +/* + * Copyright 2012 Maxime Ripard + * + * Maxime Ripard <[email protected]> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/include/ "skeleton.dtsi" + +/ { + interrupt-parent = <&intc>; + + cpus { + cpu at 0 { + compatible = "arm,cortex-a8"; + }; + }; +
Quoted 8 lines
arch/arm/boot/dts/sun5i.dtsi line 27
Quoted 3 lines
arch/arm/boot/dts/sun5i.dtsi new file +3
-0+ chosen { + bootargs = "earlyprintk console=ttyS0,115200"; + };No memory node here? My experience is, that the
soc.dtsifile should contain a memory node with the max possible memory size of the SoC. Which will be overwritten by the board dts file containing the max memory size of the board.
I've worked on boards that were not doing that, so I have a different experience here, but that looks reasonable.
Quoted 35 lines
Quoted 21 lines
arch/arm/boot/dts/sun5i.dtsi new file +20
-0+ soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x01c20000 0x300000>; + ranges; + + timer at 01c20c00 { + compatible = "allwinner,sunxi-timer"; + reg = <0x01c20c00 0x400>; + interrupts = <22>; + }; + + intc: interrupt-controller at 01c20400 { + compatible = "allwinner,sunxi-ic"; + reg = <0x01c20400 0x400>; + interrupt-controller; + #interrupt-cells = <1>; + }; +arch/arm/boot/dts/sun5i.dtsi line 58
Quoted 10 lines
arch/arm/boot/dts/sun5i.dtsi new file +10
-0+ uart1: uart at 01c28400 { + compatible = "ns8250"; + reg = <0x01c28400 0x400>; + interrupts = <2>; + reg-shift = <2>; + clock-frequency = <24000000>; + status = "disabled"; + }; + }; +};Looks good so far. I suggest that with the A10/cubieboard support we move to the following dts/dtsi organization:
Quoted 7 lines
sunxi.dtsi- Devices common to all Allwinner sunXi SoC'ssun4i.dtsi- sun4i Devices, will includesunxi.dtsisun5i.dtsi- sun5i Devices, will includesunxi.dtsiboard.dts- will include eithersun4i.dtsiorsun5i.dtsiIf we agree on this, then I'll send a patch with this re-organization with the cubieboard patches.
Yes, that would make sense.
Thanks!
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 6/6 ARM: sunxi: Add entry to MAINTAINERS
In reply to Maxime Ripard--- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+)
MAINTAINERS +6 -0
@@ -685,6 +685,12 @@ M: Lennert Buytenhek <[email protected]> L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers) S: Maintained +ARM/Allwinner A1X SoC support +M: Maxime Ripard <[email protected]> +L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-sunxi/ + ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES M: Andrew Victor <[email protected]> M: Nicolas Ferre <[email protected]>
Signature · 1 line
1.7.9.5
cover Add basic support for Allwinner A1X SoCs
In reply to Maxime RipardHi Maxime,
Quoted 7 lines · Maxime Ripard
You'll find in this patchset the initial support for Allwinner A10 and A13 SoCs from Allwinner. Since the internal name of these SoCs are sun4i and sun5i, the mach- directory is named sunxi.
You can find these SoCs in the Cubieboard, the A13-olinuxino or the Melee A1000.
Quoted 6 lines
Both SoCs should work fine, as the A13 is a trimmed down version of the A10, but it has only been tested on a A13-OlinuXino from Olimex.
Support is quite minimal for now, since it only includes timer and IRQ controller drivers, so we can only boot to userspace through initramfs. Support for the other peripherals on these SoCs will come eventually.
Great, thanks!
I've been working on upstreaming sunxi support as well in the last days. You were a bit faster. :) Here is my latest port, for review on the linux-sunxi list:
https://groups.google.com/forum/#!topic/linux-sunxi/H4ct05OmYtQ
(sorry about this google list)
I'll review your patches soon and send some comments.
Thanks,
Stefan
Arnd Bergmann
maintainercover Add basic support for Allwinner A1X SoCs
In reply to Maxime RipardQuoted 7 lines · Maxime Ripard
You'll find in this patchset the initial support for Allwinner A10 and A13 SoCs from Allwinner. Since the internal name of these SoCs are sun4i and sun5i, the mach- directory is named sunxi.
You can find these SoCs in the Cubieboard, the A13-olinuxino or the Melee A1000.
Quoted 6 lines
Both SoCs should work fine, as the A13 is a trimmed down version of the A10, but it has only been tested on a A13-OlinuXino from Olimex.
Support is quite minimal for now, since it only includes timer and IRQ controller drivers, so we can only boot to userspace through initramfs. Support for the other peripherals on these SoCs will come eventually.
Hi Maxime,
Thanks for sending these, I'm pretty excited we actually get this far for 3.8. All patches look good for inclusion from my side, but I'll let Stefan and others comment first and then take your second version. We are getting closer to the merge window already, so I'd like to pull it in rather soon and maybe add some fixups later.
I've also ordered a Cubieboard myself now, so hopefully I'll also find some time to play with this.
Arnd
cover Add basic support for Allwinner A1X SoCs
Hi Arnd,
Quoted 15 lines · Arnd Bergmann
Quoted 7 lines · Maxime Ripard
You'll find in this patchset the initial support for Allwinner A10 and A13 SoCs from Allwinner. Since the internal name of these SoCs are sun4i and sun5i, the mach- directory is named sunxi.
You can find these SoCs in the Cubieboard, the A13-olinuxino or the Melee A1000.
Quoted 6 lines
Both SoCs should work fine, as the A13 is a trimmed down version of the A10, but it has only been tested on a A13-OlinuXino from Olimex.
Support is quite minimal for now, since it only includes timer and IRQ controller drivers, so we can only boot to userspace through initramfs. Support for the other peripherals on these SoCs will come eventually.
Quoted 7 lines
Hi Maxime,
Thanks for sending these, I'm pretty excited we actually get this far for 3.8. All patches look good for inclusion from my side, but I'll let Stefan and others comment first and then take your second version. We are getting closer to the merge window already, so I'd like to pull it in rather soon and maybe add some fixups later.
Yes, that would be great. I can send some patches to add A10/cubieboard support in a few days.
Quoted 2 lines
I've also ordered a Cubieboard myself now, so hopefully I'll also find some time to play with this.
Nice.
Thanks,
Stefan
cover Add basic support for Allwinner A1X SoCs
In reply to Arnd BergmannHi Arnd,
Le 16/11/2012 08:51, Arnd Bergmann a ?crit :
Quoted 15 lines · Maxime Ripard
Quoted 7 lines
You'll find in this patchset the initial support for Allwinner A10 and A13 SoCs from Allwinner. Since the internal name of these SoCs are sun4i and sun5i, the mach- directory is named sunxi.
You can find these SoCs in the Cubieboard, the A13-olinuxino or the Melee A1000.
Quoted 6 lines
Both SoCs should work fine, as the A13 is a trimmed down version of the A10, but it has only been tested on a A13-OlinuXino from Olimex.
Support is quite minimal for now, since it only includes timer and IRQ controller drivers, so we can only boot to userspace through initramfs. Support for the other peripherals on these SoCs will come eventually.
Quoted 7 lines
Hi Maxime,
Thanks for sending these, I'm pretty excited we actually get this far for 3.8. All patches look good for inclusion from my side, but I'll let Stefan and others comment first and then take your second version. We are getting closer to the merge window already, so I'd like to pull it in rather soon and maybe add some fixups later.
That's great. I'll do my best to send a v2 asap.
Quoted 2 lines
I've also ordered a Cubieboard myself now, so hopefully I'll also find some time to play with this.
Nice :)
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
cover Add basic support for Allwinner A1X SoCs
In reply to Maxime RipardDear Maxime Ripard,
Quoted 7 lines · Maxime Ripard
You'll find in this patchset the initial support for Allwinner A10 and A13 SoCs from Allwinner. Since the internal name of these SoCs are sun4i and sun5i, the mach- directory is named sunxi.
You can find these SoCs in the Cubieboard, the A13-olinuxino or the Melee A1000.
Quoted 6 lines
Both SoCs should work fine, as the A13 is a trimmed down version of the A10, but it has only been tested on a A13-OlinuXino from Olimex.
Support is quite minimal for now, since it only includes timer and IRQ controller drivers, so we can only boot to userspace through initramfs. Support for the other peripherals on these SoCs will come eventually.
Would you mind adding a file Documentation/arm/sunxi/README (or another name) that lists the SoCs that are supported and the public datasheets that are available for those SoCs?
I think it's always great to ease the process of finding the SoC datasheets.
Thanks!
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com