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()函数。
1.2 x86 OTG架构
xHCI和dwc3组成一个PCI多功能设备,xHCI的func号为0,dwc3的func号为1。由于PCI总线一般只有INTA#到INTD#的4个中断引脚,所以PCI多功能设备的func一般不会超过4个,但是共享中断除外。
1.3 Doorbell机制
发送方把消息放入信箱,按一下门铃,产生中断通知接收方,接收方读到消息在共享寄存器做个标记,表示信息接收了。
1.4 usb_hc_died
usb_hc_died() -> 需要重启电脑才能恢复
[v2] usb/hcd: Send a uevent signaling that the host controller has died
https://patchwork.kernel.org/patch/10896705/
2 PIPE PHY
2.1 PIPE PHY数据线宽度
USB 3.0 PIPE PHY的数据线宽度是可以设置的,最大宽度分别是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对应一个方波)。
2.2 xHCI带宽计算
- Average TRB Length - 只有NEC chip支持这个feature
[24/98] USB: xhci: properly set endpoint context fields for periodic eps.
http://lkml.iu.edu/hypermail/linux/kernel/1005.1/00848.html
2.3 SerDes - CML
- CML:Current Mode Logic
- 速度高于2.5Gbps的串行接口电路一般都用CML
- 恒流源16mA
- 使用总线:PCIe、USB SS(1000mV peak-to-peak)和千兆以太网(PHYless)
- USB SS TX+/-上加AC耦合电容,是为了隔离RX+/-端的直流偏置对发送端的影响
- USB SS眼图调试就是调整SerDes寄存器(QCOM)
- CML通过外接电阻做电平转换后兼容LVDS
- 百兆以太网4b/5b编码,千兆以太网8b/10b编码,万兆以太网64b/66b编码
- 支持SGMII模式的MAC中包含了PCS和SerDes模块(GMII接口的MAC只有PHY才包含PCS和PMA模块),SGMII中的S表示使用了SerDes传输数据,此时SerDes发送的10b数据ENC_TXD[0:9]表示TX_ER、TX_EN和TXD[0:7];接收的10b数据ENC_RXD[0:9]表示RX_ER、RX_DV和RXD[0:7];而SerDes模式时传输的是PCS 8b/10b编码后的数据
- SerDes发送端驱动器其实就是一个DAC(数字-模拟转化器),而接收器的模拟前端就是一个ADC(模拟-数字转化器)。当然,比较特殊的是,对于传输“0”和“1”电平的SerDes系统而言,这里的“DAC”和“ADC”有效位都只有1比特。此外,与传统AD/DA的差别在于,为了补偿信道的影响,SerDes中的“DAC”和“ADC”通常具有均衡能力
- PHY loopback测试是在PCS子层,不是在SerDes层
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每个port有包含PORTSC在内的4个寄存器
@ 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 电源管理
4.1 全局禁止运行时autosuspend
echo -1 > /sys/module/usbcore/parameters/autosuspend
4.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
5 EMC测试
5.1 出问题的RF频点
步长20MHz,380MHz和440Mhz容易出问题。
5.2 EMC干扰后,USB设备断开走的代码路径
- U盘,走hub.c的usb_reset_device();USB设备使用过程中复位与设备第一次连接复位的区别是udev->config非空;获得syspath路径函数kobject_get_path(kobj, GFP_KERNEL)
- USB转以太网,走hub.c的EM interference
- 表现与手工插入、移除一样
5.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
6 Bulk传输速度计算
- Full-speed
每个frame最大可以传输19个Bulk包,每个Bulk包最大是64Bytes,所以其最大传输速率是:64 x 19 x 1000 = 1.16MB/s。
- High-speed
USB 2.0在每个微帧中最大可传输13个Bulk包,每个Bulk包最大是512Bytes,而每个微帧长固定为125μs,所以其最大传输速率为:512 x 13 x 8 x 1000 = 53MB/s。
7 ACPI
7.1 iasl_win
cat /sys/firmware/acpi/tables/DSDT > DSDT.aml
sudo apt-get install iasl
iasl -d DSDT.aml
cat DSDT.dsl
7.2 URLs
WINDOWS BINARY TOOLS
https://www.acpica.org/downloads/binary-tools
8 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。
9 URLs
The USB 3.0 link training by example: From LFPS bursts to link commands
http://xillybus.com/tutorials/usb3.0-training-by-example
[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/
10 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
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
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)相当
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收购
PAM-4:每个符号表示2个bit,眼图有3个眼睛;而NRZ眼图只有一个眼睛
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
HSIO:x86 High-Speed Input/Output