USB xHCI控制器使用总结

VI行超过80字符长度提示:set colorcolumn=81

1 APL USB xHCI控制器
1.1 驱动架构
14nm Apollo Lake (Gen9, A39X0) was released in September 2016.
APL 8-port MPH xHCI控制器实际上有两个roothub,一个是roothub 2.0的,一个是roothub 3.0。因为xHCI的这个特性,在Linux内核里,如果发现了PCI或者PCIe总线上具有xHCI控制器,那么驱动会向USB Core子系统注册两个roothub控制器,一个是roothub 2.0,一个是roothub 3.0,代码参见xhci-pci.c中的xhci_pci_probe()函数。

UEFI中xHCI驱动没有使用中断方式,而是用的轮训方式。

xhci_get_endpoint_index()
ep_index = (epnum * 2) + direction - 1
ep_index = 6 means ep3in

1.2 OTG架构
寄存器地址:PCI_BAR0 + 80D8h
8-port MPH xHCI和dwc3组成一个PCI多功能设备,xHCI的func号为0,dwc3的func号为1,Synopsys dwc3 usb comes from inSilicon。由于PCI总线一般只有INTA#到INTD#的4个中断引脚,所以PCI多功能设备的func一般不会超过4个,但是共享中断除外。

/sys/bus/platform/drivers/intel_usb_dr_phy/intel_usb_dr_phy.0/mux_state

1.3 xHCI Scheduler Async Delay
Datasheet
21.1 xHCI - including OTG MUX Registers
21.2 xHCI PCI Config Registers
21.3 DBC
21.4 DWC3
21.5 DWC3
21.6 xHCI Proprietary Registers
21.7 DWC3 PCI Config Registers
21.9 DWC3 PCI Config Registers

寄存器地址:PCI_BAR0 + 80D4h
在控制或者Bulk令牌传输之间插入延时,否则IN或者OUT令牌发送太快会导致ublox M8030全速设备丢包。

1.4 PIPE PHY数据线宽度
DWC_usb3_databook_2.50a.pdf
USB 3.0 PIPE PHY(SerDes = PCIe Gen2)的数据线宽度是可以设置的,最大宽度分别是Tx 32bit、Rx 32bit,需要根据PIPE PHY的接口频率来设置数据线宽度。如果PIPE PHY运行在128MHz,那么Tx和Rx的数据线宽度都是32bit;如果PIPE PHY运行在256MHz,那么Tx和Rx的数据线宽度都是16bit。

USB 3.0 Gen1的速度5Gbps,是指Tx和Rx的速率都是5Gbps(128MHz x 4bytes或者256MHz x 2bytes)。
USB 3.0 Gen1的速度5Gbps(625MB/s),协议开销(overhead)占用了20%带宽,所以实际有效速度是500MB/s。
USB 3.0 Tx或者Rx的传输速率虽然是5Gbps,但实际上数字信号的方波频率是2.5GHz(传输2个bit对应一个方波)。

Intel APL (Gen9, A39X0) 8-port MPH xHCI的物理层名字是ModPHY(High Speed I/O Modular Physical Layer for Intel USB 3.0)。

1.5 USB babble
babble错误表示在IN或者OUT token后,而在ACK之前,端点接收数据多于端点的bMaxPacketSize。

1.6 USB DCI DbC调试技术
CONFIG_USB_XHCI_DBGCAP
/sys/bus/pci/devices/0000:00:14.0/dbc

用于调试的USB 3.0 Debugging Cable的VBUS、DP和DM不连接,也就是pinout的1到3不连接,仅连接pinout的4到9。DbC软件工具是Intel System Studio。

Windows目标机需要打开调试功能,输入msconfig打开系统配置工具。在引导 - 高级选项下面:勾选调试,调试端口选择USB,USB目标名称随便写一个自己能记住的名字。将来Host和Target两端要靠这个名字进行匹配。

