07-21-2014 07:57 AM
Hello everyone,
I've spent a week trying to get this to work and I'm out of ideas. I'm working on a project that requires 5 UART controller. I've enabled UART0 in PS and it's working. Now I have instantiated 3 AXI UART (16550 style) xilinx cores and connected them in XPS on the axi4lite bus. These are the generated addresses:
I then connected the interrupts to the GIC:
The three pairs of RX & TX pins are connected to a PMOD.
I have attached the full dts file, in case I missed some other configs for the interrupt controller, but here are the relevant entries:
serial@e0000000 { clock-names = "ref_clk", "aper_clk"; clocks = <0x3 0x17 0x3 0x28>; compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps"; current-speed = <0x1c200>; interrupt-parent = <0x2>; interrupts = <0x0 0x1B 0x4>; reg = <0xe0000000 0x1000>; xlnx,has-modem = <0x0>; }; serial@e0001000 { clock-names = "ref_clk", "aper_clk"; clocks = <0x3 0x18 0x3 0x29>; compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps"; current-speed = <0x1c200>; interrupt-parent = <0x2>; interrupts = <0x0 0x32 0x4>; reg = <0xe0001000 0x1000>; xlnx,has-modem = <0x0>; }; axi_uart0: serial@42A00000 { current-speed = <115200>; clock-frequency = <100000000>; compatible="ns16550a"; interrupt-parent = <0x2>; interrupts = < 0x0 0x39 0x4>; reg = < 0x42A00000 0x10000 >; reg-offset = <0x1000>; reg-shift = <2>; xlnx,family = "zynq"; xlnx,has-external-rclk = <0x0>; xlnx,has-external-xin = <0x0>; xlnx,is-a-16550 = <0x1>; xlnx,s-axi-aclk-freq-hz = <0x5F5E100>; xlnx,use-modem-ports = <0x0>; xlnx,use-user-ports = <0x0>; xlnx,instance = "axi_uart16550_0"; }; axi_uart1: serial@42A20000 { current-speed = <115200>; clock-frequency = <100000000>; compatible = "ns16550a"; interrupt-parent = <0x2>; interrupts = < 0x0 0x38 0x4>; reg = < 0x42A20000 0x10000 >; reg-offset = <0x1000>; reg-shift = <2>; xlnx,family = "zynq"; xlnx,has-external-rclk = <0x0>; xlnx,has-external-xin = <0x0>; xlnx,is-a-16550 = <0x1>; xlnx,s-axi-aclk-freq-hz = <0x5F5E100>; xlnx,use-modem-ports = <0x0>; xlnx,use-user-ports = <0x0>; xlnx,instance = "axi_uart16550_1"; }; axi_uart2: serial@42A40000 { current-speed = <115200>; clock-frequency = <100000000>; compatible = "ns16550a"; interrupt-parent = <0x2>; interrupts = < 0x0 0x37 0x4>; reg = < 0x42A40000 0x10000 >; reg-offset = <0x1000>; reg-shift = <2>; xlnx,family = "zynq"; xlnx,has-external-rclk = <0x0>; xlnx,has-external-xin = <0x0>; xlnx,is-a-16550 = <0x1>; xlnx,s-axi-aclk-freq-hz = <0x5F5E100>; xlnx,use-modem-ports = <0x0>; xlnx,use-user-ports = <0x0>; xlnx,instance = "axi_uart16550_2"; };
Now the fun part: From the 3 cores, the second one is working fine! The other two appear in the boot sequence and in the /dev/ directory, but no interrupts are being generated and no traffic gets through.
I'm working with a zedboard and running:
Linux localhost.localdomain 3.12.0-xillinux-1.3-xilinx-dirty #11 SMP PREEMPT Mon Jul 21 17:14:34 EEST 2014 armv7l armv7l armv7l GNU/Linux
Any help is greatly appreciated!
07-23-2014 02:03 AM
Ok, so the problem was that the interrupt wasn't matched with the correct core instance: axi_uart_16550_0 has base address 0x42A40000 and interrupt 89 and axi_uart_16550_2 has address 0x42A00000 and interrupt 87. So the mistake was in the device tree source where it should be like this:
axi_uart0: serial@42A40000 {
current-speed = <115200>;
clock-frequency = <100000000>;
compatible="ns16550a";
interrupt-parent = <0x2>;
interrupts = < 0x0 0x39 0x4>;
reg = < 0x42A40000 0x10000 >;
reg-offset = <0x1000>;
reg-shift = <2>;
xlnx,family = "zynq";
xlnx,has-external-rclk = <0x0>;
xlnx,has-external-xin = <0x0>;
xlnx,is-a-16550 = <0x1>;
xlnx,s-axi-aclk-freq-hz = <0x5F5E100>;
xlnx,use-modem-ports = <0x0>;
xlnx,use-user-ports = <0x0>;
xlnx,instance = "axi_uart16550_0";
};
axi_uart1: serial@42A20000 {
current-speed = <115200>;
clock-frequency = <100000000>;
compatible = "ns16550a";
interrupt-parent = <0x2>;
interrupts = < 0x0 0x38 0x4>;
reg = < 0x42A20000 0x10000 >;
reg-offset = <0x1000>;
reg-shift = <2>;
xlnx,family = "zynq";
xlnx,has-external-rclk = <0x0>;
xlnx,has-external-xin = <0x0>;
xlnx,is-a-16550 = <0x1>;
xlnx,s-axi-aclk-freq-hz = <0x5F5E100>;
xlnx,use-modem-ports = <0x0>;
xlnx,use-user-ports = <0x0>;
xlnx,instance = "axi_uart16550_1";
};
axi_uart2: serial@42A00000 {
current-speed = <115200>;
clock-frequency = <100000000>;
compatible = "ns16550a";
interrupt-parent = <0x2>;
interrupts = < 0x0 0x37 0x4>;
reg = < 0x42A00000 0x10000 >;
reg-offset = <0x1000>;
reg-shift = <2>;
xlnx,family = "zynq";
xlnx,has-external-rclk = <0x0>;
xlnx,has-external-xin = <0x0>;
xlnx,is-a-16550 = <0x1>;
xlnx,s-axi-aclk-freq-hz = <0x5F5E100>;
xlnx,use-modem-ports = <0x0>;
xlnx,use-user-ports = <0x0>;
xlnx,instance = "axi_uart16550_2";
};
07-21-2014 08:05 AM
So this is what happens at boot:
root@localhost:~# dmesg |grep serial [ 0.547895] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 59, base_baud = 3124999) is a xuartps [ 0.555287] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 82, base_baud = 3124999) is a xuartps [ 12.178423] 42a00000.serial: ttyS2 at MMIO 0x42a01000 (irq = 89, base_baud = 6250000) is a 16550A [ 12.201021] 42a20000.serial: ttyS3 at MMIO 0x42a21000 (irq = 88, base_baud = 6250000) is a 16550A [ 12.240373] 42a40000.serial: ttyS4 at MMIO 0x42a41000 (irq = 87, base_baud = 6250000) is a 16550A
Notice that the three PL cores are ttyS2, ttyS3 and ttyS4, probably because ttyS0 and ttyS1 have failed to map properly for the first two devices (the PS ones). They appear /dev but they aren't working at all. It is annoying to have two bogus devices in /dev, but I can like with it. The problem is with ttyS2 and ttyS4 (ttyS3 is working fine).
07-23-2014 02:03 AM
Ok, so the problem was that the interrupt wasn't matched with the correct core instance: axi_uart_16550_0 has base address 0x42A40000 and interrupt 89 and axi_uart_16550_2 has address 0x42A00000 and interrupt 87. So the mistake was in the device tree source where it should be like this:
axi_uart0: serial@42A40000 {
current-speed = <115200>;
clock-frequency = <100000000>;
compatible="ns16550a";
interrupt-parent = <0x2>;
interrupts = < 0x0 0x39 0x4>;
reg = < 0x42A40000 0x10000 >;
reg-offset = <0x1000>;
reg-shift = <2>;
xlnx,family = "zynq";
xlnx,has-external-rclk = <0x0>;
xlnx,has-external-xin = <0x0>;
xlnx,is-a-16550 = <0x1>;
xlnx,s-axi-aclk-freq-hz = <0x5F5E100>;
xlnx,use-modem-ports = <0x0>;
xlnx,use-user-ports = <0x0>;
xlnx,instance = "axi_uart16550_0";
};
axi_uart1: serial@42A20000 {
current-speed = <115200>;
clock-frequency = <100000000>;
compatible = "ns16550a";
interrupt-parent = <0x2>;
interrupts = < 0x0 0x38 0x4>;
reg = < 0x42A20000 0x10000 >;
reg-offset = <0x1000>;
reg-shift = <2>;
xlnx,family = "zynq";
xlnx,has-external-rclk = <0x0>;
xlnx,has-external-xin = <0x0>;
xlnx,is-a-16550 = <0x1>;
xlnx,s-axi-aclk-freq-hz = <0x5F5E100>;
xlnx,use-modem-ports = <0x0>;
xlnx,use-user-ports = <0x0>;
xlnx,instance = "axi_uart16550_1";
};
axi_uart2: serial@42A00000 {
current-speed = <115200>;
clock-frequency = <100000000>;
compatible = "ns16550a";
interrupt-parent = <0x2>;
interrupts = < 0x0 0x37 0x4>;
reg = < 0x42A00000 0x10000 >;
reg-offset = <0x1000>;
reg-shift = <2>;
xlnx,family = "zynq";
xlnx,has-external-rclk = <0x0>;
xlnx,has-external-xin = <0x0>;
xlnx,is-a-16550 = <0x1>;
xlnx,s-axi-aclk-freq-hz = <0x5F5E100>;
xlnx,use-modem-ports = <0x0>;
xlnx,use-user-ports = <0x0>;
xlnx,instance = "axi_uart16550_2";
};
05-31-2016 10:49 AM