当前位置:   article > 正文

rk3588 偶现usb无法使用_dwc3 fc000000.usb: failed to enable ep0out

dwc3 fc000000.usb: failed to enable ep0out

目录

背景介绍

分析过程

日志分析

追踪代码

原因分析

1. 检查函数传参以及代码流程

2. 检查调用逻辑

3. 增加延时

4. 配置成usb3.0

打开usbdp相关的phy

删除maximum-speed

删除usbdrd_dwc3_0中phy的配置

总结


背景介绍

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

  1. &usbdrd3_0 {
  2. status = "okay";
  3. };
  4. &usbdrd_dwc3_0 {
  5. status = "okay";
  6. dr_mode = "otg";
  7. phys = <&u2phy0_otg>;
  8. phy-names = "usb2-phy";
  9. maximum-speed = "high-speed";
  10. extcon = <&u2phy0>;
  11. };
  12. &u2phy0 {
  13. status = "okay";
  14. };
  15. &u2phy0_otg {
  16. status = "okay";
  17. };
  18. &usbdp_phy0 {
  19. status = "disabled";
  20. };
  21. &usbdp_phy0_dp {
  22. status = "disabled";
  23. };
  24. &usbdp_phy0_u3 {
  25. status = "disabled";
  26. };

发现偶现usb不可用,概率大约20%

分析过程

日志分析

通过串口log对比正常和异常log,找到usb相关差异

  1. 异常log会有如下报错
  2. dwc3 fc000000.usb: failed to enable ep0out
  3. 正常log没有报错,会有
  4. dwc3 fc000000.usb: device reset

追踪代码

找到对应代码位置

  1. driver/usb/dwc3/gadget.c
  2. __dwc3_gadget_start()
  3. {
  4. ........
  5. dep = dwc->eps[0];
  6. ret = __dwc3_gadget_ep_enable(dep, DWC3_DEPCFG_ACTION_INIT);
  7. if (ret) {
  8. dev_err(dwc->dev, "failed to enable %s\n", dep->name);
  9. goto err0;
  10. }
  11. ........
  12. }

添加log,找到最初报错位置

  1. driver/usb/dwc3/gadget.c
  2. dwc3_send_gadget_ep_cmd()
  3. {
  4. ........
  5. u32 timeout = 5000;
  6. ........
  7. dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
  8. do {
  9. reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
  10. if (!(reg & DWC3_DEPCMD_CMDACT)) {
  11. cmd_status = DWC3_DEPCMD_STATUS(reg);
  12. switch (cmd_status) {
  13. case 0:
  14. ret = 0;
  15. break;
  16. case DEPEVT_TRANSFER_NO_RESOURCE:
  17. dev_WARN(dwc->dev, "No resource for %s\n",
  18. dep->name);
  19. ret = -EINVAL;
  20. break;
  21. case DEPEVT_TRANSFER_BUS_EXPIRY:
  22. /*
  23. * SW issues START TRANSFER command to
  24. * isochronous ep with future frame interval. If
  25. * future interval time has already passed when
  26. * core receives the command, it will respond
  27. * with an error status of 'Bus Expiry'.
  28. *
  29. * Instead of always returning -EINVAL, let's
  30. * give a hint to the gadget driver that this is
  31. * the case by returning -EAGAIN.
  32. */
  33. ret = -EAGAIN;
  34. break;
  35. default:
  36. dev_WARN(dwc->dev, "UNKNOWN cmd status\n");
  37. }
  38. break;
  39. }
  40. } while (--timeout);
  41. if (timeout == 0) {
  42. ret = -ETIMEDOUT;
  43. cmd_status = -ETIMEDOUT;
  44. }
  45. ........
  46. }

原因分析

从上面的代码可以看出,是读usb控制器的某个寄存器5000次都没有得到目标值

1. 检查函数传参以及代码流程

添加log,发现正常和异常时传入的参数和内部走的代码流程完全一致, 排除函数内部问题

2. 检查调用逻辑