1.7 Other Atom xHCI
1) Atom E3800 (Bay Trail, BYT, Gen7, 2013) has a 7-port MPH xHCI, 1 port supports DEBUG capability, 2 ports support HSIC, 4 ports are shared with 4-port MPH EHCI. It has an independent super speed USB device controller, but does not support OTG.
2) Atom Z8000 (Cherry Trail, CHT, Gen8, 2014) has an 8-port MPH xHCI, port1 supports OTG, 2 ports support HSIC (LVCMOS 1.2V), 2 ports support SSIC. It is similar to APL.

1.8 Interrupt on Short Packet
xhci_hcd WARN Event TRB for slot x ep y with no TDs queued
http://billauer.co.il/blog/2019/11/xhci-controller-bug-warning/

https://lore.kernel.org/patchwork/patch/860018/
https://lkml.org/lkml/2016/1/5/1035

1.9 LTSSM stuck issue
not warm reset yet, waiting 200ms
not enabled, trying warm reset again

This log shows ss port stuck issue.
Disable USB3 roothub port: Clear power Feature and Set BH_Reset Feature.
In Hex format.
23 01 0008 port1 0000
23 03 001c port1 0000
Disable USB3 non roothub port: Set Rx.disabled Feature.
In Hex format.
23 03 0005 0400|port1 0000
Add # define DEBUG at the first line of the hub.c file (above the header files) for enabling Linux dynamic debug log.

1.10 debug
1) A3940 full-speed token sends fast
2) LTSSM stuck
3) over-current
4) UFD accessory setup + INQUIRY concurrent issue
5) USB Eye Pattern Issue
NRZI编码遇到原始数据0反转,原始数据1不反转,遇到连续6个1强插一个0。
USB packet format: Sync|PID (SETUP/IN/OUT/DATA0/ACK)|data|CRC|EOP
6.4.5 TRB Completion Codes of xHCI spec.
COMP_USB_TRANSACTION_ERROR (Bad PID or CRC) - EPROTO
Enable the xhci_dbg of handle_tx_event() in xhci-ring.c

DWC3 gadget: DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE

2 Bulk传输速度计算
- Full-speed
每个frame最大可以传输19个Bulk包,每个Bulk包最大是64 Bytes,所以其最大传输速率是:19 x 64 x 1000 = 1.16 MB/s。
- High-speed
USB 2.0在每个微帧中最大可传输13个Bulk包,每个Bulk包最大是512 Bytes,而每个微帧长固定为125 μs,所以其最大传输速率为:13 x 512 x 8 x 1000 = 51 MB/s。
- Super-speed
USB 3.0在每个微帧中最大可传输13个Bulk包,每个Bulk包最大是1024 Bytes,而每个微帧长固定为125 μs,所以其最大传输速率为:13 x 1024 x 8 x 1000 = 102 MB/s。

3 APL xHCI HS眼图调试
3.1 P2SB USB2 tunning registers
reg_addr = 0xf8000000 (P2SB bar0) + (PortID << 16) + offset;

3.2 EHCI眼图调试寄存器设置流程
第一步:把寄存器USBCMD的bit4和bit5设成0
第二步:把寄存器USBCMD的bit0和bit6设成0
第三步:
- 对应的USB port的PORTSC,port suspend(bit7)设置成0
- 然后把测试模式selector(取值范围:>0,<5,这个数字对应眼图夹具上的那个开关的拨弄的编号)写到PORTSC中(selector << 16)

3.3 xHCI每个port的4个寄存器
- EHCI每个port都有一个寄存器PORTSC
- xHCI中每个2.0和3.0 port entry的寄存器个数(包括PORTSC)都是4,并且每个port entry占了16个字节

drivers/usb/host/xhci-hub.c 
xhci_get_ports()

3.4 xHCI HS眼图调试寄存器设置流程
第一步:把寄存器USBCMD的bit0设成0
第二步:
- 对应的USB port的PORTSC,port power(bit9)设置成0
- 然后把测试模式selector(取值范围:>0,<5,这个数字对应眼图夹具上的那个开关的拨弄的编号)写到PORTPMSC中(selector << 28)

