开发板 :NanoPC-T6
开发板eMMC
:256GB
LPDDR4
:16GB
显示屏 :15.6
英寸HDMI
接口显示屏u-boot
:2017.09
linux
:6.1
----------------------------------------------------------------------------------------------------------------------------
有关USB
的发展历史,以及接口规范这一节我们就不再重复介绍了,没有相关基础的话可以参考我之前写过的文章:
- 《
linux
驱动移植-usb
驱动基础》; - 《
Rockchip RK3399 - USB
基础》;
一、RK3588 USB
介绍
1.1 USB
控制器
RK3588
支持4个独立的USB
控制器,不同控制器相互独立:
- 两个
USB2.0 HOST
(EHCI
&OHCI
); - 两个
USB3.0 OTG
(DWC3/xHCI
); - 一个
USB3.0 HOST
(xHCI
);只支持USB3.0
功能,不向下兼容USB2.0
;
其中:
EHCI/OHCI
: 表示该USB
控制器集成了EHCI
控制器和OHCI
控制器;DWC3/xHCI
:表示该USB
控制器集成了DWC3
控制器和xHCI
控制器;USB3.0
物理层传输速率为5Gbps
,USB2.0
物理层传输速率为480Mbps
;
1.1.1 USB2.0 HOST
(EHCI
/OHCI
)
支持高速 (480Mbps
),全速 (12Mbps
) 和低速 (1.5Mbps
),USB2.0 Host
控制器的框图如下图所示;
内部有EHCI
和OHCI
Host Controller
:
OHCI
支持USB1.0
和USB1.1
;EHCI
支持USB2.0
;
Port Routing Control
: 用于选择用EHCI
还是OHCI
。
USB2.0 Host
控制器连接到USB2.0 PHY
。
EHCI
和OHCI Rockchip
采用linux
内核Generic
驱动,一般开发时只需要对设备树作相应配置,即可正常工作。
为了同时支持USB1.0
、USB1.1
和USB2.0
,就需要同时用到EHCI
和OHCI
,因此需要在设备树中把这两个USB
控制器都打开,如:
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
}
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
这样配置之后,RK3588
的两个USB2.0 HOST
控制器就使能了,并且同时支持EHCI
和OHCI
。
1.1.2 USB3.0 OTG
(DWC3
/xHCI
)
RK3588 USB3.0 OTG
使用Synopsys
方案,即xHCI
扩展的DWC3
控制器,Host
功能在xHCI
框架下实现,而Device
功能由DWC3
扩展部分实现。
DWC3
具有以下特性:
- 支持
Control
/Bulk
(including stream
)/Interrupt
/Isochronous
传输方式; USB3.0
支持同时执行IN
和OUT
传输,带宽达到8Gbps
;- 支持描述符缓存 (
Descriptor Caching
) 和数据预取 (Data Pre-fetching
); Device
模式支持的IN
端点数量和OUT
端点数量请参考芯片手册;- 支持硬件自动处理
ERDY
和burst
; - 支持端点批量流传输 (
bulk stream
); - 支持
USB3.0 DRD
(Dual-Role Device
) 特性; - 支持根据
OTG ID
状态切换Device
和Host
模式; - 对于支持
Type-C
的芯片,支持UFP/DFP
角色交换; - 不支持
SRP
(session request protocol
),HNP
(hostnegotiation protocol
)和RSP
(Role Swap Protocol
);
USB3.0 xHCI Host
特性:
- 最多可以连接
64
个外设; - 支持一个中断器;
- 支持一个
USB2.0
端口和一个USB3.0
端口; - 支持
USB3.0/USB2.0
并发传输,带宽达到8Gbps
; - 支持标准和开源的
xHCI
驱动; - 部分芯片支持
xHCI Debug Capability
;
USB3.0 OTG
控制器的框图如下图所示;
USB3.0 OTG
具有USB3.0 OTG
(USB Peripheral
和USB Host
)功能,且向下兼容USB2.0 OTG
功能,大传输速率为5Gbps
。
由于USB3.0 HOST
控制器为xHCI
,集成于DWC3 OTG IP
中,所以不用单独为其配置设备树,只需要配置DWC3
,并且设置DWC3
的dr_mode
属性为dr_mode
= otg
或者dr_mode
= host
,即可以使能xHCI
控制器。
1.1.3 USB3.0 HOST
(xHCI
)
USB3.0 HOST
控制器只支持USB3.0
功能,无法支持USB2.0
(因为没有带USB2.0 PHY
)。因此,USB3.0 HOST
需要与USB2.0 HOST
控制器组合,以支持完整的USB3.0
协议功能。
1.2 USB PHY
RK3588
支持7个独立的USB PHY
:
- 4个
USB2.0 PHY
:在设备树中分别叫做u2phy0
、u2phy1
、u2phy2
、u2phy3
; - 2个
USB3.0/DP Combo PHY
:在设备树中分别叫做usbdp_phy0
和usbdp_phy1
; - 1 个
USB3.0/SATA/PCIe Combo PHY
:在设备树中叫做combphy2_psu
;
其中:
USB3.0/DP Combo PHY
支持4 x lanes
,可以同时支持USB3.0 + DP 2 x lanes
;USB3.0/SATA/PCIe Combo PHY
在同一时刻,只能支持一种工作模式,也即USB3.0
与SATA/PCIe
接口是互斥的;
Rockchip
采⽤的USB PHY
主要有如下几种:
USB2.0 PHY
[Vendor: Innosilicon
];RK3588
使用的4个USB2.0 PHY
正是采用这个;USB2.0 PHY
[Vendor: Synopsys
];Synopsys USB2.0 PHY
只⽤于较早的⼏款芯⽚(RK3066
/RK3188
/RK3288
),当前的主流芯⽚和后续的芯⽚USB2.0 PHY
都是采⽤Innosilicon
提供的IP
;USB3.0 PHY
[Vendor: Innosilicon
];Inno USB3.0 PHY
只⽀持Super-speed
,没有向下兼容High-Speed
,所以需要和Inno USB2.0 PHY
组成⼀个Combo PHY
;RK3588
使用的2个USB3.0/DP Combo PHY
正是采用这个;USB3.0 PHY
[Vendor: naneng
]:RK3588
使用的USB3.0/SATA/PCIe Combo PHY
正是采用这个;Type-C PHY
[Vendor: Cadence
]。
1.2.1 USB2.0 PHY
USB2.0 PHY
支持1个port
和2个port
两种设计,如下图是支持2个port
的框图;
Host Port
:通过UTMI+
连接到USB2.0 Host
控制器;
OTG Port
:通过UTMI+
连接USB3.0/2.0 OTG
控制器的USB2.0
逻辑模块;
以RK3588
为例,使用的4个USB2.0 PHY
均是采用Innosilicon IP
,每个USB2.0 PHY
都只有1个port
端口;
u2phy0
:包含u2phy0_otg
;u2phy1
:包含u2phy1_otg
;u2phy2
:包含u2phy2_host
;u2phy3
:包含u2phy3_host
;
1.2.2 USB3.0/DP Combo PHY
RK3588
使用的2个 USB3.0/DP Combo PHY
均是采用Innosilicon IP
。Inno USB3.0 PHY
只⽀持Super-speed
,没有向下兼容High-Speed
,所以需要和Inno USB2.0 PHY
组成⼀个Combo PHY
。如下图是⼀个典型的USB3.0 OTG
控制器架构图;
注意:图中由下方的USB3.0 PHY
可以看做是个 USB3.0/DP Combo PHY
。
1.2.3 USB3.0/SATA/PCIe Combo PHY
RK3588
使用的 USB3.0/SATA/PCIe Combo PHY
采用NaNeng IP
。只能支持USB3.0
,不向下兼容USB2.0
。并且,在芯片内部设计时,没有与USB2.0 PHY
组合。
1.3 USB
控制器和USB PHY
关系
1.3.1 连接示意
RK3588 USB
控制器和USB PHY
的连接示意图如下:
USB 接口类型(仅仅示例,接口类型可调整) | USB 控制器 | USB PHY |
---|---|---|
USB3.0 Type-C0 | USB3.0 OTG0 (DWC3&xHCI) | USB3.0/DP Combo PHY0 + USB2.0 PHY0 |
USB3.0 Type-C1 | USB3.0 OTG1 (DWC3&xHCI) | USB3.0/DP Combo PHY1 + USB2.0 PHY1 |
USB2.0 HOST0 Type-A | USB2.0 HOST0(EHCI&OHCI) | USB2.0 PHY2 |
USB2.0 HOST1 Type-A | USB2.0 HOST1(EHCI&OHCI) | USB2.0 PHY3 |
USB3.0 HOST2 Type-A | USB3.0 HOST2 (xHCI) | USB3.0/SATA/PCIe Combo PHY2 |
可视化如下:
由图可以看出,RK3588
最多可以同时支持2个全功能的USB3.0 Type-C
接口,2个USB2.0 Type-A
接口,1 个 USB3.0 Type-A
接口(不向下兼容USB2.0
);
USB3.0 OTG
控制器 与DP
控制器复用USB3.1/DP Combo PHY
,可组成全功能的Type-C
接口,也可以拆分独立使用(如:常见的USB3.0 Type-A
接口 +DP
接口[2 x lanes
]);USB3.0/DP Combo PHY
只能支持USB3.0
,不向下兼容USB2.0
。所以,它们在芯片内部设计时,实际是与USB2.0 PHY
组合,以支持完整的USB3.0
协议功能。其中:USB3.0/DP Combo PHY0
固定与USB2 PHY0
组合;USB3.0/DP Combo PHY1
固定与USB2 PHY1
组合;
USB3.0 HOST2
控制器只支持USB3.0
功能,无法支持USB2.0
(因为没有带USB2.0 PHY
)。可以将USB3.0 HOST2
与USB2.0 HOST0
或USB2.0 HOST1
组合,作为一个完整的USB3.0 Type-A
接口;USB3.0/SATA/PCIe Combo PHY
只能支持USB3.0
,不向下兼容USB2.0
。并且,在芯片内部设计时,没有与USB2.0 PHY
组合。因此,USB3.0 HOST2
需要与USB2.0 HOST0/1
接口(二选一)组合,以支持完整的USB3.0
协议功能;
需要注意的是,RK3588 USB
支持的接口类型并不局限于图中所描述的USB Type-C/A
接口类型,而是可以支持所有常见的USB
接口,包括USB2.0/3.0 Type-C
,USB2.0/3.0 Type-A
,Micro USB2.0/3.0
等,具体信息请参考RK3588 USB
支持的接口类型。
为了适配不同的USB
电路设计和接口类型,Linux
内核USB
驱动已经做了软件兼容,开发者只需要根据产品的USB
硬件电路,对Linux USB DTS
进行正确配置,即可使能对应的USB
接口功能。
1.3.2 引脚定义
RK3588 USB
控制器和芯片端USB
传输数据的pin
脚的对应关系如下表所示:
USB控制器/Pin脚 | RK3588 USB data pin |
---|---|
USB2.0 HOST0 | USB20_HOST0_DP/USB20_HOST0_DM |
USB2.0 HOST1 | USB20_HOST1_DP/USB20_HOST1_DM |
USB3.0 OTG0 | TYPEC0_USB20_OTG_DP/TYPEC0_USB20_OTG_DM, TYPEC0_SSRX1P/TYPEC0_SSRX1N, TYPEC0_SSTX1P/TYPEC0_SSTX1N, TYPEC0_SSRX2P/TYPEC0_SSRX2N, TYPEC0_SSTX2P/TYPEC0_SSTX2N |
USB3.0 OTG1 | TYPEC1_USB20_OTG_DP/TYPEC1_USB20_OTG_DM, TYPEC1_SSRX1P/TYPEC1_SSRX1N, TYPEC1_SSTX1P/TYPEC1_SSTX1N TYPEC1_SSRX2P/TYPEC1_SSRX2N, TYPEC1_SSTX2P/TYPEC1_SSTX2N |
USB3.0 HOST2 | USB30_2_SSTXP/USB30_2_SSTXN USB30_2_SSRXP/USB30_2_SSRXN |
二、硬件原理图
这里我使用的开发板型号是NanoPC-T6
,开发板如下图所示;
USB
资源如下:
-
USB-C/DP
: 一个全功能USB3.0 Type‑C
接口, 支持USB3.0
数据传输和DP
显示输出,分辨率高达4Kp60
; -
USB3.0:
一个USB3.0 Type-A
;
2.1 USB3.0 Type‑C
我们使用的开发板NanpiPC-T6
,USB3.0/DP Combo PHY0
与USB2 PHY0
物理接口被设计为USB3.0 Type-C
,如下图所示:
友善的这块电路实际上是参考Rockchip
官方的Type-C USB3.0/DP
全功能硬件电路。
需要注意的是这里TYPEC0_USB20_VBUSDET
引脚是连接到VCCA_3V3_S0
。至于为啥这么设计,官方给出了说明:
- 为了支持高压充电功能,同时降低硬件电路的风险,
TYPEC0_USB20_VBUSDET
不要连接Type-C
接口的VBUS
,固定上拉到3.3V
即可(TYPEC0_USB20_VBUSDET
连接到VCCA_3V3_S0
),但不能悬空; - 当
Type-C0
设计为支持PD
功能的Type-C
接口时,即支持外置Type-C
控制器芯片(如:FUSB302
或者HUSB311
),则TYPEC0_USB20_VBUSDET
固定上拉到VCCA_3V3_S0
,软件驱动可以通过Type-C
控制器芯片的CC
检测USB Device
的连接和
断开;
2.1.1 电源接线
上图中供电依次为VDDA_0V85_S0
、VCCA_1V8_S0
、VDDA_0V75_S0
、VCCA_3V3_S0
,这些电源均是由电源芯片RK806
输出。
(1) 电源VDDA_0V85_S0
由RK806
第10号引脚提供的;
(2) 电源VCCA_1V8_S0
由RK806
第60号引脚提供的;
(3) 电源VDDA_0V75_S0
由RK806
第11号引脚提供的;
(4) 电源VCCA_3V3_S0
由RK806
第63号引脚提供的。
2.1.2 Type-C
接口接线
其中TYPEC0_SSTX1P
、TYPEC0_SSTX1N
、TYPEC0_SSRX1P
、TYPEC0_SSRX1N
、TYPEC0_SSTX2P
、TYPEC0_SSTX2N
、TYPEC0_SSRX2P
、TYPEC0_SSRX2N
、TYPEC0_SBU1
、TYPEC0_SBU2
、TYPEC0_USB20_OTG_DM
、TYPEC0_USB20_OTG_DP
连接到开发板上的TYPE-C
,TYPE-C
为USB3.0 Type-C
接口;
RK3588 | USB3.0/DP Combo PHY0 | USB2.0 PHY0 | USB3.0 Type-C |
---|---|---|---|
TYPEC0_SSTX1P/DP0_TX1P | TYPEC0_SSTX1P | SSTX1_P | |
TYPEC0_SSTX1N/DP0_TX1N | TYPEC0_SSTX1N | SSTX1_N | |
TYPEC0_SSRX1P/DP0_TX0P | TYPEC0_SSRX1P | SSRX1_P | |
TYPEC0_SSRX1N/DP0_TX0N | TYPEC0_SSRX1N | SSRX1_N | |
TYPEC0_SSTX2P/DP0_TX3P | TYPEC0_SSTX2P | SSTX2_P | |
TYPEC0_SSTX2N/DP0_TX3N | TYPEC0_SSTX2N | SSTX2_N | |
TYPEC0_SSRX2P/DP0_TX2P | TYPEC0_SSRX2P | SSRX2_P | |
TYPEC0_SSRX2N/DP0_TX2N | TYPEC0_SSRX2N | SSRX2_N | |
TYPEC0_SBU1/DP0_AUXP | TYPEC0_SBU1 | SBU1 | |
TYPEC0_SBU2/DP0_AUXN | TYPEC0_SBU2 | SBU2 | |
GPIO4_A6 | TYPEC0_SBU1_DC | SBU1 | |
GPIO4_A7 | TYPEC0_SBU2_DC | SBU2 | |
TYPEC0_USB20_OTG_DM | TYPEC0_OTG_DM | D- | |
TYPEC0_USB20_OTG_DP | TYPEC0_OTG_DP | D+ | |
TYPEC0_USB20_OTG_DM | TYPEC0_OTG_DM | DM | |
TYPEC0_USB20_OTG_DP | TYPEC0_OTG_DP | DP | |
USB20_AVDD_3V3 | TYPEC0_USB20_VBUSDET | ||
TYPEC_CC1 | |||
TYPEC_CC2 |
如下图所示:
电源VBUS5V0_TYPEC
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由TYPEC5V_PWREN_H
(GPIO1_D2
)引脚使能;
2.1.3 fusb302
fusb302
是可编程的USB Type-C
控制器,支持识别各种USB
设备和对应的工作状态,且支持最高100W
的PD
协议。
其具有一下主要特征:
- 具备自主
DRP
切换的双重角色功能; - 根据已连接的设备选择作为
Host
(主机)或Device
(设备)进行连接; - 通过软件配置为
Host
(主机)、Device
(设备)或双重角色; - 支持
USB
功率传递(PD
)2.0:
其引脚如下:
引脚 | 类型 | 功能 |
---|---|---|
CC1/CC2 | I/O | Type-C连接器的配置通道(CC)引脚。最初用于确定插入事件发生以及插入的方向。连接后的功能取决于检测到的操作模式。 作为主机运行时: 1)设置可被连接设备感知的VBUS的允许充电电流; 2)用于与使用USB BMC Power Delivery的设备进行通信; 3)用于检测已发生的拔出事件 作为设备运行时: 4)指示来自连接的主机的允许下沉电流。用于与使用USB BMC Power Delivery的设备进行通信主要用来 PD协议通信或其他: |
VBUS | Input | 当作为面向上行端口(设备)运行时,该引脚可用于设备插入和拔出的检测。 |
VCONN | Power Switch | 要将调节输入电源切换到正确的CC引脚作为VCONN以为USB3.1完整功能电缆和其他配件供电。 |
INIT | Open-Drain Output | 中断输出,当有事件发生时,用于通知处理器读取I2C寄存器数据。如:插入/拔出typeC,INIT_N都会拉低一下。 |
SCL | Input | I2C时钟 |
SDA | Open-Drain I/O | I2C数据引脚 |
INT
连接的是RK3588
的GPIO0_D3
引脚,I2C
通信使用的是I2C6
。
由于这篇文章不是fusb302
的专栏,所以就不细说了,具体参考《PD
快充 - fusb302
驱动调试笔记》。
2.2 USB3.0 Type-A
我们使用的开发板NanpiPC-T6
,USB3.0/DP Combo PHY1
与USB2 PHY1
物理接口被设计为USB3.0 Type-A
,如下图所示:
友善的这块电路实际上是参考Rockchip
官方的Type-C to Type-A USB 3.1/DP
硬件电路。
需要注意的是这里TYPEC1_USB20_VBUSDET
引脚是悬空的,至于为啥这么设计,官方给出了说明:
- 如果
USB OTG
有作Device/HOST
的应用场景,建议TYPEC0_OTG_VBUSDET
通过30KΩ
的电阻串联到USB Type-A
接口的VBUS
; - 然而友善这里将
TYPEC1_USB20_VBUSDET
引脚悬空处理,USB Type-A
接口大概率只能作为HOST mode
使用。
2.2.1 Type-A
接口接线
其中TYPEC1_SSTX1P
、TYPEC1_SSTX1N
、TYPEC1_SSRX1P
、TYPEC1_SSRX1N
、TYPEC1_USB20_OTG_DM
、TYPEC1_USB20_OTG_DP
连接到USB3
,USB3
为USB3.0 Type-A
接口;
RK3588 | USB3.0 Type-C PHY1 | USB2.0 PHY1 | USB3.0 Type-A |
---|---|---|---|
TYPEC1_SSTX1P/DP1_TX1P | TYPEC1_SSTX1P | TX+ | |
TYPEC1_SSTX1N/DP1_TX1N | TYPEC1_SSTX1N | TX- | |
TYPEC1_SSRX1P/DP1_TX0P | TYPEC1_SSRX1P | RX+ | |
TYPEC1_SSRX1N/DP1_TX0N | TYPEC1_SSRX1N | RX- | |
TYPEC1_USB20_OTG_DM | TYPEC1_OTG_DM | D- | |
TYPEC1_USB20_OTG_DP | TYPEC1_OTG_DP | D+ |
如下图所示:
电源VCC5V0_USB30_HOST2
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由USB_HOST_PWREN_H
(GPIO4_B0
)引脚使能。
当USB3.0 OTG
控制器工作在Device mode
,关闭VBUS
输出。当USB3.0 OTG
控制器工作在HOST mode
,打开VBUS
输出。此外,稳压芯片SY6280AAC
的输出电流由OCB pin
连接的电阻决定,最大电流Ilim(A)=6800/Rset(ohm)
,VBUS
输出限流为1A
.
三、设备树
设备树配置参考文档:
Documentation/devicetree/bindings/usb/snps,dwc3.yaml
;Documentation/devicetree/bindings/usb/generic-ohci.yaml
;Documentation/devicetree/bindings/usb/generic-ehci.yaml
;Documentation/devicetree/bindings/connector/usb-connector.yaml
;Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
;Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
;Documentation/devicetree/bindings/phy/phy/phy-rockchip-naneng-combphy.txt
;
RK3588 USB
接口和USB dts
节点的对应关系:
USB 接口类型(仅仅示例) | USB控制器DTS 节点 | USB PHY DTS 节点 |
---|---|---|
USB3.0 Type-C0 对应开发板上标号为USB-C/DP的接口 |
USB3.0 OTG0 (DWC3&xHCI) - usbdrd3_0 - usbdrd_dwc3_0 |
USB3.0/DP Combo PHY0 + USB2.0 PHY0 - u2phy0 - u2phy0_otg - usbdp_phy0 - usbdp_phy0_u3 |
USB3.0 Type-C1 对应开发板上标号为USB3.0的接口,只不过接口类型被做成了Type-A |
USB3.0 OTG1 (DWC3&xHCI) - usbdrd3_1 - usbdrd_dwc3_1 |
USB3.0/DP Combo PHY1 + USB2.0 PHY1 - u2phy1 - u2phy1_otg - usbdp_phy1 - usbdp_phy1_u3 |
USB2.0 HOST0 Type-A | USB2.0 HOST0(EHCI&OHCI) - usb_host0_ehci - usb_host0_ohci |
USB2.0 PHY2 - u2phy2 - u2phy2_host |
USB2.0 HOST1 Type-A | USB2.0 HOST1(EHCI&OHCI) - usb_host1_ehci - usb_host1_ohci |
USB2.0 PHY3 - u2phy3 - u2phy3_host |
USB3.0 HOST2 Type-A | USB3.0 HOST2 (xHCI) - usbhost3_0 - usbhost_dwc3_0 |
USB3.0/SATA/PCIe Combo PHY2 - combphy2_psu |
3.1 NaniPC-T6
设备树
在《Rockchip RK3588
- 移植uboot 2017.09 & linux 6.1
(友善之家脚本方式)》我们介绍了友善内核编译过程,在arch/arm64/Makefile
文件指定了如何生成resource.img
文件。
DTBS := rk3*-nanopi*-rev*.dtb
# 调用scripts/mkimg编译生成resource.img(由设备树、图片资源文件组成,不包含内核)
nanopi4-images: dtbs kernel.img $(LOGO) $(LOGO_KERNEL)
$(Q)$(srctree)/scripts/mkimg --dtb $(DTBS) --keep-dtb-name
可以看到NaniPC-T6
友善提供的内核源码默认编译使用的设备树文件包括rk3*-nanopi*-rev*.dtb
,对于RK3588
而言具体包含以下文件:
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/kernel-rk3588# ls arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev*.dtb
arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dtb arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev04.dtb
arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev02.dtb arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev05.dtb
arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev03.dtb arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dtb
以rk3588-nanopi6-rev09.dts
为例,文件引入了rk3588.dtsi
以及rk3588-nanopi6-common.dtsi
:
#include "rk3588.dtsi"
#include "rk3588-nanopi6-common.dtsi"
3.2 USB
控制器
USB3.0 OTG0
(DWC3
/xHCI
)、USB2.0 HOST0/1
(EHCI&OHCI
)、USB3.0 HOST2
(xHCI
)的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
USB3.0 OTG1
(DWC3
/xHCI
)的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588.dtsi
,这个文件包含了rk3588s.dtsi
:
因为USB DTSI
节点配置的是USB
控制器和PHY
的公共资源和属性,建议开发者不要改动。
#include "rk3588s.dtsi"
3.2.1 USB2.0 HOST0
(EHCI&OHCI
)
USB2.0 HOST0
控制器设备节点usb_host0_ehci
、usb_host0_ohci
定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb_host0_ehci: usb@fc800000 {
compatible = "rockchip,rk3588-ehci", "generic-ehci";
reg = <0x0 0xfc800000 0x0 0x40000>;
interrupts = ;
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&u2phy2>;
clock-names = "usbhost", "arbiter", "utmi";
companion = <&usb_host0_ohci>;
phys = <&u2phy2_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
usb_host0_ohci: usb@fc840000 {
compatible = "generic-ohci";
reg = <0x0 0xfc840000 0x0 0x40000>;
interrupts = ;
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&u2phy2>;
clock-names = "usbhost", "arbiter", "utmi";
phys = <&u2phy2_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
3.2.2 USB2.0 HOST1
(EHCI&OHCI
)
USB2.0 HOST1
控制器设备节点usb_host1_ehci
、usb_host1_ohci
定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb_host1_ehci: usb@fc880000 {
compatible = "rockchip,rk3588-ehci", "generic-ehci";
reg = <0x0 0xfc880000 0x0 0x40000>;
interrupts = ;
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&u2phy3>;
clock-names = "usbhost", "arbiter", "utmi";
companion = <&usb_host1_ohci>;
phys = <&u2phy3_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
usb_host1_ohci: usb@fc8c0000 {
compatible = "generic-ohci";
reg = <0x0 0xfc8c0000 0x0 0x40000>;
interrupts = ;
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&u2phy3>;
clock-names = "usbhost", "arbiter", "utmi";
phys = <&u2phy3_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
3.2.3 USB3.0 OTG0
(DWC3
/xHCI
)
USB3.0 OTG0(DWC3/xHCI)
控制器设备节点usbdrd3_0
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usbdrd3_0: usbdrd3_0 {
compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
<&cru ACLK_USB3OTG0>;
clock-names = "ref", "suspend", "bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";
usbdrd_dwc3_0: usb@fc000000 {
compatible = "snps,dwc3";
reg = <0x0 0xfc000000 0x0 0x400000>;
interrupts = ;
power-domains = <&power RK3588_PD_USB>;
resets = <&cru SRST_A_USB3OTG0>;
reset-names = "usb3-otg";
dr_mode = "otg";
phys = <&u2phy0_otg>, <&usbdp_phy0_u3>;
phy-names = "usb2-phy", "usb3-phy";
phy_type = "utmi_wide";
snps,dis_enblslpm_quirk;
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
snps,dis-u2-freeclk-exists-quirk;
snps,dis-del-phy-power-chg-quirk;
snps,dis-tx-ipgap-linecheck-quirk;
snps,parkmode-disable-ss-quirk;
quirk-skip-phy-init;
status = "disabled";
};
};
3.2.4 USB3.0 OTG1
(DWC3
/xHCI
)
USB3.0 OTG1(DWC3/xHCI)
控制器设备节点usbdrd3_1
,定义在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
usbdrd3_1: usbdrd3_1 {
compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
<&cru ACLK_USB3OTG1>;
clock-names = "ref", "suspend", "bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";
usbdrd_dwc3_1: usb@fc400000 {
compatible = "snps,dwc3";
reg = <0x0 0xfc400000 0x0 0x400000>;
interrupts = ;
power-domains = <&power RK3588_PD_USB>;
resets = <&cru SRST_A_USB3OTG1>;
reset-names = "usb3-otg";
dr_mode = "host";
phys = <&u2phy1_otg>, <&usbdp_phy1_u3>;
phy-names = "usb2-phy", "usb3-phy";
phy_type = "utmi_wide";
snps,dis_enblslpm_quirk;
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
snps,dis-u2-freeclk-exists-quirk;
snps,dis-del-phy-power-chg-quirk;
snps,dis-tx-ipgap-linecheck-quirk;
snps,parkmode-disable-ss-quirk;
status = "disabled";
};
};
3.2.5 USB3.0 HOST2
(xHCI
)
USB3.0 HOST2(xHCI)
控制器设备节点usbhost3_0
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usbhost3_0: usbhost3_0 {
compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
<&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
<&cru PCLK_PHP_ROOT>, <&cru CLK_PIPEPHY2_PIPE_U3_G>;
clock-names = "ref", "suspend", "bus", "utmi", "php", "pipe";
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";
usbhost_dwc3_0: usb@fcd00000 {
compatible = "snps,dwc3";
reg = <0x0 0xfcd00000 0x0 0x400000>;
interrupts = ;
resets = <&cru SRST_A_USB3OTG2>;
reset-names = "usb3-host";
dr_mode = "host";
phys = <&combphy2_psu PHY_TYPE_USB3>;
phy-names = "usb3-phy";
phy_type = "utmi_wide";
snps,dis_enblslpm_quirk;
snps,dis-u2-freeclk-exists-quirk;
snps,dis-del-phy-power-chg-quirk;
snps,dis-tx-ipgap-linecheck-quirk;
snps,dis_rxdet_inp3_quirk;
snps,parkmode-disable-ss-quirk;
status = "disabled";
};
};
3.2.6 使能
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-common.dtsi
中,使能了:
-
USB2.0 HOST0
(EHCI&OHCI
); -
USB3.0 OTG0(DWC3/xHCI)
; -
USB3.0 HOST2(xHCI)
;
# USB2.0 HOST0(EHCI&OHCI)
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
};
# USB3.0 OTG0(DWC3/xHCI)
&usbdrd3_0 {
status = "okay";
};
# USB3.0 HOST2(xHCI)
&usbhost3_0 {
status = "disabled";
};
而USB2.0 HOST1
(EHCI&OHCI
)、USB3.0 OTG1(DWC3/xHCI)
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
中有使能:
# USB2.0 HOST1(EHCI&OHCI)
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
# USB3.0 OTG1(DWC3/xHCI)
&usbdrd3_1 {
status = "okay";
};
3.3 USB PHY
USB PHY
和USB
控制器具有一一对应的关系,需要成对配置。在芯片内部,USB PHY
和控制器的连接关系,请参考1,3
小节。在dtsi
节点中,通过USB
控制器节点的phys
属性关联对应的USB PHY
。
USB2.0 PHY0/2/3
、USB3.0/DP Combo PHY0
、USB3.0/SATA/PCIe Combo PHY
的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
USB2.0 PHY1
、USB3.0/DP Combo PHY1
的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
3.3.1 USB2.0 PHY0
USB2.0 PHY0
包含1个端口设备节点为u2phy0_otg
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb2phy0_grf: syscon@fd5d0000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5d0000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy0: usb2-phy@0 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0x0 0x10>;
interrupts = ;
resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy0";
#clock-cells = <0>;
rockchip,usbctrl-grf = <&usb_grf>;
status = "disabled";
u2phy0_otg: otg-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.2 USB2.0 PHY1
USB2.0 PHY1
包含1个端口设备节点为u2phy1_otg
,定义在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
usb2phy1_grf: syscon@fd5d4000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5d4000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy1: usb2-phy@4000 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0x4000 0x10>;
interrupts = ;
resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy1";
#clock-cells = <0>;
rockchip,usbctrl-grf = <&usb_grf>;
status = "disabled";
u2phy1_otg: otg-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.3 USB2.0 PHY2
USB2.0 PHY2
包含1个端口设备节点为u2phy2_host
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb2phy2_grf: syscon@fd5d8000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5d8000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy2: usb2-phy@8000 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0x8000 0x10>;
interrupts = ;
resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy2";
#clock-cells = <0>;
status = "disabled";
u2phy2_host: host-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.4 USB2.0 PHY3
USB2.0 PHY3
包含1个端口设备节点为u3phy3_host
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb2phy3_grf: syscon@fd5dc000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5dc000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy3: usb2-phy@c000 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0xc000 0x10>;
interrupts = ;
resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy3";
#clock-cells = <0>;
status = "disabled";
u2phy3_host: host-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.5 USB3.0/DP Combo PHY0
USB3.0/DP Combo PHY0
包含2个端口,对应设备节点分别为usbdp_phy0_dp
、usbdp_phy0_u1
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usbdp_phy0: phy@fed80000 {
compatible = "rockchip,rk3588-usbdp-phy";
reg = <0x0 0xfed80000 0x0 0x10000>;
rockchip,u2phy-grf = <&usb2phy0_grf>;
rockchip,usb-grf = <&usb_grf>;
rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
rockchip,vo-grf = <&vo0_grf>;
clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
<&cru CLK_USBDP_PHY0_IMMORTAL>,
<&cru PCLK_USBDPPHY0>,
<&u2phy0>;
clock-names = "refclk", "immortal", "pclk", "utmi";
resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
<&cru SRST_USBDP_COMBO_PHY0_CMN>,
<&cru SRST_USBDP_COMBO_PHY0_LANE>,
<&cru SRST_USBDP_COMBO_PHY0_PCS>,
<&cru SRST_P_USBDPPHY0>;
reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
status = "disabled";
usbdp_phy0_dp: dp-port {
#phy-cells = <0>;
status = "disabled";
};
usbdp_phy0_u3: u3-port {
#phy-cells = <0>;
status = "disabled";
};
};
3.3.6 USB3.0/DP Combo PHY1
USB3.0/DP Combo PHY1
包含2个端口,对应设备节点分别为usbdp_phy1_dp
、usbdp_phy1_u1
,定义在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
usbdp_phy1: phy@fed90000 {
compatible = "rockchip,rk3588-usbdp-phy";
reg = <0x0 0xfed90000 0x0 0x10000>;
rockchip,u2phy-grf = <&usb2phy1_grf>;
rockchip,usb-grf = <&usb_grf>;
rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
rockchip,vo-grf = <&vo0_grf>;
clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
<&cru CLK_USBDP_PHY1_IMMORTAL>,
<&cru PCLK_USBDPPHY1>,
<&u2phy1>;
clock-names = "refclk", "immortal", "pclk", "utmi";
resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
<&cru SRST_USBDP_COMBO_PHY1_CMN>,
<&cru SRST_USBDP_COMBO_PHY1_LANE>,
<&cru SRST_USBDP_COMBO_PHY1_PCS>,
<&cru SRST_P_USBDPPHY1>;
reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
status = "disabled";
usbdp_phy1_dp: dp-port {
#phy-cells = <0>;
status = "disabled";
};
usbdp_phy1_u3: u3-port {
#phy-cells = <0>;
status = "disabled";
};
};
3.3.7 USB3.0/SATA/PCIe Combo PHY
USB3.0/SATA/PCIe Combo PHY
对应的设备节点为combphy2_psu
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
combphy2_psu: phy@fee20000 {
compatible = "rockchip,rk3588-naneng-combphy";
reg = <0x0 0xfee20000 0x0 0x100>;
#phy-cells = <1>;
clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
<&cru PCLK_PHP_ROOT>;
clock-names = "refclk", "apbclk", "phpclk";
assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
assigned-clock-rates = <100000000>;
resets = <&cru SRST_P_PCIE2_PHY2>, <&cru SRST_REF_PIPE_PHY2>;
reset-names = "combphy-apb", "combphy";
rockchip,pipe-grf = <&php_grf>;
rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
rockchip,pcie1ln-sel-bits = <0x100 1 1 0>;
status = "disabled";
};
3.3.8 使能
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-common.dtsi
中,使能了:
-
USB2.0 PHY0
; -
USB2.0 PHY2
; -
USB3.0/DP Combo PHY0
; -
USB3.0/SATA/PCIe Combo PHY
# USB2.0 PHY0
&u2phy0 {
status = "okay";
};
&u2phy0_otg {
status = "okay";
};
# USB2.0 PHY2
&u2phy2 {
status = "okay";
};
&u2phy2_host {
status = "okay";
};
# USB3.0/DP Combo PHY0
&usbdp_phy0 {
status = "okay";
};
&usbdp_phy0_u3 {
status = "okay";
};
# USB3.0/SATA/PCIe Combo PHY
&combphy2_psu {
status = "okay";
};
而USB2.0 PHY1
、USB2.0 PHY03
、USB3.0/DP Combo PHY1
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
中有使能:
# USB2.0 PHY1
&u2phy1 {
status = "okay";
};
&u2phy1_otg {
phy-supply = <&vcc5v0_host_30>;
status = "okay";
};
# USB2.0 PHY3
&u2phy3 {
status = "okay";
};
&u2phy3_host {
phy-supply = <&vcc3v3_host_32>;
status = "okay";
};
# USB3.0/DP Combo PHY1
&usbdp_phy1 {
status = "okay";
};
&usbdp_phy1_u3 {
status = "okay";
};
3.4 USB3.0 Type-C
NanoPC-T6
开发板支持1个USB3.0 Type-C
接口,对应的USB
控制器为USB3.0 OTG0(DWC3/xHCI)
、对应的USB PHY
为USB3.0/DP Combo PHY0
和USB2 PHY0
;
因此对应的设备树配置,包括USB3.0 OTG0(DWC3/xHCI)
控制器设备树配置和USB3.0/DP Combo PHY0
、USB2 PHY0
设备树配置。
3.4.1 使能usbdrd3_0
通过dr_mode
属性设置USB
控制器的模式,一共有三种模式:otg
(同时支持主机/设备)、host
(主机)、peripheral
(设备),这里配置为otg
;
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
配置:
# USB3.0 OTG0(DWC3/xHCI)
&usbdrd3_0 {
status = "okay";
};
&usbdrd_dwc3_0 {
dr_mode = "otg";
usb-role-switch;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
dwc3_0_role_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_role_sw>;
};
};
};
3.4.2 使能u2phy0_otg
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
配置:
# USB2.0 PHY0
&u2phy0 {
status = "okay";
};
&u2phy0_otg {
status = "okay";
};
3.4.3 使能usbdp_phy0_u3
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
配置:
# USB3.0/DP Combo PHY0
&usbdp_phy0 {
orientation-switch;
rockchip,dp-lane-mux = <0 1 2 3 >;
svid = <0xff01>;
# 根据硬件设计,配置属性"sbu1-dc-gpios"和"sbu2-dc-gpios"
sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
usbdp_phy0_orientation_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_orien_sw>;
};
usbdp_phy0_dp_altmode_mux: endpoint@1 {
reg = <1>;
remote-endpoint = <&dp_altmode_mux>;
};
};
};
&usbdp_phy0_u3 {
status = "okay";
};
3.4.4 电源配置
USB3.0 Type-C
电源VBUS5V0_TYPEC
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由TYPEC5V_PWREN_H
(GPIO1_D2
)引脚使能,高电平有效;
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-common.dtsi
配置vbus5v0_typec
;
vbus5v0_typec: vbus5v0-typec {
compatible = "regulator-fixed";
enable-active-high;
# GPIO1_D2控制
gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&typec5v_pwren>;
regulator-name = "vbus5v0_typec";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_usb>;
};
3.4.5 FUSB302
配置
配置外置Type-C
控制器芯片FUSB302
,设备节点fusb302@22
配置在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
;
&i2c6 {
clock-frequency = <200000>;
status = "okay";
eeprom@53 {
compatible = "microchip,24c02", "atmel,24c02";
reg = <0x53>;
#address-cells = <2>;
#size-cells = <0>;
pagesize = <16>;
size = <256>;
eui_48: eui-48@fa {
reg = <0xfa 0x06>;
};
};
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio0>;
interrupts = ;
# 中断GPIO0_D3
int-n-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
vbus-supply = <&vbus5v0_typec>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_role_sw: endpoint@0 {
remote-endpoint = <&dwc3_0_role_switch>;
};
};
};
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
;
source-pdos =
;
altmodes {
#address-cells = <1>;
#size-cells = <0>;
altmode@0 {
reg = <0>;
svid = <0xff01>;
vdo = <0xffffffff>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_orien_sw: endpoint {
remote-endpoint = <&usbdp_phy0_orientation_switch>;
};
};
port@1 {
reg = <1>;
dp_altmode_mux: endpoint {
remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
};
};
};
};
};
};
3.5 USB3.0 Type-A
NanoPC-T6
开发板支持1个USB3.0 Type-A
接口,对应的USB
控制器为USB3.0 OTG1(DWC3/xHCI)
、对应的USB PHY
为USB3.0/DP Combo PHY1
和USB2 PHY1
;
因此对应的设备树配置,包括USB3.0 OTG1(DWC3/xHCI)
控制器设备树配置和USB3.0/DP Combo PHY1
、USB2 PHY1
设备树配置。
3.5.1 使能usbdrd3_0
通过dr_mode
属性设置USB
控制器的模式,这里配置为host
。
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
中配置:
# USB3.0 OTG1(DWC3/xHCI)
&usbdrd3_1 {
status = "okay";
};
# 如果配置dr_mode为otg,同时配置extcon = <&u2phy1>属性,才能支持软件切换Device/Host mode
&usbdrd_dwc3_1 {
dr_mode = "host";
snps,xhci-trb-ent-quirk;
status = "okay";
};
注意:NanoPC-T6
开发板大概率不支持USB3.0 Type-A
作为Device mode
使用,如果非要作为Device mode
使用,可以尝试将工作模式dr_mode
配置为otg
。
3.5.2 使能u2phy1_otg
USB3.0 Type-A
工作为主机模式时,可以外接USB
设备,比如鼠标,键盘,并为所连接的USB
设备提供VBUS
电源;因此需要配置phy-supply
,用于控制VBUS
输出5V
。
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
配置:
# USB2.0 PHY1
&u2phy1 {
status = "okay";
};
&u2phy1_otg {
phy-supply = <&vcc5v0_host_30>;
status = "okay";
};
注意:使用phy-supply
,无法实现VBUS
的动态开关。如果工作模式dr_mode
配置为otg
(支持Device/HOST
),并且OTG
独占GPIO
,不与其它HOST
共用,则应该配置为vbus-supply = <&vcc5v0_host_30>
,才能实现VBUS
动态开关.
3.5.3 使能usbdp_phy1_u3
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
配置:
# USB3.0/DP Combo PHY1
&usbdp_phy1 {
status = "okay";
};
&usbdp_phy1_u3 {
status = "okay";
};
3.5.4 电源配置
USB3.0 Type-A
电源VCC5V0_USB30_HOST2
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由USB_HOST_PWREN_H
(GPIO4_B0
)引脚使能,,高电平有效;
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dts
配置vcc5v0_host_30
;
vcc5v0_host_30: vcc5v0-host-30 {
compatible = "regulator-fixed";
enable-active-high;
# GPIO4_B0控制
gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host30_en>;
regulator-name = "vcc5v0_host_30";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_usb>;
};
四、调试接口
4.1 sysfs
4.1.1 USB
设备
所有USB
设备可以在/sys/bus/usb/devices
下找到;
root@NanoPC-T6:~# ls -l /sys/bus/usb/devices
总用量 0
lrwxrwxrwx 1 root root 0 12月 18 23:56 1-0:1.0 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-0:1.0 # USB3.0 OTG1
lrwxrwxrwx 1 root root 0 12月 18 23:56 2-0:1.0 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb2/2-0:1.0 # USB3.0 OTG1
lrwxrwxrwx 1 root root 0 12月 18 23:56 3-0:1.0 -> ../../../devices/platform/fc800000.usb/usb3/3-0:1.0 # USB2.0 HOST0 EHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 4-0:1.0 -> ../../../devices/platform/fc840000.usb/usb4/4-0:1.0 # USB2.0 HOST0 OHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 5-0:1.0 -> ../../../devices/platform/fc880000.usb/usb5/5-0:1.0 # USB2.0 HOST1 EHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 6-0:1.0 -> ../../../devices/platform/fc8c0000.usb/usb6/6-0:1.0 # USB2.0 HOST1 OHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb1 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb2 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb2
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb3 -> ../../../devices/platform/fc800000.usb/usb3
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb4 -> ../../../devices/platform/fc840000.usb/usb4
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb5 -> ../../../devices/platform/fc880000.usb/usb5
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb6 -> ../../../devices/platform/fc8c0000.usb/usb6
如上图所示,可以看到大量的USB
设备。取名规则如下:
bus-port[.port]:configuration.interface
其中:
bus
:表示USB
控制器所连接的总线编号;从1开始编号;port
:表示总线上的硬件端口号;从0开始编号;比如1-0
是根hub
自身信息,当hub
上有插入设备时,就会出现1-1
了。port
:如果总线上的硬件端口连接的设备是一个HUB
,那么该port
表示连接在hub
上的硬件端口号;从1开始编号;configuration
:表示设备的配置值;从1开始编号;interface
:表示设备的接口号;从0开始编号;
比如1-1:1.1
具有以下含义:
1-1
:表示连接到第一个USB
控制器的编号为1的硬件端口;1.1
:表示设备的第一个配置(configuration
)编号为1接口(interface
)。
7-1.2:1.0
具有以下含义:
7-1.2
:表示连接到第7个USB
控制器的编号为1的硬件端口连接了一个hub
,hub
编号为2的硬件端口上连接了一个设备;1.0
:表示设备的第一个配置(configuration
)编号为0接口(interface
)。
4.1.2 USB
设备信息
由于当前开发板的USB
接口没有介入任何设备,因此看到都是USB
控制器上连接的root hub
;
root@NanoPC-T6:~# cd /sys/bus/usb/devices
root@NanoPC-T6:/sys/bus/usb/devices# ls
1-0:1.0 2-0:1.0 3-0:1.0 4-0:1.0 5-0:1.0 6-0:1.0 usb1 usb2 usb3 usb4 usb5 usb6
root@NanoPC-T6:/sys/bus/usb/devices# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
接着我们向开发板USB3.0 Type-A
接口插入一个鼠标,再次查看:
root@NanoPC-T6:/sys/bus/usb/devices# ls
1-0:1.0 1-1 1-1:1.0 1-1:1.1 1-1:1.2 2-0:1.0 3-0:1.0 4-0:1.0 5-0:1.0 6-0:1.0 usb1 usb2 usb3 usb4 usb5 usb6
可以看到多出了目录1-1 1-1:1.0 1-1:1.1 1-1:1.2
;
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1:1.0 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.0
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1:1.1 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.1
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1:1.2 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.2
实际上后面三个都是链接文件都是指向1-1
目录下的子文件。1-1
表示连接到第一个USB
控制器的编号为1的硬件端口;
1-1:1.0
:表示设备的第一个配置(configuration
)编号为0接口(interface
);1-1:1.1
:表示设备的第一个配置(configuration
)编号为1接口(interface
);1-1:1.2
:表示设备的第一个配置(configuration
)编号为2接口(interface
);
我们查看一下USB
鼠标的信息:
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/idProduct
c52b
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/idVendor
046d
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/product
USB Receiver
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/manufacturer
Logitech
实际上这个信息在内核日志也是可以看到的:
[389322.004486] usb 1-1: new full-speed USB device number 9 using xhci-hcd
[389322.147736] usb 1-1: New USB device found, idVendor=046d, idProduct=c52b, bcdDevice=24.11
[389322.147753] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[389322.147762] usb 1-1: Product: USB Receiver
[389322.147769] usb 1-1: Manufacturer: Logitech
[389322.189271] logitech-djreceiver 0003:046D:C52B.0015: hiddev96,hidraw0: USB HID v1.11 Device [Logitech USB Receiver] on usb-xhci-hcd.9.auto-1/input2
[389322.311793] input: Logitech M545/M546 as /devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.2/0003:046D:C52B.0015/0003:046D:4052.0016/input/input28
[389322.312977] logitech-hidpp-device 0003:046D:4052.0016: input,hidraw1: USB HID v1.11 Mouse [Logitech M545/M546] on usb-xhci-hcd.9.auto-1/input2:1
[389343.419592] logitech-hidpp-device 0003:046D:4052.0016: HID++ 4.5 device connected.
USB
鼠标工作在全速模式下,xHCI
控制器,USB1.1
通信协议,使用的USB
总线编号为1,设备编号为9。
4.2 debugfs
USB
调试信息位于/sys/kernel/debug/usb
;
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/
总用量 0
-r--r--r-- 1 root root 0 1月 1 1970 devices
drwxr-xr-x 4 root root 0 1月 1 1970 ehci
drwxr-xr-x 18 root root 0 1月 1 1970 fc000000.usb
drwxr-xr-x 2 root root 0 1月 1 1970 fc400000.usb
drwxr-xr-x 2 root root 0 12月 18 23:56 fusb302-6-0022
drwxr-xr-x 4 root root 0 1月 1 1970 ohci
drwxr-xr-x 2 root root 0 12月 18 23:56 tcpm-6-0022
drwxr-xr-x 3 root root 0 1月 1 1970 xhci
其中:
devices
:该文件列出了当前系统中已连接的USB
设备的详细信息;ehci
:该目录包含EHCI
主机控制器接口的调试信息;fc000000.usb
:该目录包含与fc000000.usb
控制器相关的调试信息,即USB3.0 OTG0
控制器;fc400000.usb
:该目录包含与fe900000.usb
控制器相关的调试信息,即USB3.0 OTG1
控制器;fusb302-6-0022
:该目录包含与fusb302-6-0022
设备相关的调试信息,6为I2C
总线编号,0022为I2C
设备地址;ohci
:该目录包含OHCI
主机控制器接口的调试信息;tcpm-6-0022
:该目录包含与tcpm-6-0022
设备相关的调试信息,4为I2C
总线编号,0022为I2C
设备地址;xhci
:该目录包含XHCI
主机控制器的调试信息;
4.2.1 查看USB3.0 OTG0
工作模式
查看USB3.0 OTG0(DWC3/xHCI)
控制器工作模式,USB3.0 OTG0(DWC3/xHCI)
控制器对应设备节点usbdrd3_0: usb@fc000000
:
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/fc000000.usb/
总用量 0
drwxr-xr-x 2 root root 0 12月 18 23:56 ep0in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep0out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep1in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep1out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep2in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep2out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep3in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep3out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep4in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep4out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep5in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep5out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep6in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep7in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep8in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep9in
-rw-r--r-- 1 root root 0 1月 1 1970 link_state
-rw-r--r-- 1 root root 0 1月 1 1970 lsp_dump
-rw-r--r-- 1 root root 0 1月 1 1970 mode
-r--r--r-- 1 root root 0 1月 1 1970 regdump
-rw-r--r-- 1 root root 0 1月 1 1970 testmode
其中:
link_state
:打印DWC3
的链路状态;regdump
:打印DWC3
控制器的寄存器状态信息;mode
:打印DWC3
的工作模式;testmode
:设置DWC3
进HighSpeed
的测试模式;
此外,DWC3
控制器驱动还实现了基于内核trace
框架的tracepoint
,支持动态使能并保存DWC3
驱动关键信息。
(1) 设备模式
我们通过Type-C
连接线将USB3.0 Type-C
接口与PC
连接在一起,我们可以查看USB3.0 OTG0
控制器的工作模式:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fc000000.usb/mode
device
可以看到USB3.0 OTG0
控制器工作在Device
(设备)模式。
(2) 主机模式
如果我们将Type-C
接口的U
盘连接到USB3.0 Type-C
接口,可以看到内核日志如下:
[348278.750101] phy phy-fd5d0000.syscon:[email protected]: illegal mode
[348278.750125] xhci-hcd xhci-hcd.13.auto: xHCI Host Controller
[348278.750143] xhci-hcd xhci-hcd.13.auto: new USB bus registered, assigned bus number 7
[348278.750245] xhci-hcd xhci-hcd.13.auto: hcc params 0x0220fe64 hci version 0x110 quirks 0x0000202002010010
[348278.750273] xhci-hcd xhci-hcd.13.auto: irq 90, io mem 0xfc000000
[348278.750376] xhci-hcd xhci-hcd.13.auto: xHCI Host Controller
[348278.750387] xhci-hcd xhci-hcd.13.auto: new USB bus registered, assigned bus number 8
[348278.750398] xhci-hcd xhci-hcd.13.auto: Host supports USB 3.0 SuperSpeed
[348278.750499] usb usb7: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.01
[348278.750509] usb usb7: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[348278.750517] usb usb7: Product: xHCI Host Controller
[348278.750524] usb usb7: Manufacturer: Linux 6.1.25 xhci-hcd
[348278.750530] usb usb7: SerialNumber: xhci-hcd.13.auto
[348278.750822] hub 7-0:1.0: USB hub found
[348278.750848] hub 7-0:1.0: 1 port detected
[348278.751081] usb usb8: We don't know the algorithms for LPM for this host, disabling LPM.
[348278.751155] usb usb8: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.01
[348278.751165] usb usb8: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[348278.751173] usb usb8: Product: xHCI Host Controller
[348278.751179] usb usb8: Manufacturer: Linux 6.1.25 xhci-hcd
[348278.751186] usb usb8: SerialNumber: xhci-hcd.13.auto
[348278.751444] hub 8-0:1.0: USB hub found
[348278.751467] hub 8-0:1.0: 1 port detected
[348278.999777] usb 7-1: new high-speed USB device number 2 using xhci-hcd
[348279.140469] usb 7-1: New USB device found, idVendor=14cd, idProduct=1212, bcdDevice= 1.00
[348279.140494] usb 7-1: New USB device strings: Mfr=1, Product=3, SerialNumber=2
[348279.140502] usb 7-1: Product: Mass Storage Device
[348279.140509] usb 7-1: Manufacturer: Generic
[348279.140516] usb 7-1: SerialNumber: 121220160204
[348279.141207] usb-storage 7-1:1.0: USB Mass Storage device detected
[348279.141451] scsi host0: usb-storage 7-1:1.0
[348280.146932] scsi 0:0:0:0: Direct-Access Mass Storage Device 1.00 PQ: 0 ANSI: 0 CCS
[348280.147312] sd 0:0:0:0: Attached scsi generic sg0 type 0
[348280.301906] sd 0:0:0:0: [sda] 30277632 512-byte logical blocks: (15.5 GB/14.4 GiB)
[348280.302047] sd 0:0:0:0: [sda] Write Protect is off
[348280.302057] sd 0:0:0:0: [sda] Mode Sense: 03 00 00 00
[348280.302184] sd 0:0:0:0: [sda] No Caching mode page found
[348280.302193] sd 0:0:0:0: [sda] Assuming drive cache: write through
[348280.308888] sda: sda1 sda2 sda3 sda4 sda5 sda6 sda7 sda8 sda9
[348280.309574] sd 0:0:0:0: [sda] Attached SCSI removable disk
同时USB3.0 OTG0
控制器工作在Host
(主机)模式;
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fc000000.usb/mode
host
4.2.2 查看USB3.0 OTG1
工作模式
查看USB3.0 OTG1(DWC3/xHCI)
控制器工作模式,USB3.0 OTG1(DWC3/xHCI)
控制器对应设备节点usbdrd3_1: usb@fc400000
:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fc400000.usb/mode
host
可以看到USB3.0 OTG1
控制器工作在Host
(主机)模式。
4.2.3 查看xhci
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/xhci/
总用量 0
drwxr-xr-x 6 root root 0 1月 1 1970 xhci-hcd.9.auto
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/xhci/xhci-hcd.9.auto/
总用量 0
drwxr-xr-x 2 root root 0 1月 1 1970 command-ring
drwxr-xr-x 3 root root 0 12月 23 00:57 devices
drwxr-xr-x 2 root root 0 1月 1 1970 event-ring
drwxr-xr-x 4 root root 0 1月 1 1970 ports
-r--r--r-- 1 root root 0 1月 1 1970 reg-cap
-r--r--r-- 1 root root 0 1月 1 1970 reg-ext-legsup:00
-r--r--r-- 1 root root 0 1月 1 1970 reg-ext-protocol:00
-r--r--r-- 1 root root 0 1月 1 1970 reg-ext-protocol:01
-r--r--r-- 1 root root 0 1月 1 1970 reg-op
-r--r--r-- 1 root root 0 1月 1 1970 reg-runtime
4.2.4 查看ehci
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/ehci/
总用量 0
drwxr-xr-x 2 root root 0 1月 1 1970 fc800000.usb
drwxr-xr-x 2 root root 0 1月 1 1970 fc880000.usb
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/ehci/fc800000.usb/
总用量 0
-r--r--r-- 1 root root 0 1月 1 1970 async
-r--r--r-- 1 root root 0 1月 1 1970 bandwidth
-r--r--r-- 1 root root 0 1月 1 1970 periodic
-r--r--r-- 1 root root 0 1月 1 1970 registers
4.2.5 查看fusb302-6-0022
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/fusb302-6-0022/
总用量 0
-r--r--r-- 1 root root 0 12月 18 23:56 log
该文件会记录USB3.0 Type-C
接口设备插拔时以及角色切换的信息,以USB3.0 Type-C
接口有USB
鼠标接入的日志为例;
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[392786.091210] IRQ: 0x21, a: 0x40, b: 0x00, status0: 0x01
[392786.091216] IRQ: TOGDONE
[392786.091810] get_src_cc_status switches: 0x44
[392786.092295] get_src_cc_status rd_mda status0: 0x1
[392786.092778] get_src_cc_status ra_mda status0: 0x21
[392786.094659] get_src_cc_status switches: 0x88
[392786.095143] get_src_cc_status rd_mda status0: 0x23
[392786.096222] detected cc1=Rd, cc2=Open
[392786.096231] cc1=Rd, cc2=Open
[392786.097099] IRQ: 0x21, a: 0x00, b: 0x00, status0: 0x01
[392786.097103] IRQ: COMP_CHNG, comp=false
[392786.296268] cc := Rd
[392786.299776] IRQ: 0x01, a: 0x00, b: 0x00, status0: 0x00
[392786.299779] IRQ: BC_LVL, handler pending
[392786.331880] BC_LVL handler, status0=0x00
[392786.398930] cc := Rp-1.5
[392786.504005] start drp toggling
[392786.553159] IRQ: 0x01, a: 0x40, b: 0x00, status0: 0x01
[392786.553166] IRQ: TOGDONE
[392786.553760] get_src_cc_status switches: 0x44
[392786.554244] get_src_cc_status rd_mda status0: 0x1
[392786.554728] get_src_cc_status ra_mda status0: 0x21
[392786.556609] get_src_cc_status switches: 0x88
[392786.557092] get_src_cc_status rd_mda status0: 0x23
[392786.558168] detected cc1=Rd, cc2=Open # 检测到对方是Rd下拉,因此USB3.0 Type-C接口作为供电方
[392786.558176] cc1=Rd, cc2=Open
[392786.559045] IRQ: 0x20, a: 0x00, b: 0x00, status0: 0x01
[392786.559048] IRQ: COMP_CHNG, comp=false
[392786.758666] pd header := Source, Host # 工作为主机模式
[392786.761053] pd := on
[392786.761069] vbus := On
[392786.761071] charge is already Off
[392786.762222] IRQ: 0x80, a: 0x00, b: 0x00, status0: 0x81
[392786.762226] IRQ: VBUS_OK, vbus=On # VBUS供电开启,为连接的USB设备提供VBUS电源
[392786.762248] cc := Rp-1.5
[392786.766246] sending PD message header: 11a1
[392786.766249] sending PD message len: 4
[392786.773617] IRQ: 0x41, a: 0x10, b: 0x00, status0: 0x82
[392786.773621] IRQ: PD retry failed
......
当USB
鼠标从USB3.0 Type-C
接口移除:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[392791.999035] cc := Rp-1.5
[393000.156208] IRQ: 0x21, a: 0x00, b: 0x00, status0: 0xa3
[393000.156213] IRQ: COMP_CHNG, comp=true
[393000.156227] cc1=Open, cc2=Open
[393000.158609] pd := off
[393000.158623] vbus := Off
[393000.158625] charge is already Off
[393000.158627] vconn is already Off
[393000.159121] pd header := Source, Host
[393000.160014] IRQ: 0x80, a: 0x00, b: 0x00, status0: 0x23
[393000.160018] IRQ: VBUS_OK, vbus=Off # VBUS供电关闭
[393000.162340] start drp toggling
如果USB3.0 Type-C
接口连接到PC
:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[394208.588702] IRQ: 0xa0, a: 0x00, b: 0x00, status0: 0x83
[394208.588708] IRQ: VBUS_OK, vbus=On
[394208.639880] IRQ: 0x01, a: 0x40, b: 0x00, status0: 0x81
[394208.639883] IRQ: TOGDONE
[394208.642732] detected cc1=Rp-def, cc2=Open # 检测到对方是Rp上拉,因此USB3.0 Type-C接口作为耗电方
[394208.642741] cc1=Rp-def, cc2=Open
[394208.843243] pd header := Sink, Device # 工作为设备模式
[394208.843304] vbus is already Off # VBUS供电关闭
[394208.845588] pd := on
[394209.157028] IRQ: 0x41, a: 0x08, b: 0x00, status0: 0x81
[394209.157033] IRQ: BC_LVL, handler pending
[394209.157035] IRQ: PD hardreset sent
[394209.159680] pd := off
[394209.160553] IRQ: 0x41, a: 0x00, b: 0x00, status0: 0x81
[394209.160556] IRQ: BC_LVL, handler pending
[394209.160564] vconn is already Off
[394209.161001] pd header := Sink, Device
[394209.193529] BC_LVL handler, status0=0x81
[394209.811430] pd header := Sink, Device
[394209.813727] pd := on
[394210.125174] IRQ: 0x41, a: 0x08, b: 0x00, status0: 0x81
[394210.125178] IRQ: BC_LVL, handler pending
[394210.125180] IRQ: PD hardreset sent
[394210.127826] pd := off
[394210.127834] vconn is already Off
[394210.128705] IRQ: 0x41, a: 0x00, b: 0x00, status0: 0x81
[394210.128709] IRQ: BC_LVL, handler pending
[394210.129098] pd header := Sink, Device
[394210.160249] BC_LVL handler, status0=0x81
当Type-C
连接线从USB3.0 Type-C
接口移除:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[394417.434921] IRQ: 0x01, a: 0x00, b: 0x00, status0: 0x80
[394417.434926] IRQ: BC_LVL, handler pending
[394417.436373] IRQ: 0x80, a: 0x00, b: 0x00, status0: 0x00
[394417.436377] IRQ: VBUS_OK, vbus=Off
[394417.438761] pd := off
[394417.438763] vbus is already Off
[394417.438765] vconn is already Off
[394417.439232] pd header := Sink, Device
[394417.441507] start drp toggling
[394417.466218] BC_LVL interrupt is turned off, abort
4.2.6 查看tcpm-6-0022
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/tcpm-6-0022
总用量 0
-r--r--r-- 1 root root 0 12月 18 23:56 log
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/tcpm-6-0022/log
[394482.036794] CC1: 3 -> 0, CC2: 0 -> 2 [state TOGGLING, polarity 0, connected]
[394482.036799] state change TOGGLING -> SRC_ATTACH_WAIT [rev3 NONE_AMS]
[394482.036803] pending state change SRC_ATTACH_WAIT -> SNK_TRY @ 200 ms [rev3 NONE_AMS]
[394482.236822] state change SRC_ATTACH_WAIT -> SNK_TRY [delayed 200 ms]
[394482.236824] cc:=2
[394482.239467] pending state change SNK_TRY -> SNK_TRY_WAIT @ 100 ms [rev3 NONE_AMS]
[394482.339481] state change SNK_TRY -> SNK_TRY_WAIT [delayed 100 ms]
[394482.339483] state change SNK_TRY_WAIT -> SRC_TRYWAIT [rev3 NONE_AMS]
[394482.339486] cc:=4
[394482.342281] pending state change SRC_TRYWAIT -> SRC_TRYWAIT_UNATTACHED @ 100 ms [rev3 NONE_AMS]
[394482.442295] state change SRC_TRYWAIT -> SRC_TRYWAIT_UNATTACHED [delayed 100 ms]
[394482.442297] state change SRC_TRYWAIT_UNATTACHED -> SNK_UNATTACHED [rev3 NONE_AMS]
[394482.442300] Start toggling
[394482.444558] state change SNK_UNATTACHED -> TOGGLING [rev3 NONE_AMS]
[394482.501840] CC1: 0 -> 0, CC2: 2 -> 2 [state TOGGLING, polarity 0, connected]
[394482.501843] state change TOGGLING -> SRC_ATTACH_WAIT [rev3 NONE_AMS]
[394482.501846] pending state change SRC_ATTACH_WAIT -> SRC_ATTACHED @ 200 ms [rev3 NONE_AMS]
[394482.701864] state change SRC_ATTACH_WAIT -> SRC_ATTACHED [delayed 200 ms]
[394482.701866] polarity 1
[394482.701868] Requesting mux state 1, usb-role 1, orientation 2
[394482.704678] vbus:=1 charge=0
[394482.704693] pending state change SRC_ATTACHED -> SRC_UNATTACHED @ 480 ms [rev3 NONE_AMS]
[394482.705850] VBUS on
[394482.705852] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS]
[394482.705888] AMS POWER_NEGOTIATION start
[394482.705890] cc:=4
[394482.708702] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION]
[394482.708707] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION]
[394482.708710] PD TX, header: 0x11a1
[394482.717265] PD TX complete, status: 2
[394482.717274] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION]
......
4.3 切换USB3.0 OTG
工作模式
我们使用的开发板USB3.0 Type-C PHY0
、USB2.0 OTG PHY0
物理接口被设计为USB3.0 Type-C
,并且外置了Type-C
控制器芯片(FUSB302
)支持软件自动切换Deivice/Host mode
。
而USB3.0 Type-C PHY1
、USB2.0 OTG PHY1
物理接口被设计为USB3.0 Type-A
,并且TYPEC1_USB20_VBUSDET
引脚悬空处理,USB3.0 Type-A
接口只能作为HOST mode
使用。
RK3588
支持通过软件方法,强制设置USB OTG
控制器切换到Host mode
或者Device mode
,而不受USB
硬件电路的OTG ID
电平或者 Type-C
接口的影响。具体有如下两种方式:
- 方式1依赖于
USB dts
的正确配置,只能用于非Type-C
接口的硬件电路设计; - 方式2没有限制。因此,在不确定软硬件是否正确适配时,推荐优先使用方式2。
4.3.1 方式一
查看工作模式:
root@NanoPC-T6:~# cat /sys/devices/platform/fd5d0000.syscon/fd5d0000.syscon:usb2-phy@0/otg_mode
otg
root@NanoPC-T6:~# cat /sys/devices/platform/fd5d4000.syscon/fd5d4000.syscon:usb2-phy@4000/otg_mode
host
更改USB3.0 OTG0
为主机模式;
root@NanoPC-T6:~# echo host > /sys/devices/platform/fd5d0000.syscon/fd5d0000.syscon:usb2-phy@0/otg_mode
更改USB3.0 OTG0
为设备模式;
root@NanoPC-T6:~# echo peripheral > /sys/devices/platform/fd5d0000.syscon/fd5d0000.syscon:usb2-phy@0/otg_mode
注意:对于Type-C
接口硬件电路设置不会生效,Type-C
控制器(Fusb302
)会自动检测连接的USB
设备,软件自行将USB3.0 OTG0
控制器配置为Host
(主机)、Device
(从机)或双重角色。
4.3.2 方式二
更改USB3.0 OTG0
为主机模式:
# Force host mode
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc000000.usb/mode
更改USB3.0 OTG0
为设备模式:
# Force device mode
root@NanoPC-T6:~# echo device > /sys/kernel/debug/usb/fc000000.usb/mode
当然,我们也可以尝试更改USB3.0 OTG1
为主机模式:
# Force host mode
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc400000.usb/mode
更改USB3.0 OTG1
为设备模式:
root@NanoPC-T6:~# echo device > /sys/kernel/debug/usb/fc400000.usb/mode
该设置会强制将USB3.0 OTG0
控制器配置为指定的工作模式。比如USB3.0 Type-C
接口当前连接着鼠标设备并且工作为主机模式,如果将其设置为设备模式,鼠标将无法工作。
4.4 作为主机模式测试
无论是开发板上的USB3.0 Type-C
接口、还是USB3.0 Type-A
接口作为主机模式测试都是很简单,将USB3.0 OTG
工作模式切换为主机模式,然后在相应USB
接口插入鼠标设备,看看鼠标设备能不能正常工作就可以了;
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc000000.usb/mode # USB3.0 Type-C接口
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc400000.usb/mode # USB3.0 Type-A接口
很显然,测试结果鼠标无论插到哪个USB
接口都可以正常工作。
4.5 作为设备模式测试
在进行模拟之前,我们需要将/bin/usbdevice
文件移动到/opt/hid
目录下,这个是官方提供的用于模拟各种usb
设备的脚本,系统系统会自动执行,默认还是将开发板模拟成adb
终端(通过/etc/profile.d/usbdevice.sh
配置的)。
这里我们不使用官方提供的脚本,主要是这个脚本支持模拟的设备种类比较多,并且代码比较复杂,有兴趣可以自己研究。
root@NanoPC-T6:/# mkdir /opt/hid
root@NanoPC-T6:/# cd /opt/hid
root@NanoPC-T6:/opt/hid# mv /bin/usbdevice /opt/hid
接下来我们会通过USB3.0 Type-C
接口进行模拟触摸屏设备,如果想模拟鼠标,键盘可以参考文章:《四、 模拟USB
设备》。
4.5.1 hid_touch
脚本
下面我们创建一个触摸屏设备,然后编写hid_touch.sh
脚本,文件存放在开发板debian
系统/opt/hid
路径下;
#!/bin/bash
gadget=g2
do_start(){
has_mount=$(mount -l | grep /sys/kernel/config)
if [[ -z $has_mount ]];then
mount -t configfs none /sys/kernel/config
fi
cd /sys/kernel/config/usb_gadget
# 当我们创建完这个文件夹之后,系统自动的在这个文件夹中创建usb相关的内容 ,这些内容需要由创建者自己填写
if [[ ! -d ${gadget} ]]; then
mkdir ${gadget}
fi
cd ${gadget}
#设置USB协议版本USB2.0
echo 0x0200 > bcdUSB
#定义产品的VendorID和ProductID
echo "0x0525" > idVendor
echo "0xa4ac" > idProduct
#实例化"英语"ID:
mkdir strings/0x409
#将开发商、产品和序列号字符串写入内核
echo "76543210" > strings/0x409/serialnumber
echo "mkelehk" > strings/0x409/manufacturer
echo "touch_screen" > strings/0x409/product
#创建一个USB配置实例
if [[ ! -d configs/c.1 ]]; then
mkdir configs/c.1
fi
#定义配置描述符使用的字符串
if [[ ! -d configs/c.1/strings/0x409 ]]; then
mkdir configs/c.1/strings/0x409
fi
echo "hid" > configs/c.1/strings/0x409/configuration
#创建功能实例,需要注意的是,一个功能如果有多个实例的话,扩展名必须用数字编号:
mkdir functions/hid.0
#配置hid描述符(根据hid协议或者g_hid.ko对于的源码hid.c的说明)
echo 0 > functions/hid.0/subclass
echo 0 > functions/hid.0/protocol
echo 5 > functions/hid.0/report_length #标识该hid设备每次发送的报表长度为5字节
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x05\\x15\\x00\\x25\\x01\\x95\\x05\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x03\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x00\\x26\\xff\\x7f\\x35\\x00\\x46\\xff\\x7f\\x75\\x10\\x95\\x02\\x81\\x02\\xc0\\xc0 > functions/hid.0/report_desc
#捆绑功能实例到配置config.1
ln -s functions/hid.0 configs/c.1
#配置USB3.0 OTG0的工作模式为Device(设备):
echo device > /sys/kernel/debug/usb/fc000000.usb/mode
echo "sleep 3s"
sleep 3s
#将gadget驱动注册到UDC上,插上USB线到电脑上,电脑就会枚举USB设备。
echo fc000000.usb > UDC # 可以通过 ls /sys/class/udc/命令查看USB设备控制器
}
do_stop() {
cd /sys/kernel/config/usb_gadget/${gadaget}
echo "" > UDC
}
case $1 in
start)
echo "Start hid gadget "
do_start
;;
stop)
echo "Stop hid gadget"
do_stop
;;
*)
echo "Usage: $0 (stop | start)"
;;
esac
对于触摸屏设备,我们配置:
subclass
:接口子类,配置为0;protocol
:接口协议,配置为0;report_length
:报告长度配置为5,触摸屏与鼠标的不同点是鼠标的上报值是相对坐标,触摸屏是绝对坐标,鼠标x、y
轴分别需要一个字节,而触摸屏一般为16bit
即两个字节;
在开发板debian
系统运行命令模拟触摸屏:
root@NanoPC-T6:/opt/hid# echo device > /sys/kernel/debug/usb/fc000000.usb/mode
root@NanoPC-T6:/opt/hid# ls /sys/kernel/config/usb_gadget/
root@NanoPC-T6:/opt/hid# bash hid_touch.sh start
Start hid gadget
sleep 3s
root@NanoPC-T6:/opt/hid# ls /sys/kernel/config/usb_gadget/
g2
root@NanoPC-T6:/opt/hid# ls /sys/kernel/config/usb_gadget/g2
UDC bDeviceProtocol bMaxPacketSize0 bcdUSB functions idVendor strings
bDeviceClass bDeviceSubClass bcdDevice configs idProduct os_desc
此时会在/dev
目录下生成了设备节点/dev/hidg0
;
root@NanoPC-T6:/opt/hid# ls -l /dev/hidg*
crw------- 1 root root 511, 0 12月 23 13:54 /dev/hidg0
如果需卸载触摸屏,执行如下命令:
root@NanoPC-T6:/opt/hid# bash hid_touch.sh stop
如果卸载不能生效,尝试重启系统。
4.5.2 编写应用程序
然后我们通过设备节点/dev/hidg0
、就可以模拟触摸屏实现与PC
的通信。
编写测试应用程序hid_touch_control.c
,文件存放在debian
开发板/opt/hid
路径下;
#include
#include
#include
#include
#include
#include
#include
#include
/**
* 触摸屏每次发送5字节报告
* report[0]的D0就是左键,D1就是右键,D2就是中键
* report[1]为X轴低字节
* report[2]为X轴高字节
* report[3]为Y轴低字节
* report[4]为Y轴高字节,
*/
/**
* @brief 将焦点移动到指定位置
*
* @param fd 文件描述符
* @param x x轴坐标
* @param y y轴坐标
*/
void move_To(int fd ,int x, int y)
{
char report[5]={0,0,0,0,0};
report[0] = 0x00;
report[1] = x & 0xFF;
report[2] = (x >> 8) & 0xFF;
report[3] = y & 0xFF;
report[4] = (y >> 8) & 0xFF;
// 写入失败
if (write(fd, report, 5) != 5) {
perror("move_To error");
return;
}
usleep(50000);
}
/**
* @brief 函数功能:画线段的函数。
*
*@param fd 文件描述符
* @param x x轴坐标
* @param y y轴坐标
*/
void line_to(int fd, int x, int y)
{
char report[5]={0,0,0,0,0};
report[0] = 0x01; //左键按下
report[1] = x & 0xFF;
report[2] = (x >> 8) & 0xFF;
report[3] = y & 0xFF;
report[4] = (y >> 8) & 0xFF;
if (write(fd, report, 5) != 5) {
perror("line_to error");
return;
}
usleep(50000);
}
int main(int argc, char const *argv[])
{
const char *filename = NULL;
int fd = 0;
if (argc != 3)
{
fprintf(stderr, "Usage: %s devname a/l\n",
argv[0]);
return 1;
}
filename = argv[1];
if ((fd = open(filename, O_RDWR, 0666)) == -1) {
perror(filename);
return 1;
}
if(argv[2][0] == 'a')
{
printf("Draw Tri-angle begin\n");
move_To(fd, 8888, 8888); //移动到(8888,8888)
line_to(fd, 8888, 8888); //开始画线
line_to(fd, 12000, 12000); //画线到(12000,12000)
move_To(fd, 12000, 12000); //松开鼠标左键
move_To(fd, 12000, 12000); //移动到(12000,12000)
line_to(fd, 12000, 12000); //开始画线
line_to(fd ,8888, 12000); //画线到(8888,12000)
move_To(fd, 8888, 12000); //松开鼠标左键
move_To(fd, 8888, 12000); //移动到(8888,12000)
line_to(fd, 8888, 12000); //开始画线
line_to(fd ,8888, 8888); //画线到(8888,8888)
move_To(fd, 8888, 8888); //松开鼠标左键
printf("Draw Tri-angle end\n");
}
if(argv[2][0] == 'l'){
printf("Draw line begin\n");
move_To(fd, 10000, 10000); // 移动到(10000,10000)
line_to(fd, 10000, 10000); // 开始画线
line_to(fd, 20000, 10000); // 画线到(20000,10000)
move_To(fd, 20000, 10000); // 松开鼠标左键
printf("Draw line end\n");
}
close(fd);
return 0;
}
直接在开发板编译应用程序:
root@NanoPC-T6:/opt/hid# gcc -o hid_touch_control hid_touch_control.c
root@NanoPC-T6:/opt/hid# ls -l
-rwxr-xr-x 1 root root 13872 12月 23 13:55 hid_touch_control
-rw-r--r-- 1 root root 2911 12月 23 13:55 hid_touch_control.c
-rwxr-xr-x 1 root root 2668 12月 23 13:47 hid_touch.sh
-rwxrwxr-x 1 pi pi 13170 5月 19 2023 usbdevice
4.5.3 测试触摸屏
(1) 这里我们和鼠标测试一样,使用Type-C
连接线将开发板USB3.0 Type-C
接口与开发板上的USB3.0 Type-A
接口连接起来;内核日志信息如下:
[ 1255.881053] dwc3 fc000000.usb: device reset
[ 1256.004255] usb 1-1: new high-speed USB device number 12 using xhci-hcd
[ 1256.004407] android_work: sent uevent USB_STATE=CONNECTED
[ 1256.007939] dwc3 fc000000.usb: device reset
[ 1256.145009] usb 1-1: New USB device found, idVendor=0525, idProduct=a4ac, bcdDevice= 6.01
[ 1256.145026] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1256.145035] usb 1-1: Product: touch_screen
[ 1256.145042] usb 1-1: Manufacturer: mkelehk
[ 1256.145048] usb 1-1: SerialNumber: 76543210
[ 1256.150185] android_work: sent uevent USB_STATE=CONFIGURED
[ 1256.151169] input: mkelehk touch_screen as /devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.0/0003:0525:A4AC.0017/input/input28
[ 1256.207775] hid-generic 0003:0525:A4AC.0017: input,hidraw0: USB HID v1.01 Mouse [mkelehk touch_screen] on usb-xhci-hcd.9.auto-1/input0
USB
触摸屏工作在高速模式下,xHCI
控制器,USB2.0
通信协议,使用的USB
总线编号为1,设备编号为1。
其中Product
=touch_screen
,Manufacturer=mkelehk
,SerialNumber=76543210
、idVendor=0525
、idProduct=a4ac
,这个就是我们在hid_touch.sh
脚本下配置的。
(2) 在开发板ubuntu
桌面安装画图软件,并运行程序;
root@rk3588:/shell/hid# sudo aptitude install -y kolourpaint
root@rk3588:/shell/hid# kolourpaint
我们将画布调到最大,并且选择左侧的直线;
(3) 打开一个开发板终端(非桌面终端)输入如下命令:
root@rk3588:/shell/hid# ./hid_touch_control /dev/hidg0 a
Draw Tri-angle begin
Draw Tri-angle end
root@rk3588:/shell/hid# ./hid_touch_control /dev/hidg0 l
Draw line begin
Draw line end
最终得到如下图:
参考文章
[1] Rockchip_Developer_Guide_USB_CN.pdf
[2] Rockchip RK3588 USB
开发指南
[3] [Rockchip_Developer_Guide_Linux_USB_PHY_CN
]
[4] Rockchip RK3399
- USB
调试
[5] Rockchip RK3399
- 移植uboot 2017.09 & linux 4.19
(友善之家脚本方式)