增加dump_statck(),查看流程,就是正常的probe流程

  1. [ 6.881962][ T1] Call trace:
  2. [ 6.881970][ T1] dump_backtrace+0x0/0x1c8
  3. [ 6.881974][ T1] show_stack+0x1c/0x2c
  4. [ 6.881981][ T1] dump_stack_lvl+0xdc/0x12c
  5. [ 6.881984][ T1] dump_stack+0x1c/0x64
  6. [ 6.881990][ T1] dwc3_send_gadget_ep_cmd+0x5e0/0xa7c
  7. [ 6.881994][ T1] __dwc3_gadget_ep_enable+0x3c8/0x568
  8. [ 6.881998][ T1] __dwc3_gadget_start+0x1d8/0x5a8
  9. [ 6.882002][ T1] dwc3_gadget_pullup+0xcc/0x310
  10. [ 6.882007][ T1] usb_gadget_connect+0x3c/0x10c
  11. [ 6.882010][ T1] udc_bind_to_driver+0x150/0x184
  12. [ 6.882012][ T1] usb_gadget_probe_driver+0xa8/0x184
  13. [ 6.882015][ T1] gadget_dev_desc_UDC_store+0xec/0x138
  14. [ 6.882020][ T1] configfs_write_file+0x104/0x154
  15. [ 6.882023][ T1] vfs_write+0x168/0x390
  16. [ 6.882026][ T1] ksys_write+0x78/0xe8
  17. [ 6.882028][ T1] __arm64_sys_write+0x20/0x30
  18. [ 6.882032][ T1] el0_svc_common+0xc0/0x23c
  19. [ 6.882035][ T1] do_el0_svc+0x28/0x88
  20. [ 6.882038][ T1] el0_svc+0x14/0x24
  21. [ 6.882041][ T1] el0_sync_handler+0x88/0xec
  22. [ 6.882044][ T1] el0_sync+0x1a8/0x1c0

3. 增加延时

既然无法从原有代码找到问题,尝试用其他方法优化,首先根据代码是循环读取5000次,中间没有其他操作,说明需要时间,
尝试在while前增加延时,看是否可以优化。
结果:没有效果

4. 配置成usb3.0

由于之前做过的rk3588的两个项目都没有此问题,其中一个是结合外置type-c控制芯片配置成全功能接口(虽然硬件上只有usb2.0),另一个是配置成usb3.0接口。

他们都没有disabled掉usbdp相关的phy。

打开usbdp相关的phy
  1. &usbdp_phy0 {
  2. status = "okay";
  3. };
  4. &usbdp_phy0_dp {
  5. status = "okay";
  6. };
  7. &usbdp_phy0_u3 {
  8. status = "okay";
  9. };

结果:没有效果

删除maximum-speed

从文档中看到,配置maximum-speed = "high-speed",通知dwc3驱动将usb限制为USB2.0 only
在上一步的基础上,把这个配置删除。
结果:usb一直不能用

删除usbdrd_dwc3_0中phy的配置

在上一步的基础上,结合另外两个项目的配置方式删除usbdrd_dwc3_0中phy的配置

  1. &usbdrd_dwc3_0 {
  2. status = "okay";
  3. dr_mode = "otg";
  4. extcon = <&u2phy0>;
  5. };

结果:有效
这个配置按照文档中的说法属于type-c to usb3.0/dp的配置,后来又经过测试,可以disable掉usbdp_phy0_dp,最终的配置如下:

  1. &usbdrd3_0 {
  2. status = "okay";
  3. };
  4. &usbdrd_dwc3_0 {
  5. status = "okay";
  6. dr_mode = "otg";
  7. extcon = <&u2phy0>;
  8. };
  9. &u2phy0 {
  10. status = "okay";
  11. };
  12. &u2phy0_otg {
  13. status = "okay";
  14. };
  15. &usbdp_phy0 {
  16. status = "okay";
  17. };
  18. &usbdp_phy0_dp {
  19. status = "okay";
  20. };
  21. &usbdp_phy0_u3 {
  22. status = "disabled";
  23. };

总结

经过这个问题,说明rk3588 type-c to usb2.0功能有bug,或者文档给出的参考配置不完整

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/899356
推荐阅读
相关标签
  

闽ICP备14008679号