MT7622 USB Device

Hi everyone,

I’ve been trying to enable USB Gadget (Device) mode on an MT7622-based board. According to the MT7622 datasheet, the USB 2.0 PHY supports "dual-mode" (host/device). However, the default mt7622.dtsi only defines the xhci node (Host-only mode).

Here is the default definition in mt7622.dtsi:

ssusb: usb@1a0c0000 {
    compatible = "mediatek,mt7622-xhci", "mediatek,mtk-xhci";
    reg = <0 0x1a0c0000 0 0x01000>,
          <0 0x1a0c4700 0 0x0100>;
    reg-names = "mac", "ippc";
    /* ... interrupts, clocks, phys ... */
    status = "disabled";
};

To switch to Gadget mode, I enabled the CONFIG_USB_MTU3 (MediaTek USB3 Dual Role controller) and CONFIG_USB_GADGET drivers via kernel_menuconfig, and applied the following DTS override to force the peripheral mode:

&ssusb {
    compatible = "mediatek,mt7622-mtu3", "mediatek,mtu3";
    
    reg = <0 0x1a0c0000 0 0x3000>,
          <0 0x1a0c4700 0 0x0100>;
    reg-names = "mac", "ippc";

    dr_mode = "peripheral";
    maximum-speed = "high-speed";

    phys = <&u2port0 PHY_TYPE_USB2>;
    vusb33-supply = <&reg_3p3v>;
    vbus-supply = <&reg_5v>;
    status = "okay";
};

The Issue:
The mtu3 driver probes successfully and registers the UDC (USB Device Controller), but it fails to initialize the Endpoints (EPs).

Here is the dmesg output:

[    1.076134] mtu3 1a0c0000.usb: failed to get phy-0
[    2.263130] mtu3 1a0c0000.usb: dr_mode: 2, drd: auto
[    2.278119] mtu3 1a0c0000.usb: irq 140
[    2.281891] mtu3 1a0c0000.usb: IP version 0x0(U2 IP)
[    2.291819] mtu3 1a0c0000.usb: fifosz/epnum: Tx=0x0/0, Rx=0x0/0
[    2.297756] mtu3 1a0c0000.usb: dma mask: 32 bits

Low-level MMIO Debugging (The Root Cause):
To determine if this is a driver initialization bug (e.g., missing clocks/power) or a physical hardware limitation, I performed a manual register dump. Register offsets and bitfields were identified using the mtu3_hw_regs.h header from the Linux 6.6 source tree (drivers/usb/mtu3/).

  1. Checking the Host (xHCI) base register:
    devmem 0x1a0c0000 32 -> 0x00960020 (xHCI controller is alive and powered).

  2. Checking Device Capability Registers (UDC/MTU3):

  • 0x1a0c0c10 (U3D_CAP_EPINFO) -> 0x00000000
  • 0x1a0c0c08 (U3D_CAP_EPNTXFFSZ) -> 0x00000000
  • 0x1a0c0c0c (U3D_CAP_EPNRXFFSZ) -> 0x00000000
  • 0x1a0c47a4 (U3D_SSUSB_HW_SUB_ID / IP_TRUNK_VERS) -> 0x00000000

Even after manually clearing the power-down bits in the IPPC registers (DEV_PDN in PW_CTRL2, and U2_CTRL_0P) and performing a SW reset via devmem, the Capability registers consistently return 0x00000000.

The fact that capability registers consistently return zero—even with the IPPC power-down bits cleared—suggests two possibilities. Either the digital UDC logic (MTU3 IP/SRAM) is physically absent/fused off in this specific SoC revision, or there is a critical, undocumented initialization sequence (such as a secure-bridge setting or a specific clock-gating dependency) required to expose the Device MAC.

Has anyone successfully initialized the MTU3 core on the MT7622 in peripheral mode? Is this a known hardware-level SKU limitation, or am I missing a "magic" sequence to wake up the UDC logic?

Thanks!

1 Like

Missing phy driver ?

If I understand correctly, the failed to get phy-0 at [ 1.076134] happens simply because the PHY driver hasn't finished initializing yet.

Then, the kernel retries at [ 2.263130], and by that time the PHY is already initialized, so the driver successfully picks it up and continues the boot process.

Is my assumption about this correct?

Do you have kmod-mt76-usb installed?

I didn't enable kmod-mt76-usb. As far as I understand, the mt76 stack in Linux is specifically designed for MediaTek Wi-Fi drivers. I understand it's needed when the SoC acts as a USB host for external wireless adapters. It shouldn't be related to the UDC mtu3 driver, which I'm trying to initialize. Or am I missing something?