UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Scholar norman_wong
Scholar
10,916 Views
Registered: ‎05-28-2012

Zynq Linux USB Driver Customization

My custom board needs to reset the USB PHY via GPIO and set the DRVVBUS_EXT bit in the USB PHY. I have done that by hacking in GPIO and ULPI code into ehci-xilinx-usbps.c. Not very elegant nor modular.

 

Is there a better way that would the design intent and structure of the driver?

 

I noticed that xusbps_usb2_platform_data has init and exit vectors. I haven't found any way to pass values for those vectors down to the driver. Those vectors do not appear to be used anywhere. How should they be used? Can I use them to handle the USB PHY reset GPIO?

0 Kudos
27 Replies
Xilinx Employee
Xilinx Employee
10,907 Views
Registered: ‎09-10-2008

Re: Zynq Linux USB Driver Customization

Hi Norman,

 

I'm not a USB expert for sure and it's a bit complicated, but here's some thoughts.

 

Ideally we need that to be specified in the device tree, which GPIO to be used for resetting the USB phy as that's a problem for every unique board design.

 

I see what you mean about the init and exit vectors.  I'll do some more digging on that.

 

You may need your own board specific file in arch/arm/mach-zynq to handle board unique stuff and for now you do hack in the reset of the USB phy there probably.  I was going to do that for ours and have not got around to it as we're using u-boot to reset the phy, but need to do this also.

 

Thanks.

0 Kudos
Scholar norman_wong
Scholar
10,899 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

Thanks for the reply. No expert on USB either. I am not sure if reseting the USB PHY once in the board file on boot is ideal. I am guessing that the USB PHY reset should be under control of the driver and reset appropriately anytime after boot.

 

Putting all USB initializaiton in the board.c file would not quite work for me. I need to set the DRVVBUS_EXT bit for VBUS to be turned on in host mode. For that I need the access to the controllers ULPI viewport. And it must be done after the USB controller is brought up but before it is enabled. And only in HOST only mode. Note the USB PHYs from Texas Instruments seem to require both DRVVBUS and DRVVBUS_EXT set for VBUS to be turned on. Ideally, the Zynq USB controller should have a "TI" mode that would handle both bits.

 

I tried registering platform data with init and exit vectors initialized to my functions. I did this from the board.c file. The result is that I get two instances of the USB driver. My instance that fails to boot because it does not have all the device tree parameters. The second instance is from the device tree definition. It fails because the first instance has taken some resources it needs. I don't think it is possible to use device trees to initialize function pointers. Scalar values only?

 

0 Kudos
Participant ierkiaga
Participant
10,267 Views
Registered: ‎11-13-2012

Re: Zynq Linux USB Driver Customization

Hi,

 

I have a similar problem in my project. My USB phy's reset is controlled by a GPIO and I controll it thought xusbps-dr-of driver, as you can see in this part of code:

 

