赞
踩
目录
rk3588有5个usb控制器,Type-C0/1接口可以简化成usb接口,作者项目中就是Type-C0作为usb2.0 only使用。
按照rk3588 usb开发参考文档进行配置
《Rockchip_RK3588_Developer_Guide_USB_CN.pdf》
Type-C USB 2.0 only DTS配置
配置3.硬件电路不带外置Type-C控制芯片,支持OTG
- &usbdrd3_0 {
- status = "okay";
- };
-
- &usbdrd_dwc3_0 {
- status = "okay";
- dr_mode = "otg";
- phys = <&u2phy0_otg>;
- phy-names = "usb2-phy";
- maximum-speed = "high-speed";
- extcon = <&u2phy0>;
- };
-
- &u2phy0 {
- status = "okay";
- };
-
- &u2phy0_otg {
- status = "okay";
- };
- &usbdp_phy0 {
- status = "disabled";
- };
-
- &usbdp_phy0_dp {
- status = "disabled";
- };
-
- &usbdp_phy0_u3 {
- status = "disabled";
- };
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
发现偶现usb不可用,概率大约20%
通过串口log对比正常和异常log,找到usb相关差异
- 异常log会有如下报错
- dwc3 fc000000.usb: failed to enable ep0out
- 正常log没有报错,会有
- dwc3 fc000000.usb: device reset
找到对应代码位置
- driver/usb/dwc3/gadget.c
- __dwc3_gadget_start()
- {
- ........
- dep = dwc->eps[0];
- ret = __dwc3_gadget_ep_enable(dep, DWC3_DEPCFG_ACTION_INIT);
- if (ret) {
- dev_err(dwc->dev, "failed to enable %s\n", dep->name);
- goto err0;
- }
- ........
- }
添加log,找到最初报错位置
- driver/usb/dwc3/gadget.c
- dwc3_send_gadget_ep_cmd()
- {
- ........
- u32 timeout = 5000;
- ........
- dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
- do {
- reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
- if (!(reg & DWC3_DEPCMD_CMDACT)) {
- cmd_status = DWC3_DEPCMD_STATUS(reg);
-
- switch (cmd_status) {
- case 0:
- ret = 0;
- break;
- case DEPEVT_TRANSFER_NO_RESOURCE:
- dev_WARN(dwc->dev, "No resource for %s\n",
- dep->name);
- ret = -EINVAL;
- break;
- case DEPEVT_TRANSFER_BUS_EXPIRY:
- /*
- * SW issues START TRANSFER command to
- * isochronous ep with future frame interval. If
- * future interval time has already passed when
- * core receives the command, it will respond
- * with an error status of 'Bus Expiry'.
- *
- * Instead of always returning -EINVAL, let's
- * give a hint to the gadget driver that this is
- * the case by returning -EAGAIN.
- */
- ret = -EAGAIN;
- break;
- default:
- dev_WARN(dwc->dev, "UNKNOWN cmd status\n");
- }
-
- break;
- }
- } while (--timeout);
-
- if (timeout == 0) {
- ret = -ETIMEDOUT;
- cmd_status = -ETIMEDOUT;
- }
- ........
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
从上面的代码可以看出,是读usb控制器的某个寄存器5000次都没有得到目标值
添加log,发现正常和异常时传入的参数和内部走的代码流程完全一致, 排除函数内部问题
增加dump_statck(),查看流程,就是正常的probe流程
- [ 6.881962][ T1] Call trace:
- [ 6.881970][ T1] dump_backtrace+0x0/0x1c8
- [ 6.881974][ T1] show_stack+0x1c/0x2c
- [ 6.881981][ T1] dump_stack_lvl+0xdc/0x12c
- [ 6.881984][ T1] dump_stack+0x1c/0x64
- [ 6.881990][ T1] dwc3_send_gadget_ep_cmd+0x5e0/0xa7c
- [ 6.881994][ T1] __dwc3_gadget_ep_enable+0x3c8/0x568
- [ 6.881998][ T1] __dwc3_gadget_start+0x1d8/0x5a8
- [ 6.882002][ T1] dwc3_gadget_pullup+0xcc/0x310
- [ 6.882007][ T1] usb_gadget_connect+0x3c/0x10c
- [ 6.882010][ T1] udc_bind_to_driver+0x150/0x184
- [ 6.882012][ T1] usb_gadget_probe_driver+0xa8/0x184
- [ 6.882015][ T1] gadget_dev_desc_UDC_store+0xec/0x138
- [ 6.882020][ T1] configfs_write_file+0x104/0x154
- [ 6.882023][ T1] vfs_write+0x168/0x390
- [ 6.882026][ T1] ksys_write+0x78/0xe8
- [ 6.882028][ T1] __arm64_sys_write+0x20/0x30
- [ 6.882032][ T1] el0_svc_common+0xc0/0x23c
- [ 6.882035][ T1] do_el0_svc+0x28/0x88
- [ 6.882038][ T1] el0_svc+0x14/0x24
- [ 6.882041][ T1] el0_sync_handler+0x88/0xec
- [ 6.882044][ T1] el0_sync+0x1a8/0x1c0
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
既然无法从原有代码找到问题,尝试用其他方法优化,首先根据代码是循环读取5000次,中间没有其他操作,说明需要时间,
尝试在while前增加延时,看是否可以优化。
结果:没有效果
由于之前做过的rk3588的两个项目都没有此问题,其中一个是结合外置type-c控制芯片配置成全功能接口(虽然硬件上只有usb2.0),另一个是配置成usb3.0接口。
他们都没有disabled掉usbdp相关的phy。
- &usbdp_phy0 {
- status = "okay";
- };
-
- &usbdp_phy0_dp {
- status = "okay";
- };
-
- &usbdp_phy0_u3 {
- status = "okay";
- };
结果:没有效果
从文档中看到,配置maximum-speed = "high-speed",通知dwc3驱动将usb限制为USB2.0 only
在上一步的基础上,把这个配置删除。
结果:usb一直不能用
在上一步的基础上,结合另外两个项目的配置方式删除usbdrd_dwc3_0中phy的配置
- &usbdrd_dwc3_0 {
- status = "okay";
- dr_mode = "otg";
- extcon = <&u2phy0>;
- };
结果:有效
这个配置按照文档中的说法属于type-c to usb3.0/dp的配置,后来又经过测试,可以disable掉usbdp_phy0_dp,最终的配置如下:
- &usbdrd3_0 {
- status = "okay";
- };
-
- &usbdrd_dwc3_0 {
- status = "okay";
- dr_mode = "otg";
- extcon = <&u2phy0>;
- };
-
- &u2phy0 {
- status = "okay";
- };
-
- &u2phy0_otg {
- status = "okay";
- };
- &usbdp_phy0 {
- status = "okay";
- };
-
- &usbdp_phy0_dp {
- status = "okay";
- };
-
- &usbdp_phy0_u3 {
- status = "disabled";
- };
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
经过这个问题,说明rk3588 type-c to usb2.0功能有bug,或者文档给出的参考配置不完整
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。