05-23-2012 02:27 AM
I'm working with a ZC702 board. Currently, I'm trying to bring up UART0, which is by default unused.
These are the steps I've taken so far:
- Recompiled the FSBL to include the proper MIO configuration
- Recreated boot.bin
- Recompiled the device tree after adding the following section right after the existing block that describes UART1:
compatible = "xlnx,ps7-uart-1.00.a";
reg = <0xe0000000 0x1000>;
interrupts = <0x3B 0x0>;
clock = <50000000>;
This is simply a copy of the existing UART block, with modified MMIO and IRQ addresses.
When Linux starts up, I get the following output:
e0001000.uart: ttyPS0 at MMIO 0xe0001000 (irq = 82) is a xuartps
console [ttyPS0] enabled
e0000000.uart: ttyPS1 at MMIO 0xe0000000 (irq = 59) is a xuartps
Looking in /dev, I see that ttyPS0 and ttyPS1 get created. However, writing to ttyPS1 generates no response,
and reading from it (cat /dev/ttyPS1) freezes the system.
It also seems that the IRQ isn't properly set up and registered with the driver:
> cat /proc/interrupts
40: 0 0 GIC xdevcfg
43: 15 0 GIC xttcpss clockevent
45: 0 0 GIC pl330
46: 0 0 GIC pl330
47: 0 0 GIC pl330
48: 0 0 GIC pl330
49: 0 0 GIC pl330
51: 2 0 GIC e000d000.spi
53: 0 0 GIC ehci_hcd:usb1
54: 1762 0 GIC eth0
56: 38 0 GIC mmc0
57: 0 0 GIC xi2cps
72: 0 0 GIC pl330
73: 0 0 GIC pl330
74: 0 0 GIC pl330
75: 0 0 GIC pl330
82: 35 0 GIC xuartps
IPI0: 0 0 Timer broadcast interrupts
IPI1: 554 763 Rescheduling interrupts
IPI2: 0 0 Function call interrupts
IPI3: 3 80 Single function call interrupts
IPI4: 0 0 CPU stop interrupts
LOC: 42501 44145 Local timer interrupts
As you can see, IRQ 59 doesn't show up.
I've tried to check whether the IRQ assignment is maybe hard-coded somewhere in the kernel, but it doesn't seem so.
Can anybody give me a pointer on what's going wrong here?
05-23-2012 10:45 AM
You can't use that UART on the 702 as the MIO pins are being used for other stuff. It's also not pinned out because of this. I'm confused why you think you can use it, but maybe I'm misunderstanding something.
Now, as long as you don't actually use it, I would think it will show up in the interrupts, but that's a bit of an odd case. There could be something there we've not seen.
We have tested that UART on an internal board, but we don't any Zynq board with both UARTs. We have tested both UARTs on the emulation platform.
05-24-2012 12:20 AM
you're absolutely right, normally, that UART isn't accessible on the ZC702. However, since I really need it, I re-purposed MIO 14 and 15 for UART0 (normally those pins are configured as GPIO) and soldered additional wires to them in order to get access.
It really puzzles me why the kernel properly recognizes the device tree entries, but then fails to set up the IRQ. When doing tests on your internal board, did you actually run both UARTs in parallel?
05-24-2012 08:08 AM
It sounds like you then reconfigure those pins (14/15) to be UART rather than GPIO, is that true?
I can try to put in both UARTs in the device tree and test on a zynq board to see if I can replicate what you see as long as I don't actually use the 2nd UART.
05-24-2012 08:36 AM
correct, MIO pins 14 and 15 are configured as UART0 via the FSBL. This should pose no problem, as they are by default not connected to anything important on the board (e.g., pin 15 is normally used to read the write protect signal of the SD card slot).
Since I presume that the problem is on the software side, it would already be a great help if you could check whether the kernel on your board sets up the IRQ for UART0 if it is included in the device tree.
05-24-2012 08:41 AM
The driver shows that the irq is not actually acquired til the port is started up which is not at probe time but when used. I then went digging and found that the clock for uart 0 was not on in the clock control register of the SLCR (0xf8000154). When I turned it on, then cated a file to the /dev/ttyPS1 I see interrrupts in proc/interrupts. It doesn't show the uart driver name beside the 59, but they appear to be working.
I did this using devmem from the Linux shell. The SLCR is unlocked right now by default in Linux (may not stay that way) so you can just writ that register to enable the uart0 clock. Mine on my board was a value of 0x1402 and I changed it to 0x1403.
See if that makes sense.
05-25-2012 06:28 AM
thanks for trying to reproduce the issue.
This is what I found: The clock for UART0 seems to be enabled, at least UART_CLK_CTRL does by default contain the value 0x1403. /dev/ttyPS1 is created on my system automatically, since I included UART0 in the device tree.
After writing to that device, IRQ 59 does indeed show up in /proc/interrupts (this might have already worked before, it just didn't come to my mind that you have to use the device first, sorry):
57: 0 0 GIC xi2cps
59: 162014 0 GIC
72: 0 0 GIC pl330
Like in your case, the driver name is missing. Two things are strange: I still get no output (can see nothing on my oscilloscope). Also, the number of interrupts generated is absurdly high (over 160,000 just from writing a single char to the device). Writing more data also takes quite long. My assumption would be that the interrupt handler fires continuously as long as it is registered. This would also explain why my system immediately freezes as soon as I run cat /dev/ttyPS1. Warnings like the following get printed in that case: INFO: rcu_preempt_state detected stall on CPU 0 (t=6000 jiffies)
I checked the GIC configuration, but can't find anything unusual. Maybe you could check whether your system displays the same behavior when reading from /dev/ttyPS1.
05-31-2012 01:12 AM
Okay, I think I've solved the problem. Seems that everything works fine if the RX pin is held on high level. Anyway, a big thanks to those who gave me their support!