USB xHCI控制器使用总结
1 Intel USB xHCI控制器
1.1 驱动架构
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 x86 OTG架构
寄存器地址:PCI_BAR0 + 80D8h
xHCI和dwc3组成一个PCI多功能设备,xHCI的func号为0,dwc3的func号为1。由于PCI总线一般只有INTA#到INTD#的4个中断引脚,所以PCI多功能设备的func一般不会超过4个,但是共享中断除外。
/sys/bus/platform/drivers/intel_usb_dr_phy/intel_usb_dr_phy.0/mux_state
1.3 x86 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 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.5 x86 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.6 reset USB device
echo 0 >
/sys/bus/usb/devices/whatever/authorized
echo 1 >
/sys/bus/usb/devices/whatever/authorized
1.7 PIPE PHY数据线宽度
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 * 4bytes或者256MHz * 2bytes)。
USB 3.0 Gen1的速度5Gbps(625MB/s),协议开销(overhead)占用了20%带宽,所以实际有效速度是500MB/s。
USB 3.0 TX或者RX的传输速率虽然是5Gbps,但实际上数字信号的方波频率是2.5GHz(传输2个bit对应一个方波)。
Intel平台xHCI的物理层名字是ModPHY(High Speed I/O Modular Physical Layer for Intel USB 3.0)。
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 xHCI HS眼图调试
3.1 EHCI眼图调试寄存器设置流程
第一步:把寄存器USBCMD的bit4和bit5设成0
第二步:把寄存器USBCMD的bit0和bit6设成0
第三步:
- 对应的USB port的PORTSC,port suspend(bit7)设置成0
- 然后把测试模式selector(取值范围:>0,<5,这个数字对应眼图夹具上的那个开关的拨弄的编号)写到PORTSC中(selector << 16)
3.2 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.3 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)Intel xHCI HS不支持修改DC level(400mV)
3.4 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
一个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 MT2712 USB xHCI控制器
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.2 qcom xHCI
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
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
CC2530:TI ChipCon2530
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眼图只有一个眼睛
Quirks:the attributes of a device that are considered to be noncompliant with expected operation
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收购
TLV:TI Low Value,高性价比
TPS:TI Performance Solution
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