验证方法:
1)把selector的值设成1,这时候你用万用表去量D+的电压为高(0.4V),而D-的电压为0,就说明寄存器设置对了
2)要测试眼图,只要把selector设成4就行了

注意点:
1)测试Host眼图时Golden Device参考板使用Cypress Ref Board
2)APL 8-port MPH xHCI HS不支持修改DC level(400mV)

3.5 xHCI HS Roothub眼图测试patch
in xhci-hub.c
int xhci_hub_control(struct usb_hcd *hcd,
    u16 typeReq, u16 wValue,
    u16 wIndex, char *buf, u16 wLength)
{
    [...]
    unsigned selector;
    [...]

        case SetPortFeature:
            if (IS_ENABLED(
                CONFIG_USB_EHSET_TEST_FIXTURE))
                selector = wIndex >> 8;
            [...]
            /* p320, s4.19.6 Port Test Modes
             * in xhci spec
             */
            case USB_PORT_FEAT_TEST:
                if (!IS_ENABLED(
                CONFIG_USB_EHSET_TEST_FIXTURE))
                {
                    (void)selector;
                    goto error;
                }

                if (hcd->speed >= HCD_USB3)
                    goto error;

                if (!selector || selector > 5)
                    goto error;

                spin_unlock_irqrestore(&xhci->lock,
                    flags);
                xhci_quiesce(xhci);
                spin_lock_irqsave(&xhci->lock,
                    flags);

                /*
                 * Put all enabled ports into
                 * Disabled state, Port Power = 0
                 * FIXME: only can set
                 * port_array[#wIndex] to PP = 0
                 */
                temp = readl(port_array[wIndex]);

                temp &= ~(1 << 9);
                writel(temp, port_array[wIndex]);
                temp = readl(port_array[wIndex]);

                spin_unlock_irqrestore(&xhci->lock,
                    flags);
                retval = xhci_halt(xhci);
                spin_lock_irqsave(&xhci->lock,
                    flags);

                temp = readl(port_array[wIndex] +
                    PORTPMSC);
                temp &= ~(0xf << 28);
                temp |= selector << 28;
                writel(temp, port_array[wIndex] +
                    PORTPMSC);

                break;
    [...]
}

4 EMC测试
4.1 出问题的RF频点
步长20MHz,380MHz和440Mhz容易出问题。

4.2 EMC干扰后,USB设备断开走的代码路径
- U盘,走hub.c的usb_reset_device();USB设备使用过程中复位与设备第一次连接复位的区别是udev->config非空;获得syspath路径函数kobject_get_path(kobj, GFP_KERNEL)
- USB转以太网,走hub.c的EM interference
- 表现与手工插入、移除一样

4.3 寄存器判断 - xHCI
宏中有大写C(change)的表示描述的是wPortChange。
每次insertion有多次portsc寄存器打印,是因为:
- USB reset前,调用hub_port_debounce()多次轮训portsc寄存器,确认设备连接
- USB reset时,调用hub_port_wait_reset()多次轮训portsc寄存器确认复位是否成功(检查portsc.bit1是否为1,1表示成功,否则失败)

wPortStatus(对应到xHCI portsc.bit0 - portsc.bit15):
bit0 - 有无设备连接,portsc.bit0
bit1 - 端口是否使能,portsc.bit1
bit4 - 端口是否有复位信号,portsc.bit4
bit8 - 端口电源,portsc.bit9,for USB2
bit8...bit5 - PORT_LINK_STATE,portsc.bit8...portsc.bit5,for USB3
wPortChange(对应到xHCI portsc.bit17 - portsc.bit31):
bit0 - 端口连接改变位,portsc.bit17
bit1- 端口使能/禁止改变位,portsc.bit18

5 电源管理
5.1 全局禁止运行时autosuspend
echo -1 >
/sys/module/usbcore/parameters/autosuspend