ut_clk_put;
219   }
220 
221   /**********************************************************/
222   // Enable USB Phy
223   dev_info(&ofdev->dev, "Enable USB Phy\n");
224   gpio_request(59, "usb_reset_n");
225   gpio_direction_output(59, 1);
226   gpio_export(59, false);
227   /**********************************************************/
228 
229   /* If ULPI phy type, set it up */
230   if (pdata->phy_mode == XUSBPS_USB2_PHY_ULPI) {
231     pdata->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops,
232       ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
233     if (pdata->ulpi) {
234       pdata->ulpi->io_priv = pdata->regs +
235               XUSBPS_SOC_USB_ULPIVP;

 

Looking for the boot console, it seems that USB phy device is attached properly but USB devices are not detected.

ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci_hcd: block sizes: qh 60 qtd 96 itd 160 sitd 96
ehci-pci: EHCI PCI platform driver
xusbps-dr e0002000.ps7-usb: Enable USB Phy
ULPI transceiver vendor/product ID 0x0424/0x0007
Found SMSC USB3320 ULPI transceiver.
ULPI integrity check: passed.
initializing XUSBPS-SOC USB Controller
xusbps-ehci xusbps-ehci.0: Xilinx PS USB EHCI Host Controller
xusbps-ehci xusbps-ehci.0: new USB bus registered, assigned bus number 1
xusbps-ehci xusbps-ehci.0: reset hcs_params 0x10011 dbg=0 ind cc=0 pcc=0 ordered ports=1
xusbps-ehci xusbps-ehci.0: reset hcc_params 0006 thresh 0 uframes 256/512/1024 park
xusbps-ehci xusbps-ehci.0: park 0
xusbps-ehci xusbps-ehci.0: reset command 0080002 (park)=0 ithresh=8 period=1024 Reset HALT
xusbps-ehci xusbps-ehci.0: ...powerdown ports...
xusbps-ehci xusbps-ehci.0: irq 53, io mem 0x00000000
xusbps-ehci xusbps-ehci.0: init command 0010005 (park)=0 ithresh=1 period=512 RUN
xusbps-ehci xusbps-ehci.0: USB 2.0 started, EHCI 1.00
usb usb1: default language 0x0409
usb usb1: udev 1, busnum 1, minor = 0
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: Xilinx PS USB EHCI Host Controller
usb usb1: Manufacturer: Linux 3.9.0-xilinx-dirty ehci_hcd
usb usb1: SerialNumber: xusbps-ehci.0
usb usb1: usb_probe_device
usb usb1: configuration #1 chosen from 1 choice
usb usb1: adding 1-0:1.0 (config #1, interface 0)
hub 1-0:1.0: usb_probe_interface
hub 1-0:1.0: usb_probe_interface - got id
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
hub 1-0:1.0: standalone hub
hub 1-0:1.0: individual port power switching
hub 1-0:1.0: individual port over-current protection
hub 1-0:1.0: Single TT
hub 1-0:1.0: TT requires at most 8 FS bit times (666 ns)
hub 1-0:1.0: power on to power good time: 20ms
hub 1-0:1.0: local power source is good
hub 1-0:1.0: enabling power on all ports
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
mpcore_wdt: MPcore Watchdog Timer: 0.1. mpcore_noboot=0 mpcore_margin=60 sec (nowayout= 0)
zynq-edac f8006000.ps7-ddrc: ecc not enabled
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
TCP: cubic registered
NET: Registered protocol family 17
VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
Registering SWP/SWPB emulation handler
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
hub 1-0:1.0: state 7 ports 1 chg 0000 evt 0000

 

The USB EHCI driver needs to reset the phy device in the initialization process?? How can I manage it?? How did you resolve it?

 

Thanks

0 Kudos
Scholar norman_wong
Scholar
10,256 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

It's been a long time since I worked on this. That's close to what I did way back on the 14.1 code. I pulsed the reset line because I could not assume that existing state of the reset line. Something like this:

dev_info(&ofdev->dev, "Enable USB Phy\n");
gpio_request(59, "usb_reset_n");
gpio_direction_output(59, 0);
udelay(1);
gpio_direction_output(59, 1);
gpio_export(59, false);

Remember to remove or correct the USB PHY reset from u-boot. Looks like they finally added the ULPI settings.

0 Kudos
Participant ierkiaga
Participant
10,251 Views
Registered: ‎11-13-2012

Re: Zynq Linux USB Driver Customization

Near Norman,

 

Where did you reset the line?? Just were I did it ?? The GPIO line is disabled (so reset enabled, because is active low) when linux boots up (without modifying u-boot), so I think that first of all, I should enable it before reseting.

 

When you say to correct the USB phy reset on u-boot, what do you want to say?? Change the USB temporary hack to make it using the GPIO??

 

/*
 * temporary hack to take USB out of reset til the is fixed
 * in Linux
 */
 writel(0x80, 0xe000a204);
 writel(0x80, 0xe000a208);
 writel(0x80, 0xe000a040);
 writel(0x00, 0xe000a040);
 writel(0x80, 0xe000a040);

 

Thanks for your attention

0 Kudos
Scholar norman_wong
Scholar
10,245 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

The ZC702 board used a GPIO for the USB PHY that my custom board used for something else. I had to remove the u-boot hack to avoid conflict with my custom board. If the old GPIO is not connected to anything on your board, I guess there is no harm.

 

I toggled the USB PHY GPIO in ehci-xilinx-usbps.c:ehci_xusbps_drv_probe(). I don't see any reason why your code placement should not work. It just has to happen before the driver starts it's initialization. Ideally, the PHY reset should occur whereever the driver has it's reset code. I was never able to find it at the time. I had to assume that the USB would not be reset again after boot.

0 Kudos
Scholar norman_wong
Scholar
10,241 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

It's occurred to me that these lines in your console mean the PHY was brought out of reset and the code was able to access the PHY through the ULPI port.

xusbps-dr e0002000.ps7-usb: Enable USB Phy
ULPI transceiver vendor/product ID 0x0424/0x0007
Found SMSC USB3320 ULPI transceiver.
ULPI integrity check: passed.

I think your detection problems are elsewhere.

0 Kudos
Participant ierkiaga
Participant
10,232 Views
Registered: ‎11-13-2012

Re: Zynq Linux USB Driver Customization

Hi Norman,

 

As you say, it seems that communication between USB controller and PHY devices is OK. So detection problem must be elsewhere.

 

I would like to know if Phy reset must be done later to enable usb device detections or it is only comunication problem between Phy and USB devices...

 

Thanks for your contribution.

Kind Regards,

 

Ibai

0 Kudos
Scholar norman_wong
Scholar
10,228 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

Normally the PHY is reset once only per boot. It everything is working fine, you never have to reset the PHY or restart the USB stack. I mention a second PHY reset in the case where you are trying to debug the USB and want to do a soft restart of the USB stack. Or in the case of soft reset, the reset line would already be asserted and and would need a deassert before assert.

 

Your console output would suggest the USB stack started correctly. The weird Xilinx pseudo hub. The various USB Device drivers. I think you have to start checking HW. Try a different cable. Check the clock signals. I'm mainly firmware. That's all I got.

0 Kudos
Participant ierkiaga
Participant
9,336 Views
Registered: ‎11-13-2012

Re: Zynq Linux USB Driver Customization

Hi norman,

 

You are rigth, USB stack started correctly and the failure is in the HW. We are using an isolation circuit and it seems that there are error in the design. I made a quick test connecting data signal without isolation and USB driver detects a device.

 

However it is not working properly yet... the driver is not able to communicate with the device without errors. I think that it is a hardware error so the pcb designed is analysing it.

 

Thx for your support.

 

Attachment error:

hub 1-0:1.0: state 7 ports 1 chg 0000 evt 0002
xusbps-ehci xusbps-ehci.0: GetStatus port:1 status 84001403 66  ACK POWER sig=k CSC CONNECT
hub 1-0:1.0: port 1, status 0301, change 0001, 1.5 Mb/s
hub 1-0:1.0: debounce: port 1: total 100ms stable 100ms status 0x301
xusbps-ehci xusbps-ehci.0: port 1 reset complete, port enabled
xusbps-ehci xusbps-ehci.0: GetStatus port:1 status 84001405 66  ACK POWER sig=k PE CONNECT
usb 1-1: new low-speed USB device number 6 using xusbps-ehci
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 2
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 3
..........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 30
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
..........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
usb 1-1: device descriptor read/64, error -71
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: port 1 reset complete, port enabled
xusbps-ehci xusbps-ehci.0: GetStatus port:1 status 84001405 66  ACK POWER sig=k PE CONNECT
usb 1-1: device descriptor read/64, error -71
usb 1-1: new low-speed USB device number 7 using xusbps-ehci
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
usb 1-1: device descriptor read/64, error -71
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0in 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: port 1 reset complete, port enabled
xusbps-ehci xusbps-ehci.0: GetStatus port:1 status 84001405 66  ACK POWER sig=k PE CONNECT
usb 1-1: device descriptor read/64, error -71
usb 1-1: new low-speed USB device number 8 using xusbps-ehci
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0out 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0out 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
usb 1-1: device not accepting address 8, error -71
usb 1-1: new low-speed USB device number 9 using xusbps-ehci
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0out 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 1
...........xusbps-ehci xusbps-ehci.0: detected XactErr len 0/8 retry 31
xusbps-ehci xusbps-ehci.0: devpath 1 ep0out 3strikes
usb usb1: clear tt buffer port 1, a0 ep0 t00080249
usb 1-1: device not accepting address 9, error -71
hub 1-0:1.0: unable to enumerate USB device on port 1
hub 1-0:1.0: state 7 ports 1 chg 0000 evt 0002

 

0 Kudos
Adventurer
Adventurer
9,229 Views
Registered: ‎12-28-2012

Re: Zynq Linux USB Driver Customization

Hi norman,

 

I am not sure my question is suit for this thread, but i have to turn to you for help。 I have attempted to my best, but i still

 

can not solve this problem, hope you can give me some suggestions and i will be very appreciate!!!

 

 

My problem is that the usb3320 ulpi transceiver can not be recognised

 

[    0.780000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.790000] initializing XUSBPS-SOC USB Controller
[    0.790000] usb_hcd_xusbps_probe: No OTG assigned!
[    0.800000] +++++ In ulpi_init function +++++
[    0.800000]  i = 0, ret = -110
[    0.810000] Unable to init ulpi transceiver, mismatching
[    0.810000] Initializing USB Mass Storage driver...
[    0.810000] usbcore: registered new interface driver usb-storage
[    0.820000] USB Mass Storage support registered.

 

 The related  kernel code is that:

// drivers/usb/otg/ulpi.c
static int ulpi_init(struct otg_transceiver *otg)
{
    int i, vid, pid, ret = 0;
    u32 ulpi_id = 0;

    printk("+++++ In ulpi_init function +++++\n");

    for (i = 0; i < 4; i++) {       // get vendor_id, product_id
        ret = otg_io_read(otg, ULPI_PRODUCT_ID_HIGH - i); 
        printk("\ti = %d, ret = %d\n", i, ret);
        if (ret < 0)
            return ret;
        ulpi_id = (ulpi_id << 8) | ret;
    }   
    vid = ulpi_id & 0xffff;
    pid = ulpi_id >> 16; 

    pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid);

    // ...

}


// drivers/usb/host/ehci-xilinx-usbps.c
static int usb_hcd_xusbps_probe(const struct hc_driver *driver, struct platform_device *pdev) {

    pr_info("initializing XUSBPS-SOC USB Controller\n");    
	
    // ...

#ifdef CONFIG_USB_XUSBPS_OTG
    ehci = hcd_to_ehci(hcd);
    if (pdata->otg) {
#ifdef CONFIG_XILINX_ZED
        pr_info ("usb_hcd_xusbps_probe: Have OTG assigned.\n");

        retval = otg_init(pdata->otg);
        if (retval) {
            dev_err(&pdev->dev, "Unable to init transceiver, probably missing\n");
            return ENODEV;
        }
#endif
        ehci->transceiver = pdata->otg;
        retval = otg_set_host(ehci->transceiver,
                                                              161,16-19     34%
        ehci->transceiver = pdata->otg;
        retval = otg_set_host(ehci->transceiver,
                &ehci_to_hcd(ehci)->self);
        if (retval)
            return retval;
        xotg = xceiv_to_xotg(ehci->transceiver);
        ehci->start_hnp = ehci_xusbps_start_hnp;
        xotg->start_host = ehci_xusbps_otg_start_host;
        xotg->stop_host = ehci_xusbps_otg_stop_host;
        /* inform otg driver about host driver */
        xusbps_update_transceiver();
    } else {
#ifdef CONFIG_XILINX_ZED
        pr_info ("usb_hcd_xusbps_probe: No OTG assigned!\n");
        if (!pdata->otg) {
            pdata->otg = otg_ulpi_create (&ulpi_viewport_access_ops,
                ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
            if (pdata->otg) {
                pdata->otg->io_priv = hcd->regs + XUSBPS_SOC_USB_ULPIVP;
                ehci->ulpi = pdata->otg;
            }

            retval = otg_init(pdata->otg);     // this will call ulpi_init() function
            if (retval) {
                pr_info("Unable to init ulpi transceiver, mismatching\n");
                return -ENODEV;
            }
        }
        pr_info ("usb_hcd_xusbps_probe: OTG now assigned!\n");
#endif

        retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
        if (retval != 0)
            goto err2;
    }

    // ...

}

 

My kernel is based on digilent-linux-3.3 version which is a little diffierence with Xilinx kernel。 

 

Since our custom board only can be reset thru pl, so i use ps gpio through emio0 to reset it. I do it in uboot just as you

 

said, but this is not work, too.

    /* temporary hack to take USB out of reset til the is fixed
       in Linux */
#if 0
    XIo_Out32(0xe000a204, 0x80);
    XIo_Out32(0xe000a208, 0x80);
    XIo_Out32(0xe000a040, 0x80);
    XIo_Out32(0xe000a040, 0x00);
    XIo_Out32(0xe000a040, 0x80);
#endif
    // we use gpio emio to reset usb otg
    printf("Usb otg reset via gpio thru emio0\n");
    XIo_Out32(0xe000a284, 0x1);     // set output dir
    XIo_Out32(0xe000a288, 0x1);     // output enable
    XIo_Out32(0xe000a048, 0x1);
    XIo_Out32(0xe000a048, 0x0);     // reset
    udelay(1);
    XIo_Out32(0xe000a048, 0x1);     // out of reset

 

Can you give me some suggestions? Very thanks!!!

 

Best Regards,

Dec

 

 

 

0 Kudos
Scholar norman_wong
Scholar
9,212 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

It's been a couple years since I worked with Xilinx or Linux. My memory is a bit fuzzy. Error 110 is a timeout. Means the ULPI viewport status flags are not changing as expected.

 

If you are using EMIO to reset the USB PHY, I assume that the PL is loaded before you toggle the EMIO in u-boot?

 

 

Adventurer
Adventurer
9,207 Views
Registered: ‎12-28-2012

Re: Zynq Linux USB Driver Customization

Hi norman,

 

Thanks for your reply!  Yes, you are right and it is just timeout when wait the Wakeup bit in ulpi_viewpoint register  to

 

complete.  Here is some of my debug in code.

 

ulpi_init 

         --->   otg_io_read

                          --->   ulpi_viewport_read        (call relationships)

 

// drivers/usb/otg/ulpi_viewpoint.c
static int ulpi_viewport_wait(void __iomem *view, u32 mask)
{
    unsigned long usec = 2000;
    u32 regval;

    while (usec--) {
        regval = readl(view);
        //pr_info("   regval = 0x%08x\n", regval);
        if (!(regval & mask))
            return 0;

        udelay(1);
    };
    pr_info("   ulpi_vp reg timeout exit val = 0x%08x\n", regval);
    pr_info ("  Ulpi wait timeout.\n");
    return -ETIMEDOUT;
}

static int ulpi_viewport_read(struct otg_transceiver *otg, u32 reg)
{
    int ret;
    void __iomem *view = otg->io_priv;

// get the reset value pr_info (" ulpi_vp reg reset val = 0x%08x\n", readl(view)); writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); // ERROR at this place if (ret) { pr_info("Wait ulpiview wakeup done failed\n"); return ret; } writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); if (ret) { pr_info("Wait ulpiview run/read done failed\n"); return ret; } return ULPI_VIEW_DATA_READ(readl(view)); }

 

 

下面是程序执行的结果:

[    0.790000] Iomap mem base 0xE0002000 to virtual base 0xD0814000
[    0.790000] initializing XUSBPS-SOC USB Controller
[    0.800000] usb_hcd_xusbps_probe: No OTG assigned!
[    0.800000] Otg transceiver ulpi viewpoint virtual base = 0xD0814170
[    0.810000] +++++ In ulpi_init function +++++
[    0.810000]    ulpi_vp reg reset val = 0x08000000
[    0.820000]    ulpi_vp reg timeout exit val = 0xa8000000
[    0.820000]    Ulpi wait timeout.
[    0.820000] Wait ulpiview wakeup done failed
[    0.820000]  i = 0, ret = -110
[    0.830000] Unable to init ulpi transceiver, mismatching
[    0.830000] Initializing USB Mass Storage driver...
[    0.840000] usbcore: registered new interface driver usb-storage
[    0.840000] USB Mass Storage support registered.
[    0.840000] Xilinx PS USB Device Controller driver (Apr 01, 2011)

 

During the read procedure, the Wakeup bit should be set and then wait Wakeup bit to transition 0。  

 

From the result, we can see that the Wakeup bit has been set correctlly(ulpi_viewpoint regval = 0xa8000000)。

 

But at my board, it seems that bit can not be clear automatically (When timeout, it still 0xa8000000)。 

 

Any suggestions?!  And what is the job of this Wakeup bit?  Thank you very much!!!

 

Best Regards,

Dec

 

0 Kudos
Adventurer
Adventurer
9,206 Views
Registered: ‎12-28-2012

Re: Zynq Linux USB Driver Customization

Yes, i program the fpga first and then dow and run the uboot  in JTAG Mode。 

 

Some commands in XMD:

         source ps7_init.tcl

         fpga -f system.bit

         dow u-boot.elf

         con

 

 

My operation to use gpio through emio0 to reset the otg is as follow,  And the corresponding EMIO Bank0 registers,

 

emio0 bit. Any problem?!   

 

 

 

   emio.png

 

   /*** UCF ***/      

   # Usb otg reset
   NET otg_reset_n LOC = J14 | IOSTANDARD = LVCMOS25;

 

 

    // we use gpio emio to reset usb otg
    printf("Usb otg reset via gpio thru emio0\n");
    XIo_Out32(0xe000a284, 0x1);     // set output dir
    XIo_Out32(0xe000a288, 0x1);     // output enable
    XIo_Out32(0xe000a048, 0x1);
    XIo_Out32(0xe000a048, 0x0);     // reset
    udelay(1);
    XIo_Out32(0xe000a048, 0x1);     // out of reset
0 Kudos
Scholar norman_wong
Scholar
9,194 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

I am primarily firmware. Cannot comment about the PL side. As far as I can tell, the EMIO config and toggle code looks correct. I have use the ps7_init.c in the FSBL but never used the ps7_init.tcl method. I assume that the ps7_init.tcl gets updated just like ps7_init.c. Those files might do some additional config of the EMIO. Check to see if you using the updated ps7_init.tcl file.

The ULPI viewport register is on the USB controller side. The WAKEUP and WRITE bits will get set regardless of the PHY state. Setting those bits starts up a state machine in the USB controler to talk to the PHY. I am guessing if the PHY responds correctly, the state machine will lower the WAKEUP and WRITE bits. Implies that the PHY is not answering.

Have you scoped out the USB PHY reset line? Checked the PHY clock? The voltages to the PHY? You've reached the limits of my knowledge. Perhaps you should start a new post. Hopefully more knowledgable people can respond.

0 Kudos
Adventurer
Adventurer
9,128 Views
Registered: ‎12-28-2012

Re: Zynq Linux USB Driver Customization

Hi norman,

 

I am sorry my reply is so late, but you suggestion is really helpful for me!  We finally found that there was no clock input

 

tothe PHY, and it was the crystal problem.  Now the PHY can be recognized. But i encounter with another problem that

 

the usb device can not be enumerate.   These errors occurs, even though there is no usb device connect  (just when

 

system is up, they are appearing)

 

[    0.780000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.790000] Iomap mem base 0xE0002000 to virtual 0xD0814000
[    0.790000] initializing XUSBPS-SOC USB Controller
[    0.800000] usb_hcd_xusbps_probe: No OTG assigned!
[    0.800000] Otg transceiver ulpi viewpoint = 0xD0814170
[    0.810000] ULPI transceiver vendor/product ID 0x0424/0x0007
[    0.810000] Found SMSC USB3320 ULPI transceiver.
[    0.820000] ULPI integrity check: passed.
[    0.820000] usb_hcd_xusbps_probe: OTG now assigned!
[    0.820000] xusbps-ehci xusbps-ehci.0: Xilinx PS USB EHCI Host Controller
[    0.830000] xusbps-ehci xusbps-ehci.0: new USB bus registered, assigned bus number 1
[    0.860000] xusbps-ehci xusbps-ehci.0: irq 53, io mem 0x00000000
[    0.880000] xusbps-ehci xusbps-ehci.0: USB 2.0 started, EHCI 1.00
[    0.880000] hub 1-0:1.0: USB hub found
[    0.880000] hub 1-0:1.0: 1 port detected
[    0.890000] Initializing USB Mass Storage driver...
[    0.890000] usbcore: registered new interface driver usb-storage
[    0.900000] USB Mass Storage support registered.
[    0.900000] Xilinx PS USB Device Controller driver (Apr 01, 2011)
[    0.910000] mousedev: PS/2 mouse device common for all mice
[    0.910000] Linux video capture interface: v2.00
[    0.910000] gspca_main: v2.14.0 registered
[    0.920000] usbcore: registered new interface driver uvcvideo
[    0.920000] USB Video Class driver (1.1.1)
[    0.930000] WDT OF probe
[    0.930000] xwdtps f8005000.swdt: Xilinx Watchdog Timer at 0xd0816000 with timeout 10 seconds
[    0.940000] sdhci: Secure Digital Host Controller Interface driver
[    0.940000] sdhci: Copyright(c) Pierre Ossman
[    0.940000] sdhci-pltfm: SDHCI platform and OF driver helper
[    0.950000] mmc0: Hardware doesn't report any support voltages.
[    0.950000] sdhci platform registration failed
[    0.960000] usbcore: registered new interface driver usbhid
[    0.960000] usbhid: USB HID core driver
[    0.970000] ALSA device list:
[    0.970000]   No soundcards found.
[    0.970000] TCP cubic registered
[    0.980000] NET: Registered protocol family 17
[    0.980000] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
[    0.990000] Registering SWP/SWPB emulation handler
[    0.990000] registered taskstats version 1
[    0.990000] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
[    1.000000] RAMDISK: gzip image found at block 0
[    1.210000] usb 1-1: new low-speed USB device number 2 using xusbps-ehci   // this place
[    1.270000] EXT4-fs (ram0): warning: mounting unchecked fs, running e2fsck is recommended
[    1.280000] EXT4-fs (ram0): mounted filesystem without journal. Opts: (null)
[    1.280000] VFS: Mounted root (ext4 filesystem) on device 1:0.
[    1.290000] Freeing init memory: 156K
Starting rcS...
++ Mounting filesystem
++ Setting up mdev
[    1.410000] usb 1-1: device descriptor read/64, error -71
++ Configure static IP 192.168.1.10
ifconfig: SIOCGIFFLAGS: No such device
ifconfig: SIOCSIFADDR: No such device
++ Starting telnet daemon
++ Starting http daemon
++ Starting ftp daemon
++ Starting dropbear (ssh) daemon
rcS Complete
zynq> [    1.720000] usb 1-1: device descriptor read/64, error -71		// EPROTO  protocol error
[    1.950000] usb 1-1: new low-speed USB device number 3 using xusbps-ehci
[   17.100000] usb 1-1: device descriptor read/64, error -110     //ETIMEDOUT con timeout error
[   22.380000] usb 1-1: device descriptor read/64, error -71
[   22.610000] usb 1-1: new low-speed USB device number 4 using xusbps-ehci
[   23.080000] usb 1-1: device not accepting address 4, error -71
[   23.200000] usb 1-1: new low-speed USB device number 5 using xusbps-ehci
[   23.670000] usb 1-1: device not accepting address 5, error -71
[   23.670000] hub 1-0:1.0: unable to enumerate USB device on port 1

 

 I am a newer for usb. Can you give me some suggestions! I am very appreciate!!!

 

Best Regards,

Dec

0 Kudos
Scholar norman_wong
Scholar
9,118 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

The USB enumeration process is triggered by activity on the data USB lines. I am guessing that your custom board thinks it is seeing activity. I found this site helpful:

 

http://www.usbmadesimple.co.uk/

 

I would guess that you should look at the D+ and D- lines for any noise. USB signalling is very dependent on the impedances on the lines. Check to see if your design matches a known design (dev board).

 

0 Kudos
Adventurer
Adventurer
9,113 Views
Registered: ‎12-28-2012

Re: Zynq Linux USB Driver Customization

Hi norman,

 

Thanks for your reply!  Do you mean these errors may be caused by HW design instead of a SW driver problem? Maybe

 

some noises has occurs between  the D+ and D- lines, Right?!   Ok, we will check the hw design.  By the way, i attac!h

 

our hw design and if you can help me have a check, that would be great !  Thank you very mach!

 

Best,

Dec

 

 

original.png
0 Kudos
Scholar norman_wong
Scholar
9,105 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

Sorry. You've really reached the limit of my knowledge of hardware. I mainly do just firmware. I know just enough hardware to ask/blame the hardware guys. Maybe start a new thread and a HW guy can comment.

 

I'm no expert on USB either. I am guessing you've got some glitches on D+, D- or even VBUS that is fooling the USB controller that something has been plugged in. The linux USB driver is fairly known quantity.

0 Kudos
Adventurer
Adventurer
6,481 Views
Registered: ‎12-28-2012

Re: Zynq Linux USB Driver Customization

Ok, anyway, i still want to express my deeplly gratidue here.  Thanks for you helps!!!

 

Best,

Dec

0 Kudos
Visitor fzxing
Visitor
5,946 Views
Registered: ‎08-13-2014

Re: Zynq Linux USB Driver Customization

Hi,norman.

I have a similar problem in my project. My USB phy's reset is controlled by a GPIO and I controll it thought xusbps-dr-of driver, as you can see in this part of code:/driver/usb/host/xilinx-dr-of.c

/*****************************************************************/

dev_info(&ofdev->dev, "Enable USB Phy\n");
gpio_request(59, "usb_reset_n");
gpio_direction_output(59, 0);
udelay(1);
gpio_direction_output(59, 1);
gpio_export(59, false);

 

/* If ULPI phy type, set it up */

         if (pdata->phy_mode == ZYNQ_USB2_PHY_ULPI) {
                 pdata->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops,
                         ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
                 if (pdata->ulpi) {
                         pdata->ulpi->io_priv = pdata->regs +
                                                         ZYNQ_SOC_USB_ULPIVP;
 
                         phy_init = usb_phy_init(pdata->ulpi);
                         if (phy_init) {
                                 dev_err(&ofdev->dev,
                                         "Unable to init USB phy, missing?\n");
                                 ret = -ENODEV;
                                 goto err_out_clk_disable;
                         }
                 } else {
                         dev_err(&ofdev->dev,
                                 "Unable to create ULPI transceiver\n");
                 }
         }

/*****************************************************************/

Looking for the boot console, it seems that USB phy device is not attached .

 

ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
zynq-dr e0002000.ps7-usb: Enable USB Phy
zynq-dr e0002000.ps7-usb: Unable to init USB phy, missing?
zynq-dr e0003000.ps7-usb: Enable USB Phy
zynq-dr e0003000.ps7-usb: Unable to init USB phy, missing?
usbcore: registered new interface driver usb-storage
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver

 

The USB EHCI driver needs to reset the phy device in the initialization process?? How can I manage it?? How did you resolve it?

 

Thanks

0 Kudos
Scholar norman_wong
Scholar
5,931 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

It's been a few years since I dealt with Xilinx USB problems. Looks all right. Not much to add. Usual questions:

Did you observe the reset pulse on an oscilloscope?

Does the PHY have clock?

Is the PL loaded and configured to handle GPIO 59? I vaguely remember 59 is an EMIO?

Has the GPIO pin been muxed in?

 

0 Kudos
Visitor fzxing
Visitor
5,928 Views
Registered: ‎08-13-2014

Re: Zynq Linux USB Driver Customization

Hi norman:

I observe the reset pulse on oscilloscope is high level;

The MIO 20 is used reset gpio other is 28~39 MIO and MIO 20 is not muxed,the MIO configured in devicetree.dts:usb-reset = ps_7_gpio<0 20 0>;

The PHY has no clock;

My baseboard is custom,and i have no PL been loaded.

Looking forward to your reply!Wish your work is smooth!

 

 

0 Kudos
Scholar norman_wong
Scholar
5,917 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

I don't quite understand. Do you observe a pulse on the PHY reset pin or do you observe a constant high level on the PHY reset pin?

As far as I know, the USB PHY needs a clock.

Your code fragment referenced GPIO 59. I think MIO 20 should map to GPIO 20. I don't think the device tree config will mux in the MIO. That is usually done in the FSBL ps7_init.c or in custom u-boot code.

 

Could be wrong it's been a few years since I worked on Zynq. The device tree support has improved since the last version I used, 14.1. Which version are you using?

0 Kudos
Visitor fzxing
Visitor
5,908 Views
Registered: ‎08-13-2014

Re: Zynq Linux USB Driver Customization

I observe a pulse on the PHY reset pin and observed a constant high level on the PHY reset pin.The following is my modified code:

         // Enable USB Phy reset pin set
         dev_info(&ofdev->dev, "Enable USB Phy\n");
         gpio_request(20, "usb_reset_n");
         gpio_direction_output(20, 0);
         udelay(1);
         gpio_direction_output(20, 1);

         gpio_export(20, false);

 

I can`t observe the clock waveforms on the PHY clock pin,i don`t know the clock is from PL or from linux driver.

The following attach file is all i modified file about kernel and ps7_init.c.

Ineed your advice,thank you very much!

0 Kudos
Scholar norman_wong
Scholar
5,902 Views
Registered: ‎05-28-2012

Re: Zynq Linux USB Driver Customization

I don't see any attachments to your post. If you are seeing the pulse, then MIO config and kernel gpio toggle code are working. That leaves the PHY clock and ULPI pins. On the ZED board, the PHY clock comes from MIO36 which is muxed to the USB controller clock. You have to trace the clock path.

 

That's all I got. You should start your own thread. Other people know a lot more than me on this. And are more current.

 

0 Kudos
Visitor fzxing
Visitor
5,900 Views
Registered: ‎08-13-2014

Re: Zynq Linux USB Driver Customization

Thank you for your advice,i think i can according to this path to solve the problem.Thank you very much!

 

0 Kudos