How many USB host controller have udoo quaad in linux?

Discussion in 'UDOO QUAD' started by Flamenawer, Nov 13, 2017.

  1. Flamenawer

    Flamenawer Member

    Nov 2, 2013
    Likes Received:
    I want connet 4 usb cameras, too much data for one, host, there is two of them?
    Last edited: Nov 13, 2017
  2. fetcher

    fetcher Member

    Mar 9, 2014
    Likes Received:
    There are two USB host controllers, but one is dedicated exclusively to the USB OTG port, present on the micro-USB connector next to the console port (second from the left, when looking at the back of your board). By default this port operates in USB Device (aka target, gadget) mode. You can plug in an OTG adapter cable there, as used on a phone or tablet, to get a type-A Host port, but some kernel hacking is necessary to get it to actually work.

    OTG ports use the the normally-unconnected 5th micro-USB pin as an ID signal - grounding this pin is supposed to switch the port into Host mode, and enable it to source rather than accept +5V power. For some reason, possibly just a layout error, the Udoo designers didn't properly route this ID signal back to the i.MX6 SoC, so it's unable to detect the grounded pin.

    I worked around this by using the i.MX6's pin-mux feature to map its OTG_ID input to a different i.MX6 pad, one which isn't bonded out to anything, then enabled the internal pull-down resistor on that pad to simulate having it externally grounded, thereby forcing USB Host mode to always be active. Note that after doing this, you can't safely plug a normal microUSB cable from another host device into the OTG, since it won't switch back to device mode, and both ends would be sourcing power.

    The below patches are to linux/arch/arm/mach-mx6/board-mx6qd_seco_UDOO.h and linux/arch/arm/mach-mx6/board-mx6_seco_UDOO.c in kernel version 3.0.35. This is an older kernel, but one I'm still using on my main Udoo, since I have a lot of customizations like this in it. Newer kernels with their DTB (Device Tree) config system do certain things differently, so you might have to adapt this a bit if not running 3.0.35.

    Once this is working, you 'grep usb /proc/interrupts' to confirm activity on both controllers.
     72:   59052865          0          0          0       GIC  usb_wakeup, fsl ehci pre interrupt, ehci_hcd:usb2
     75:   57014388          0          0          0       GIC  usb_wakeup, fsl ehci pre interrupt, ehci_hcd:usb1
    'usb1' is the OTG port, which I dedicate to a tethered LTE cellphone used as a backup Internet connection, and 'usb2' is everything else, including both rear panel ports, the internal one on a header, and the Udoo's on-board Wifi if you use that (if not, its module can be removed to reveal a handy 4th USB port, but it's behind the same USB 2.0 hub chip as the other three).

    Anyway, here's the necessary patch to board-mx6qd_seco_UDOO.h --
    +++ board-mx6qd_seco_UDOO.h     2015-01-11 14:19:59.000000000 -0500
    @@ -6,9 +6,15 @@
     *    IOMUXPAD explanation
    -*       (mux address, pad address, mux, 0x0000, 0, pad values)
    +*  -jnh- (padctrl address!, mux address!, mux value, 0x0000, 0, pad values)
    +// -jnh- daisy-chain mux change also required in board-mx6_seco_UDOO.c
    +               (IOMUX_PAD(0x04EC, 0x01D8, 0, 0x0000, 0, (PAD_CTL_PKE | PAD_CTL_PUE | \
    +                PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
    +                PAD_CTL_SRE_FAST | PAD_CTL_HYS)))
     // SAM3X erase
    @@ -118,6 +125,8 @@
     static iomux_v3_cfg_t mx6qd_seco_UDOO_pads[] = {
    +       MX6Q_PAD_ENET_RX_ER__USB_OTG_ID__PULLDOWN,      // pull down to force OTG HOST mode
            /* AUDMUX */
    And to linux/arch/arm/mach-mx6/board-mx6_seco_UDOO.c --
    @@ -308,10 +322,11 @@
     static void __init imx6q_seco_UDOO_init_usb(void) {
            imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
    -       /* disable external charger detect,
    -        * or it will affect signal quality at dp .
    +       /* -jnh-
    +        * set GPR1 daisy-chain mux: USB_OTG_ID == ENET_RX_ER
    +        * this has nothing to do with charger detection!
    -       mxc_iomux_set_gpr_register(1, 13, 1, 1);
    +       mxc_iomux_set_gpr_register(1, 13, 1, 0);
     //     mx6_usb_dr_init();
    Flamenawer likes this.
  3. Flamenawer

    Flamenawer Member

    Nov 2, 2013
    Likes Received:
    Thank you a lot for all your help, sadly compile or modify a kernel is out of my capabilities. Maybe in the future.
    I hope udoo staff take note of your nice post and make a kernel that make it to work,is important for robotics with visual perception, kinect ..., you need a lot of bandwidth, and that 2 host controllers...
  4. fetcher

    fetcher Member

    Mar 9, 2014
    Likes Received:
    If you use the newer 3.14.56 kernel, the USB drivers have been updated to allow host-mode to work by default on the OTG port, without having to patch the kernel or recompile.

    However, I did find it necessary to disable a flaky over-current protection feature, which is active by default and makes the OTG port highly unstable due to spurious resets (as tested on two different Udoo Quads, and with a variety of USB devices including usb-storage hard drives, Android phones, even just a plain keyboard running a 1.5Mb/s low-speed. Long cables and high-speed transfers do make the problem worse, though. If messages like

    "usb 1-1: reset high-speed USB device number 65 using ci_hdrc

    appear in your kernel log (dmesg), this is what's going on.

    The good news is that this problem can be quickly fixed by editing the active device-tree .dts under /boot/dts or /boot/dts-overlay (the latter is used if use_custom_dtb=true appears in /boot/uEnv.txt), for example imx6q-udoo-hdmi.dts, then recompiling it with the dtc tool. After making a backup of this file, find the usb-controller block labeled "usb@02184000", then insert the two marked lines below after the vbus-supply line, but before the closing bracket:
                            usb@02184000 {
                                    compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                    reg = <0x2184000 0x200>;
                                    interrupts = <0x0 0x2b 0x4>;
                                    clocks = <0x2 0xa2>;
                                    fsl,usbphy = <0x1e>;
                                    fsl,usbmisc = <0x1f 0x0>;
                                    fsl,anatop = <0x19>;
                                    status = "okay";
                                    pinctrl-names = "default";
                                    vbus-supply = <0x20>;
                                    disable-over-current;    //  ADD THIS
                                    dr_mode = "host";       //  ADD THIS
    usb@02184200, appearing right after this block is for the other USB host controller, the one feeding an on-board 4-port hub. It wouldn't hurt to add the disable-over-current flag to this one as well.

    Finally, recompile the binary/"blob" version of your modified device tree,

    dtc -I dts -O dtb imx6q-udoo-hdmi.dts >imx6q-udoo-hdmi.dtb # (adjust filenames as needed)

    then reboot, and enjoy two stable USB Host controllers!

    By the way, in reading up on the i.MX6 chip you may find references to two additional host controllers onboard, which also appear as "disabled" devices in the .dts Device Tree (at addresss 02184400 and 02184600), but these are HSIC-only controllers intended for interconnect between chips, and would need an outboard transceiver chip added to be usable for standard USB connections. Worse still, they share pins with the onboard GIgabit Ethernet, and so are mutually exclusive with being able to use the NIC. So, on a board like the Udoo, two USB controllers is unfortunately the limit.

    If only they'd bonded out the i.MX6 PCI-Express controller pins, we could have added more of our own, or even USB 3.0 (though not at full speed). It would have made the board more expensive for something most people would never use, though.
    waltervl likes this.

Share This Page