RK3568 USB休眠唤醒调试
问题描述
调试环境
RK3568
linux 系统
kernel5.10
现象
USB Host 口接鼠标,客户希望系统进入深度休眠之后能够通过鼠标唤醒系统,但是实际是系统进入休眠的瞬间马上被唤醒,导致系统无法进入深度休眠。
异常日志
异常日志分析
RK 平台,如果在 dts 中设置 rockchip,sleep-debug-en = <1>
,系统休眠唤醒的时候调试串口会打印休眠唤醒相关的调试信息,从上面异常日志可以看到,该调试信息包括休眠模式配置、唤醒源配置、实际唤醒源等。
从系统唤醒的调试信息看,系统配置了CPU、GPIO、USB 为唤醒源,进入深度休眠之后被唤醒,唤醒源是 USB 中断。经排查,如果 USB 口不键盘接鼠标等可以唤醒系统的设备,系统休眠后不会被唤醒,因此可确定是 USB 口唤醒系统。
问题分析
USB休眠唤醒补丁
RK 平台把 USB 休眠唤醒相关的配置补丁收集到一起放到了官方网站上,有 RK 官方支持权限的客户可以从这里获取:Rockchip_Support_USB_HOST_Wakeup.7z 里面包含 RK 各个的配置和配置说明,理论上根据补丁配置就可以实现 USB 休眠唤醒功能,这里根据个人调试经历简单说明几个关键步骤。
确认USB供电
客户的需求是系统进入深度休眠的状态下,支持通过 USB 设备唤醒系统。为了实现以上功能,系统进入深度休眠的时候系统的 USB 模块和系统外接的 USB 设备必要保持在工作状态。因此,USB 相关模块需要在系统休眠时保持供电状态,RK 平台 USB 相关的供电主要是 USBPHY 和 USB 口的 VBUS 供电。以 RK3568 平台为例,USBPHY 的供电是下面这三路:
为了让这三路供电在系统休眠的时候保持不关闭,需要找到输出这三路供电的地方,通过在原理图上的搜索,可以看到对应 PMIC 的 LDO2、LDO7、Switch 1:
再找到代码中 DTS 对应的配置,设置regulator-on-in-suspend
和休眠时的电压,如:
USB 口的 VBUS 供电,可以在原理图上找到是由主控的 GPIO0_A6 口控制的。
再找到代码中 DTS 对应的配置,设置regulator-boot-on
和regulator-always-on
,如:
确认休眠唤醒配置
RK 平台的休眠唤醒配置在 DTS 的rockchip_suspend
节点。由于系统休眠的时候要保持 USB 模块处于工作状态,因此需要把相关模块从休眠配置rockchip,sleep-mode-config
中去掉,让其休眠时保持正常工作。在唤醒配置rockchip,wakeup-config
中添加 USB 唤醒属性 RKPM_USB_WKUP_EN
,其配置如下:
确认USBPHY休眠功能
由于 SDK 中 u2phy0_host 的 suspend 没有打开,导致 USBPHY 一直处于工作状态,系统休眠的时候如果接了鼠标等设备,处于工作状态的 USB 设备中断会唤醒系统,因此需要在代码里打开 suspend,修改如下:
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 66e5e10c0321..c99bd7342613 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -3512,7 +3512,7 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
},
[USB2PHY_PORT_HOST] = {
/* Select suspend control from controller */
- .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d2 },
+ .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 },
.ls_det_en = { 0x0080, 1, 1, 0, 1 },
.ls_det_st = { 0x0084, 1, 1, 0, 1 },
.ls_det_clr = { 0x0088, 1, 1, 0, 1 },
小结
RK 平台的 USB 唤醒功能基本上在 SDK 的基础上加官方提供的补丁就可以实现了。本文主要介绍了自己的调试经历和关键步骤的理解,希望对 RK 平台的开发者有参考意义。
欢迎关注公众号“我的RK随记”,获取更多技术分享!