5.2 xHCI autosuspend
Intel APL (Gen9, A39X0) 8-port MPH xHCI会注册2个host,一个是usb1(LS/FS/HS),另一个是usb2(SS)。
禁止usb1电源管理:
echo on >
/sys/bus/usb/devices/usb1/power/control
禁止usb2电源管理:
echo on >
/sys/bus/usb/devices/usb2/power/control

6 ACPI
6.1 iasl_win
cat /sys/firmware/acpi/tables/DSDT > DSDT.aml
sudo apt-get install iasl
iasl -d DSDT.aml
cat DSDT.dsl

6.2 URLs
WINDOWS BINARY TOOLS
https://www.acpica.org/downloads/binary-tools

7 ARM xHCI
7.1 Faraday Technology
[29th-Mar-2022]
Faraday Technology provides USB 2.0 and xHCI controller IP.
IP Memory provides DDR PHY IP.

7.2 28nm iMX 8QuadMax MEK
iMX 8QuadMax was released in Q1, 2017.
MEK: Multisensory Enablement Kit
SABRESD: NXP Smart Application Blueprint for Rapid Engineering Smart Device
USBOTG1: 0x5b0d_0000, Chipidea
USBH1: 0x5b0e_0000, Chipidea Host HSIC
USBOTG3: 0x5b11_0000, Cadence xHCI, connected to PTN5110

7.3 28nm MT2712
MT2712 was released in 2017.
MT2712包含2个MPH xHCI,每个xHCI包含2个port,一个3.0口和一个2.0口。其中3.0口通过外接Richtek的PD控制器RT1711H(支持TCPCI规范)后,可以支持USB Type-C;而2.0口支持OTG。

echo device >
/sys/kernel/debug/usb/11271000.usb/mode

ESIT: INT/ISO Endpoint Service Interval Time, = max_packet_size x num_of_burst

7.4 Nvidia 12nm Xavier
4-port MPH, 3 ports support SuperSpeed, it integrated Falcon controller.
2-port CYPD4226-40LQXIT
bus-port.port.port...

Tegra186 4-port MPH xHCI port3 connected to Microchip MOST OS81118 in Daimler NTG6 head unit.
Tegra30 was based on 40nm process technology, and released on November 9th, 2011. It integrated 3 Chipidea SPH EHCI.

7.5 qcom 7nm SA8155
7.5.1 Gen3 Cockpit
DWC_usb3_databook_2.50a.pdf
SA8155 and SA8195 are the Gen3 Cockpit SoC.
SA8295 is the Gen4 Cockpit SoC.

SA8155 includes 2 SPH dwc3 xHCI, it was based on 855 SM8150, and released in 2019.
SA8195 includes 4 SPH dwc3 xHCI. USB0 and USB1 support high speed, USB2 and USB3 support super speed.

USB3 QMP SerDes offset: 0x1000
DP SerDes offset: 0x2000

overlay.dtbo-base: to be overlaid dtb
dts-dirs += $(DEVELOP_PRODUCT)

/sys/devices/platform/soc/a600000.ssusb/mode
echo "file dwc3-msm.c +p" >
/sys/kernel/debug/dynamic_debug/control

CONFIG_STRICT_DEVMEM
CONFIG_DEVMEM
drivers/char/mem.c
busybox hexdump -C /proc/device-tree/xxx/reg
echo on >
/sys/bus/usb/devices/usb1/power/control
busybox devmem 0xa6f8858 32

7.5.2 8cx
8cx means 8 Compute eXtreme. SC8280XP dwc3-msm.c uses qcom,dual-port to implement 2-port MPH xHCI.

7.6 Raspberry Pi
Raspberry Pi 4B uses VL805 xHCI.
Raspberry Pi 5 uses RP1 chipset to implement v3.30b dwc_usb3 xHCI.

