04-01-2016 09:34 AM
I have a problem using my Zynq (on a Zybo board) as an USB peripheral with the Zynq running Linux.
The problem is that the USB phy chip is detected 'randomly'. On some boots it is detected, on others it is not.
Sometimes a soft reboot helps to have the chip detected on the next boot, sometimes a power cycling is required for the chip to be found (I think I waited 30 minutes of automated reboots once, without seeing a successful boot).
If the USB phy is detected, there seems not to be any problems with the USB communication.
The problem seems to be the same as here:
but the solution pointed to there does not fix my issue (https://forums.xilinx.com/t5/Embedded-Linux/Petalinux-2015-2-1-usb-not-working/td-p/654349). Perhaps this is because in that thread, the USB was used in host mode, whereas I need peripheral.
As suggetsed there, setting the 'usb_phy' in the kernel device tree to
compatible = 'usb-nop-xceive';
does not fix the issue, only hides it.
When using the ulpi-phy driver, at least the kernel deteceted that no ULPI chip was found, and gave an error.
With the usb-nop-xceive, my USB gadget module gets inserted fine, but on half of the boots, nothing happens.
The host side does not detect any USB devices, the Zynq does not get any USB requests.
I tried to add a
reset-gpios = <&gpio0 46 1>;
to map the ULPI reset to the kernel (as per Zybo documentation), but it seems this went unused?
Removing that line from the devicetree, and examining GPIO 46 via /sys/class/gpio/ says the GPIO is '1', i.e. reset released both when the device has booted to a working USB setup and when the USB setup has failed.
It could be, ofcourse that something sets this reset pin later, after bootup, and the PHY is in reset when the Chipidea USB tries to configure it. But I am not sure where, when or how to check this.
I have tried both with Xilinx's linux tree and with the one Digilent provides for Zybo. Same effect with both. I'd much prefer to work with Xilinx's tree (or even upstream), than Digilent's, as Xilinx's is more up-to-date.
The Chipidea IP is set to 'peripheral' mode.
dr_mode = "peripheral";
OTG is not required, nor does setting it seem to help the issue.
Any ideas on how to fix this, or even where to look for the problem would be greatly appreciated.
04-12-2016 10:18 AM
This doesn't seem to be a Linux issue after all (oops, wrong forum?).
I was able to isolate the same random behaviour to be visible already in u-boot's 'usb start' command.
Zynq> usb start starting USB... USB0: ULPI request timed out zynq ULPI viewport init failed lowlevel init failed USB1: usb1 wrong num MIO: 0, Index 1 lowlevel init failed USB error: all controllers failed lowlevel init
And on the occasional boot it works:
Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 1 USB Device(s) found USB1: usb1 wrong num MIO: 0, Index 1 lowlevel init failed scanning usb for storage devices... 0 Storage Device(s) found
Now, if when detection has failed, I manually reset the USB PHY by touching a grounded wire to the PHY chip's RESETN pin (while u-boot waits in its prompt), at the next 'usb start' command the PHY chip is found.
Unfortunately, when booting Linux from here on, my own USB kernel module makes the Zynq freeze when inserted.
If the USB PHY is found without the manual reset described above, then my module works just fine.
I'm a bit less baffled now, but any thoughts on what is going on would be appreciated.
04-21-2016 10:50 AM
04-21-2016 11:41 PM
After much learning I managed to get the USB available. These are the main points:
So, finally I got it working by routing the USB reset pin to MIO46 in Vivado, and compiling a new u-boot, using Vivado's generated ps7_init_gpl.c. I edited this file, as it was generated with the reset pin with reverse polarity, but I guess this is just a tick-box in Vivado that I missed.
I don't have an explanation on why resetting the USB-PHY later (from u-boot cmd line or linux) would not fix the issue. Perhaps it messed up the Chipidea/Synopsys USB controller IP?