7.7 Samsung 8nm EA9
EA9 includes 4 SPH dwc3_v3.20a xHCI, controller 0 and 1 support Super-speed, controller 2 and 3 support High-speed. EA9 was released in 2017. EA9 uses 36bit physical memory address bus.
USB0: 0x1720_0000
USB1: 0x1730_0000
USB2: 0x1740_0000
USB3: 0x1750_0000
Synopsys PHY0 Base: 0x171C_0000
Synopsys PHY1 Base: 0x171D_0000
Synopsys PHY2 Base: 0x171E_0000
Synopsys PHY3 Base: 0x171F_0000
LTSTATE_HIS: offset 0x0014, USB30 Link Training History Register. 5 history state, each history has a 4-bit field recording one of 16 LTSSM training state.

7.8 VMware Ubuntu xHCI
bus 1: EHCI
bus 2: OHCI
bus 3: 4-port xHCI high-speed
bus 4: 4-port xHCI super-speed
And USB flash drive is attached to bus 4 port1.

8 URLs
[RFC v2 00/22] USB 3.0 hub support & xHCI split roothub for 2.6.38
http://www.spinics.net/lists/linux-usb/msg40949.html

[1/1] usb: Check if port status is equal to RxDetect
https://lore.kernel.org/patchwork/patch/482049/

9 Abbreviations
ARC:Argonant RISC Core
AT91SAM9260:SAM means Smart ARM-based Microcontroller
ATMEL SAMBA:ATMEL Smart ARM-based Microcontroller Boot Assistant
DCI:Direct Connection Interface
DWC2:Design Ware Controller 2,Apple的嵌入式设备,包括iPad和iPhone都是使用的DWC2;DWC技术来至于收购的InSilicon
Falcon:FAst Logic CONtroller。NVIDIA私有的RISC MCU,主要用在桌面GPU(Falcon中的寄存器一般映射到PCI BAR0)或者Tegra xHCI控制器中。NVIDIA正在把私有的Falcon MCU架构换成RISC-V
HSIO:x86 High-Speed Input/Output
ISP1161:Philips' Integrated host Solution Pairs 1161,“Firms introduce USB host controllers”,https://www.eetimes.com/document.asp?doc_id=1290054
MPH:USB Multi-Port Host,Intel的MPH的Port1作为OTG使用,和DWC3(仅作为slave)使用一个MUX开关来控制Host还是UDC连接到该Port1
MTU3 ippc:MTK USB3 IP Port Control
PAM-4:每个符号表示2个bit,眼图有3个眼睛;而NRZ眼图只有一个眼睛
SL811HS:Cypress/ScanLogic 811 Host/Slave,性能上与ISP1161(Integrated host Solution Pairs 1161)相当
SOM: Intel Atom Processor System on Module
SPH:USB Single-Port Host
TDI:TransDimension Inc.,该公司首先发明了将TT集成到EHCI RootHub中的方法,这样对于嵌入式系统来说,就省去了OHCI/UHCI的硬件,同时降低了成本,作为对该公司的纪念,Linux内核定义了宏ehci_is_TDI(ehci);产品UHC124表示USB Host Controller;收购了ARC USB技术;现已被chipidea收购,chipidea又被mips收购
TT:Transaction Translator(事务转换器,将USB2.0的包转换成USB1.1的包)
U0:USB SS link is Up
USB BH reset:Bigger Hammer or Brad Hosler,表示warm reset;you may be confused why the USB 3.0 spec calls the same type of reset "warm reset" in some places and "BH reset" in other places. "BH" reset is supposed to stand for "Big Hammer" reset, but it also stands for "Brad Hosler". Brad died shortly after the USB 3.0 bus specification was started, and they decided to name the reset after him. The suggestion was made shortly before the spec was finalized, so the wording is a bit inconsistent.
USB overhead:开销,包头包尾等由协议层而不是应用层添加的字节,也就是说,一个USB包中除了payload之外的附加字节(Token、ACK、CRC等)都叫overhead
xECP:xHCI Extended Capabilities Pointer
XUSB2PR: Intel xHC USB 2.0 Port Routing Register