RK3588V1设备树移植记录
这边实验室做的板子是基于友善的板子删掉一些外设移植过来的,但是友善官方并没有给出一个完整的SDK,或者说跟我们之前使用的SDK差距有点大,所以这边基于之前使用的SDK,将板子(这里取名为lemoV1版本,因为后面还会继续优化,添加外设)适配移植到目前使用的SDK中,使得之后可以直接通过 ./build.sh lunch 选择相应的 .mk文件一键编译即可!
温馨提示:其中有一些很重要的关键点一些具体配置是根据我自己的板子进行修改的,所以不要直接应用在你的配置文件中,这是一遍温故而知新的笔记博客,可能并不适合你直接照着我的解决方法来解决问题,但是方法都是通用的,方法论都是通用的,知识点都是通用的。
能点进来就是同道中人啊~,同道中人,这将近3万字的总结怎么说能值一个点赞、收藏+关注吧。
加油!
RK3588V1设备树移植记录博客目录
- RK3588V1设备树移植记录
1. 环境准备
虚拟机设置共享文件夹可以使用:
sudo /usr/bin/vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=0 -o gid=0 -o umask=022
1.1. 将 原厂SDK设备树目录中 中不需要的设备树先进行移除, 尽量只保留会用得到的设备树.
rm -rf rk3568*
rm -rf rk3588-evb*
rm -rf rk3566*
rm -rf rk3399*
rm -rf rk3368*
rm -rf rk3328*
rm -rf rk3326*
rm -rf rk3308*
rm -rf 1808*
# friendly需要额外删除的
rm -rf rk3562*
rm -rf rk3528*
rm -rf rk3567*
rm -rf rk1808*
rm -rf rk3358*
1.2. 添加自定义的设备树文件
因为只自定义了上层的两个头文件, 也就使能在这两个上层文件中进行修改, 如果要修改其它, 也需要自己 cp 然后替换一下. 避免改动底层通用文件!
1.3. 添加自定义的内核配置文件
到 SDK/kernel/arch/arm64/configs
中 cp 一份原本可以使用的内核配置, 之后改动这个文件即可.
1.4. 添加自定义 mk 文件
SDK/device/rockchip/rk3588 下面直接添加自己的 mk 文件即可, 推荐直接 cp 之后覆盖修改.
xhz@xhz-virtual-machine:~/Neardi/Neardi-3588-SDK-Linux-V3.0/device/rockchip/rk3588$ ls
BoardConfig-ab-base.mk
BoardConfig.mk
BoardConfig-rk3588-neardi-linux-lc160-f1.mk
BoardConfig-rk3588-neardi-linux-lc160.mk
BoardConfig-rk3588-neardi-linux-lkd3588-f0.mk
BoardConfig-rk3588-neardi-linux-lkd3588-f3.mk
BoardConfig-rk3588-neardi-linux-lkd3588-f4.mk
BoardConfig-rk3588-neardi-linux-lkd3588-tp2855.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f0.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f1.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f2.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f3.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f4.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f5.mk
BoardConfig-rk3588-neardi-linux-lpa3588-f6.mk
BoardConfig-rk3588-neardi-linux-lpb3588-f0.mk
BoardConfig-rk3588-neardi-linux-lpb3588-f1.mk
BoardConfig-rk3588-xhz-linux-lemo3588-f0.mk // 自己的mk文件, 替换为设备树和内核配置变量
BoardConfig-security-base.mk
boot4recovery.its
boot.its
parameter-ab.txt
parameter.txt
zboot.its
修改完成后 sdk 添加自己产品基本就没问题了, 剩下就是自定义就行修改就可以了.
1.5. git 管理相应目录
适配板子其实就是在已有的 sdk 源码的基础上就行针对自己板子的增删查改, 其中每个问题可能都会修改好几个文件, 很容易忘记自己什么时候修改过哪一个文件的哪一个位置, 既然目前的配置文件和相应的基本功能已经调通, 可以尝试使用 git 来管理一些常用的目录, 这样更加方便管理和调试.
- kernel
主要的修改对应就是 kernel, 其它的配置应该都比较简单, 直接在目录中使用 readme 来记录即可. 但是 kernel 的修改会很频繁.
这边已经自己维护了一个kernel仓库,便于对不同板卡的修改做出记录。
1.6. 相关系统镜像的命名规范
有单独章节讲解。
2. 设备树, 驱动移植对比分析
本质上应该是对目前已有的设备树的引用使用分析, 可以自己创建一个最上层的设备树文件来包含
2.1. 原SDK 使用到的全部设备树文件
2.2. friendly 使用的全部设备树文件
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
2.3. 自定义 lemo 使用的设备树文件
2.4. 最终自定义的设备树文件
3. kernel 移植适配记录
3.1. 原厂 sdk 测试
这边是一个坑,可以直接看总结,一开始一直起不来怀疑是电源相应的节点配置错误,但有时却不影响启动?需要仔细查看内核驱动信息进行分析,但是要考试了,这一部分内容就先鸽了,考完试之后务必分析出来。
首先直接烧录去掉 uboot 图形显示以及 pcie3x4 设备树节点以及相关 hdmi 显示之后的镜像进行测试.
烧录进行测试的时候如果使用的是一整个镜像固件, 建议换一个小一点的根文件系统. 来减少烧录时间.
sdk 这边还需要打通切换另一个设配置文件, 也就是 device 中新建一个 mk 文件, 使用自己新建的设备树和内核配置文件.
[Line] : 136; [Func] : kbase_platform_rk_init(); power-off-delay-ms not available.
[ 5.175290] rockchip-dmc dmc: leakage=43
[ 5.175301] rockchip-dmc dmc: leakage-volt-sel=1
[ 5.175580] rockchip-dmc dmc: avs=0
[ 5.175592] rockchip-dmc dmc: current ATF version 0x100
[ 5.175683] rockchip-dmc dmc: normal_rate = 1560000000
[ 5.175690] rockchip-dmc dmc: reboot_rate = 2112000000
[ 5.175696] rockchip-dmc dmc: suspend_rate = 528000000
[ 5.175702] rockchip-dmc dmc: video_4k_rate = 1560000000
[ 5.175708] rockchip-dmc dmc: video_4k_10b_rate = 1560000000
[ 5.175713] rockchip-dmc dmc: video_svep_rate = 1560000000
[ 5.175719] rockchip-dmc dmc: boost_rate = 2112000000
[ 5.175724] rockchip-dmc dmc: fixed_rate(isp|cif0|cif1|dualview) = 2112000000
[ 5.175731] rockchip-dmc dmc: performance_rate = 2112000000
[ 5.175737] rockchip-dmc dmc: hdmirx_rate = 2112000000
[ 5.175745] rockchip-dmc dmc: failed to get vop bandwidth to dmc rate
[ 5.175750] rockchip-dmc dmc: failed to get vop pn to msch rl
[ 5.175850] rockchip-dmc dmc: l=10000 h=2147483647 hyst=5000 l_limit=0 h_limit=0 h_table=0
[ 5.175888] rockchip-dmc dmc: could not find power_model node
[ 5.176159] mali fb000000.gpu: GPU hardware issue table may need updating:
[ 5.176159] r0p0 status 5 is unknown; treating as r0p0 status 0
[ 5.176169] mali fb000000.gpu: GPU identified as 0x7 arch 10.8.6 r0p0 status 0
[ 5.176327] mali fb000000.gpu: No priority control manager is configured
[ 5.176338] mali fb000000.gpu: No memory group manager is configured
[ 5.176390] mali fb000000.gpu: Protected memory allocator not available
[ 5.176848] mali fb000000.gpu: Capping CSF_FIRMWARE_TIMEOUT to CSF_FIRMWARE_PING_TIMEOUT
[ 5.177661] mali fb000000.gpu: Couldn't find power_model DT node matching 'arm,mali-simple-power-model'
[ 5.177673] mali fb000000.gpu: Error -22, no DT entry: mali-simple-power-model.static-coefficient = 1*[0]
[ 5.177870] mali fb000000.gpu: Error -22, no DT entry: mali-simple-power-model.dynamic-coefficient = 1*[0]
[ 5.178018] mali fb000000.gpu: Error -22, no DT entry: mali-simple-power-model.ts = 4*[0]
[ 5.178161] mali fb000000.gpu: Error -22, no DT entry: mali-simple-power-model.thermal-zone = ''
[ 5.180133] mali fb000000.gpu: Using configured power model mali-lodx-power-model, and fallback mali-simple-power-model
[ 5.180257] mali fb000000.gpu: l=10000 h=85000 hyst=5000 l_limit=0 h_limit=800000000 h_table=0
[ 5.181233] rockchip-vop2 fdd90000.vop: [drm:vop2_bind] vp0 assign plane mask: 0x5, primary plane phy id: 2
[ 5.181246] rockchip-vop2 fdd90000.vop: [drm:vop2_bind] vp1 assign plane mask: 0xa, primary plane phy id: 3
[ 5.181277] rockchip-vop2 fdd90000.vop: [drm:vop2_bind] vp2 assign plane mask: 0x140, primary plane phy id: 8
[ 5.181289] rockchip-vop2 fdd90000.vop: [drm:vop2_bind] vp3 assign plane mask: 0x280, primary plane phy id: 9
[ 5.181299] rockchip-drm display-subsystem: failed to get hdmi0_phy_pll: -2
[ 5.181307] rockchip-drm display-subsystem: failed to get hdmi1_phy_pll: -2
[ 5.181675] [drm] failed to init overlay plane Cluster0-win1
[ 5.181713] [drm] failed to init overlay plane Cluster1-win1
[ 5.181751] [drm] failed to init overlay plane Cluster2-win1
[ 5.181786] [drm] failed to init overlay plane Cluster3-win1
[ 5.184662] mali fb000000.gpu: Probed as mali0
[ 5.186441] mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual 400000HZ div = 0)
[ 5.199129] rockchip-drm display-subsystem: bound fdd90000.vop (ops 0xffffffc01156f5f0)
[ 5.200361] dwhdmi-rockchip fde80000.hdmi: registered ddc I2C bus driver
[ 5.200723] rockchip-drm display-subsystem: bound fde80000.hdmi (ops 0xffffffc0115774f8)
[ 5.201936] dwhdmi-rockchip fdea0000.hdmi: registered ddc I2C bus driver
[ 5.202249] rockchip-drm display-subsystem: bound fdea0000.hdmi (ops 0xffffffc0115774f8)
[ 5.202345] rockchip-drm display-subsystem: bound fde50000.dp (ops 0xffffffc011579b08)
[ 5.202382] rockchip-drm display-subsystem: bound fde60000.dp (ops 0xffffffc011579b08)
[ 5.203082] rockchip-drm display-subsystem: failed to parse loader memory
[ 5.303537] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[ 5.406974] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[ 5.510357] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[ 5.613515] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[ 5.716814] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[ 5.716845] dwhdmi-rockchip fdea0000.hdmi: failed to get edid
[ 5.749281] dw-dp fde60000.dp: failed to probe DP link: -110
通过调试日志可以猜出来就是显示相关的配置导致内核启动失败. 因为目前的 lemo 板子压根就没有任何显示相关的导出, 唯一的一个 dp 接口的引脚估计配置还和 neardi 的板子不同. 所以首先要针对这一部分进行配置修改.
3.2. 自定义 lemo 设备树
防止进行修改调试导致原先 neardi 的设备树无法正常使用, 所以这边完全 copy 一份外部配置的设备树 dts 文件来自定义.
4. 关键节点的配置说明
4.1. 显示相关
因为一开始的 neardi f3 的系统固件直接烧录启动失败, 先尝试将驱动中与 DP 相关的驱动失能, 是在不行就将 edid 驱动以及设备树中与 hdmi 和 dp 相关的直接注释即可. 设备树在定义的时候失能, 然后在其它文件中进行使能是一种较为规范的使用方式, 有利于设备树的可重用性以及便于编辑理解.
将驱动中与 DP 相关的进行失能, 依旧不行, 所以决定将 edid 和 dp 以及 hdmi 相关的设备树直接注释掉, 然后重新编译内核.
4.1.1. 默认的顶层设备树文件
4.1.2. 修改之后的
这一步之后也还是不行.
同时取消这两个:
如果还是不行就直接失能 DRM 驱动即可. 还是直接失能 DRM 试一下吧, 这个 dp 节点不管怎么调试都报错.
依然不行, 估计是内核中的驱动未失能干净, 某个地方还是尝试 probe dp 接口了.
难道是因为物理链层有问题吗? 尝试失能几个 PHY 子系统. 这边应该是还未进行失能 (失能了 CSI2 D-PHY 和 Display Port PHY Driver) , 但是完全重新编译一次 SDK 之后就可以成功启动, 怀疑是 ubuntu 的问题, 或者不重新全编译一次 kernel 设备树或者配置应用不完全.
重新烧录了一遍使用 ubuntu 的系统, 依然正常进入, 就是 rockchip_dw_dp 那一部分的问题, 现在就是不清楚具体是那一部分的问题. 感觉不全编译一次似乎很多修改无法应用上.
4.1.3. 尝试修改复现
- 查看是否失能 PHY 子系统
目前的 PHY 子系统
之前的子系统:
4.1.4. 全部从来
- 设备树发生变化
与之前可以使用的 dp 输出版本相比, 目前仅仅是设备树中注释掉了, dp 与 hdmi 的相关接口. 重新测试仅仅是设备树发生了变化能否正常启动. 正常情况下, 这一步内核启动会报错.
- 直接修改 display port PHY 子系统
不清楚之前是 DRM 修改是否成功, 但是应该是成功了, 所以直接从 PHY 子系统开始修改那两个.#
4.1.5. 总结
- 最后发现不管 PHY 子系统是不是能, 或者 DRM 驱动使不使能, 都可以进入系统, 所以现在估计就是设备树修改之后要全编译一次, 否则无法成功应用进去, 简单测试一下失能之前的那几个设备树应该就可以了. 测试一下.
- 最新的发现就是直接烧录内核设备树竟然成功应用上了, 甚至显示了之前的 dp probe 失败的信息, 但还是正常进入系统, 目前是一开始可以进入, 然后重新烧录内核之后也可以启动, 这边的下一步思路是: 重新全编译一遍然后分别烧录 buildroot 和 ubuntu 整体固件进一步进行测试.
- buildroot 根文件系统的固件没有问题, 可以启动, 而且设备树也是正常都启用的.
- ubuntu 依然可以正常启动, 但是可能是因为直接将 rootfs.img 指向 ubuntu 的根文件系统, 应该还要指向一个 ext4 文件, 所以重新./build.sh ubuntu, 然后重新生成一次测试.
- ok, 依然是可以正常启动, 那就先不管了. 因为之前板子的镜像固件也没有保存, 无法完全复现. 但是发现如果仅仅是将 rootfs.img 直接指向 ubuntu-base-img 确实会导致报错, 所以还是正常的./build.sh ubuntu 比较合适, 否则需要查看编译 ubuntu 脚本自己修改.
- 切记, 自己任何一个觉得可以长期使用的系统镜像或者你打算新作一个镜像, 都要将之前的保留下来! 都要直接保存下来.!!! 是一整套!!!
并且目前 DP 接口并不能够正常使用 DP 进行显示输出.
4.1.6. 尝试使能 dp 显示
因为 rk3588 只提供了一路的 typec dp 输出, lemo 原本的设备树就支持, 观察设备树也基本一致, 所以两者使能 dp 输出的驱动应该是相同的, 尝试将下面两个设备树直接使能然后编译进行测试:
直接烧录之后第一次直接插上 typec 启动会报错, 导致内核烧录失败, 之后重新烧录, 启动后插上 typec 后 dp 输出显示正常.
4.2. 网口驱动
root@LPA3588:~# [ 306.533023] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 306.533077] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 306.567060] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 306.567111] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 306.592566] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 306.592613] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 306.606954] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 306.606996] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 606.506511] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 606.506609] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 606.527619] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 606.527668] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 606.544822] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 606.544865] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 606.584410] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 606.584446] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 906.505571] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 906.505681] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 906.532045] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 906.532101] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
[ 906.550724] rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at addr -1
[ 906.550774] rk_gmac-dwmac fe1c0000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)
下一步就是给网卡驱动做适配, 看看究竟是设备树的问题, 还是原理图中就不相同, 亦或者是内核驱动的问题.
基本就是设备树的问题, 因为之前的自研核心板使用的是类似 RTL8211F 的芯片, 而 lemo 板子使用的是 RTL8125BG 芯片, 芯片的引脚定义数量和功能都有比较大的不同. 所以这边先对比分析一下各自的设备树配置.
4.2.1. 设备树配置区别
neardi 使用的是 gmac 和外部 phy, gmac 与 phy 通过 GRMII 与 mac 通信, 然后 phy 再转 RJ45 进行通信, lemo 使用的是 pcie 转 RJ45, 就是 pcie 直接与 phy 芯片进行通信, 然后 phy 在通过 MDIO 转到 RJ45.
了解自研板子使用的是 gmac 通过 RGMII 与 PHY 通信, 而 lemo 使用的是 pcie 转 rj45.
并且 neardi 的 pcie 都没有使用到, 可以全部失能了.
4.2.1.1. neardi 以太网设备树配置:
&gmac0 {
/* Use rgmii-rxid mode to disable rx delay inside Soc */
phy-mode = "rgmii-rxid";
clock_in_out = "input";
snps,reset-gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 20ms, 100ms for rtl8211f */
snps,reset-delays-us = <0 20000 100000>;
pinctrl-names = "default";
pinctrl-0 = <&gmac0_miim
&gmac0_tx_bus2
&gmac0_rx_bus2
&gmac0_rgmii_clk
&gmac0_rgmii_bus
&gmac0_clkinout>;
tx_delay = <0x43>;
/* rx_delay = <0x3f>; */
phy-handle = <&rgmii_phy>;
status = "disabled";
};
&mdio0 {
rgmii_phy: phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x1>;
};
};
#endif
&gmac1 {
/* Use rgmii-rxid mode to disable rx delay inside Soc */
phy-mode = "rgmii-rxid";
clock_in_out = "input";
snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 20ms, 100ms for rtl8211f */
snps,reset-delays-us = <0 20000 100000>;
pinctrl-names = "default";
pinctrl-0 = <&gmac1_miim
&gmac1_tx_bus2
&gmac1_rx_bus2
&gmac1_rgmii_clk
&gmac1_rgmii_bus
&gmac1_clkinout>;
tx_delay = <0x44>;
/*rx_delay = <0x0>; */
phy-handle = <&rgmii_phy1>;
status = "okay";
};
&mdio1 {
rgmii_phy1: phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
};
};
4.2.1.2. lemo3588 网卡设备树配置
&pcie2x1l0 {
reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
rockchip,init-delay-ms = <100>;
vpcie3v3-supply = <&vcc_3v3_pcie20>;
status = "okay";
pcie@0,0 {
reg = <0x00200000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
r8125_u12: pcie@20,0 {
reg = <0x000000 0 0 0 0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
};
&pcie2x1l1 {
reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
rockchip,init-delay-ms = <500>;
rockchip,skip-hw-retry;
vpcie3v3-supply = <&vdd_mpcie_3v3>;
status = "okay";
};
&pcie2x1l2 {
reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc_3v3_pcie20>;
status = "okay";
pcie@0,0 {
reg = <0x00400000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
r8125_u10: pcie@40,0 {
reg = <0x000000 0 0 0 0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
};
&pcie30phy {
status = "okay";
};
&pcie3x4 {
reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie30>;
status = "okay";
};
4.2.1.3. 修改 neardi 适配 lemo pcie 设备树节点
&pcie2x1l0 {
//reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
// reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
// rockchip,skip-scan-in-resume;
// status = "okay";
reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
rockchip,init-delay-ms = <100>;
vpcie3v3-supply = <&vcc_3v3_pcie20>;
status = "okay";
pcie@0,0 {
reg = <0x00200000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
r8125_u12: pcie@20,0 {
reg = <0x000000 0 0 0 0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
};
&pcie2x1l2 {
reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc_3v3_pcie20>;
status = "okay";
pcie@0,0 {
reg = <0x00400000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
r8125_u10: pcie@40,0 {
reg = <0x000000 0 0 0 0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
};
其中要注意因为是分三个 2.0 的 pcie 使用, 所以 combphy0_ps, combphy1_ps, combphy2_psu 都要使能.
4.2.2. 内核配置区别
修改内核配置:
将 8125 进行使能. 然后如果 gmac 还有报错信息的话可以尝试使能这个 STM 选项:
修改完成内核之后编译报错, 因为没有定义 pcie2x1l0 和 2 中相应的电源管理节点.
之后编译进行烧录, 发现板端有一个 eth1 正常显示并且可以使用:
测试一下是不是 pcie2x1l2 有问题, 分别将两个 pcie 控制器进行失能, 可以看出即使只有 1l2 的时候依然没有 eth0, 但是只有 1l0 时依然有 eth1, 所以可以排除是驱动冲突问题.
设备树进行这样修改, 因为stat0与pcie冲突,所以一直会报错一个pcie host初始化失败。
// 2024-11-25 20:44:22 changed by xhz,
&sata0 {
status = "disabled";
};
// 2024-11-25 20:44:22 changed by xhz
重新编译烧录之后可以看到有两个网口了:
4.2.3. 网口重命名, 最后决定不使用, 发现会导致一个网口不显示
目前这个网口名称使用起来太麻烦, 使用 udev 进行重命名:
# 将 MAC 地址 62:ea:fb:ca:95:e7 的网卡命名为 eth0
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="62:ea:fb:ca:95:e7", NAME="eth2"
# 将 MAC 地址 7e:89:a2:68:bb:96 的网卡命名为 eth1
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="7e:89:a2:68:bb:96", NAME="eth1"
4.2.4. 总结:
正常按照 lemo 原本的设备树添加相应的节点(甚至不添加仅仅使能应该也可以). 最关键的一点是要注意 pcie 控制器相应的 phy 选择正确, 最后也是最关键的部分就是一定要避免 combphy 中的 mux 复用冲突 (也就是不能同时被 stat 和 pcie2x 使用), 一次只能使用一种功能, 具体看官方文档介绍和设备树引用配置.
4.3. RKNPU 模块未加载
使用之前 nearid 的配置, 发现系统中没有 rknpu 相关的目录, 使用dmesg | grep -i rknpu
也没有相关的调试信息, 说明虽然 rknpu 被成功编译, 但是并没有被成功加载到内核当中.
4.3.1. 确定问题
总的来说, 感觉还是设备树的问题.
不清楚是因为模块加载失败还是压根就没到这一步就出现了问题, 所以尝试将 rknpu 编译为 ko 模块手动挂载:
编译时出现报错, 修改内核源码:
kernel/arch/arm64/mm/ dma-mapping.c
也就是添加下面几行将这几个函数符号进行导出
导出 iommu_setup_dma_ops 函数之后编译正常.
之后 insmod 发现 dmesg 没有反应, 没有调试信息, 不过出现/sys/module/rknpu
目录
经过与自研网关板子对比挂载 rknpu.ko 模块发现, 自研板子即使启动后使用 insmod 挂载 rknpu 驱动, 也可以显示正常的挂载信息, 并且出现/sys/kernel/debug/rknpu
目录, 但是 lemo3588 目前没有任何可用的信息. 说明不是内核以及驱动的问题, 是设备树或者硬件配置不同,
并且启动的时候调试信息显示 gpu 报错, 并且还显示类似于 load kernel modules 失败的问题:
[ 5.173078] systemd[1]: Condition check resulted in File Sy Starting Rsemount Root and Kernel File Systems...
tem Check on Root Device being skipped.
[ 5.174880] systemd[1]: Starting Load Kernel Modules...
[ 5.176698] systemd[1]: Starting Remount Root and Kernel File Systems...
[ 5.178625] sy Starting udev Coldplug all Devices...s
temd[1]: Starting udev Coldplug all Devices...
[ OK ] Mounted stemd[1]: Mounted POSIX Message Queue File System.
POSIX Message Queue File System.
[ OK ] Mounted /sys/kernel/debug.
[ OK ] Mounted Kernel Trace File System.
[ 5.183206] systemd[1]: Mounted /sys/kernel/debug.
[ 5.183632] systemd[1]: Mounted Kernel Trace File System.
[ 5.184271] s[ OK ] Finished 1;39mLoad Kernel Module chromseos_pstore.
temd[1]: modprobe@chromeos_pstore.service: Succeeded.
[ 5.185061] systemd[1]: Finished Load Kernel Module chromeos_pstore.
[ 5.190062] systemd[1]: modprobe@pstore_blk.service: Succeeded.
[ OK ] Finished Load Kernel Module pstore_blk.
[ 5.190371] EXT4-fs (mmcblk0p7): re-mounted. Opts: (null)
[ 5.190594] systemd[1]: Finished Load Kernel Module pstore_blk.
[ 5.191659] systemd[1]: modprobe@pstore_zo[ OK ] Finnei.sshed Load Kernel Module pstore_zone.
ervice: Succeeded.
] 5.192224] systemd[1]: Finished Load Kernel Module[msFtAoIrLeE_Dzn[e0.m
[F a i l e5d. 1to start Load Kernel Modules.
See 'systemctl s92tatus systemd-modules-load.s92ervice' for details.
6] systemd[1]: systemd-modules-load.service: Main process exited, code=exited, sta[ OK ] Finished 1;39mRemount Root and Kernel File Systems.
us=1/FAILURE
[ 5.193032] systemd[1]: systemd-modules-load.service: Failed with result 'exit-code'.
[ 5.193561] systemd[1]: Failed to start Load Kernel Modules.
FUSE Control File System...Finished Remount Root and Kernel File MoSuynsttienmgs .
[ 5.197610] systemd[1]: Mounting FUSE Control File System...
[ 5.199372] systemd[1]: Mounting Kernel Configuration File System Mounting .Kernel Configuration File System...
..
分析之后觉得这些可能没什么问题.
4.3.2. 查看相关的节点
对比发现, rknpu 中vdd_npu_s0`有问题.
4.3.2.1. 原 friendly
挂载在 i2c2 下的,
4.3.2.2. 原 neardi
却是挂载在 i2c1 下的子节点.
4.3.3. 修改vdd_npu_s0
到 i2c2 下
该节点对应硬件 rk860-2 电源管理芯片, 应该是单独为 npu 供电的模块, 所以与硬件强相关, 需要对照原理图进行修改.
直接将 friendly 中的 i2c2 内容复制到 lemo 中, 然后将之前的以及 i2c1 的注释掉.
虽然还是无法显示 rknpu, 但是我估计这个节点已经没有问题了, 再看看其它相关节点.
通过观察系统总线可以看出来: 估计是引脚选择问题或者冲突。
4.3.4. 解决 i2c2 m0 引脚占用
最终发现是 i2c 引脚冲突。
can0节点的的引脚与i2c冲突占用, 将其修改。
这边已经将其进行失能了, 接着再去编译测试. 不够规范, 要标注好修改的是哪一个文件. 避免修改偏底层的文件, 影响 neardi 的配置, 因为目前都是从这个里面出的. 如果修改了, 就需要自己另 cp 一套出来.
4.3.5. npu 成功出现
重新编译测试发现, /dev 中出现 i2c-2 总线
并且成功 出现/sys/kernel/debug/rknpu
4.3.6. 总结
最后发现是一个 rk860-2 电源管理芯片挂载的问题, 该芯片用于为 rknpu 供电, neardi 中默认接到 i2c1 中, 但是 lemo3588 中是接到 i2c-2 总线的, 并且 neardi 默认开启了 can0 导致与 lemo 中 i2c-2 以及 rk8602 所使用的引脚冲突, 需要失能 can0, 或者切换到其它 gpio. 不过对于 lemo, 直接失能就行了. 之后将vdd_npu_s0
节点复制到 i2c2 节点中即可.
5. 部分非关键节点修改
每一个节点对应系统中的一个功能, 都很重要, 这里的非关键的含义是"暂时对系统运行影响不大"的意思, 像是一些 led 显示, 网口 led 显示, 一些设备树中打开但是实际没有使用到的 uaet, can, i2c, spi 等, 这些需要一点点修改, 记录也比较杂一点.
5.1. 两个 LED 灯
优化适配好记得要同步最后使用的 zzu 版本设备树.
lemo led 灯原理图:
neardi: 只需要关注 neardi 的原理图以及设备树中是否使用了这两个引脚, 防止造成冲突, 如果有直接失能即可.
修改设备树过程中一个报错提示将 status 重定义两次, 注意同一个节点中不能有两个 status.
5.1.1. 根据友善修改 lemo 设备树节点
// 2024-11-29 11:58:21 changed by xhz, for gpio-leds, if the modification is
// successful, the node commeneted above will be deleted
// 最终的leds节点, 以及pinctrl控制节点:
leds: leds {
compatible = "gpio-leds";
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&sys_led_pin>, <&usr_led_pin>;
sys_led: led-0 {
gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
usr_led: led-1 {
gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
};
&pinctrl {
leds {
sys_led_pin: sys_led_pin {
rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
};
usr_led_pin: usr_led_pin {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
5.1.2. 总结
修改后两个 led 均可以正常闪烁, 也就是这两个引脚也没有与 neardi 的引脚产生冲突.
后续使用时发现, 其实有一个用户可编程 led 是可以不用配置的, 否则用户在其它地方就无法使用该 gpio 来自行控制这个引脚了, 控制的时候会显示该引脚已被占用.
6. 系统级配置
目前可以正常运行网关系统, 说明大多数的外设都没有问题了, 可能像是一些 led, 网口 led 等显示会有点问题, 以及开机后网口名称显示和可能有一个网口不显示(遇到的次数有点多,重启即可解决). 不过目前来说使用起来还算可以.
系统配置主要通过修改根文件系统实现:
sudo mount -o loop ubuntu-base-focal.img ./ubuntu-rootfs/
sudo chroot ubuntu-rootfs/
6.1.1. 修改欢迎语句
将欢迎语句修改为 lemon3588
使用 Big 字体.
sudo vim /etc/update-motd.d/60-my-welcome-message
#!/bin/sh
cat << "EOF"
_________ _
|_ /_ / | | |
_ / / / /| |_| | ____ _____ ___ ___
| |/___/___|\__,_| |___ \| ____|/ _ \ / _ \
| | ___ _ __ ___ ___ __) | |__ | (_) | (_) |
| |/ _ \ '_ ` _ \ / _ \|__ <|___ \ > _ < > _ <
| | __/ | | | | | (_) |__) |___) | (_) | (_) |
|_|\___|_| |_| |_|\___/____/|____/ \___/ \___/
EOF
sudo chmod 777 60-my-welcome-message
6.1.2. 修改以太网口名
可以不进行修改, 因为有时候修改失败会导致一时 eth1 一会 en…啥的, 干脆直接使用一种名字也方便点.
6.1.3. 添加 lemo 用户名
修改用户名为 lemon
adduser lemo
// 用户名 密码
lemo lemo@zzu
添加可 root 操作权限:
sudo visudo
// 下面添加:
lemo ALL=(ALL:ALL) ALL
7. usb 驱动无法正确识别
目前附加一个问题描述为 TYPE-C 口无法正确识别 USB3.0. 似乎是 VBUS 的电源管理模块引脚配置错误.
连接一款 fpga 的 usb3.0, neardi 连接后可以正确识别, lsusb 可以显示, 并且会出现 video 接口, 并且可以使用 vlc 进行调用. 但是友善的原镜像和 lemo3588(移植的 neardi 的镜像)的, 都显示无法识别这个 usb 芯片, 并且生成 video 接口, 不清楚为什么 neardi 的就可行, 按理来说
neardi 正常的输出:
root@HanWei3588:~#
[ 91.710649] usb 1-1: new high-speed USB device number 2 using ehci-platform
[ 91.859828] usb 1-1: New USB device found, idVendor=04b4, idProduct=00f8, bcdDevice= 0.00
[ 91.859852] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 91.859867] usb 1-1: Product: FX3
[ 91.859880] usb 1-1: Manufacturer: Cypress
[ 91.874015] uvcvideo: Found UVC 1.10 device FX3 (04b4:00f8)
lemo 以及原友善不正常的输出:
[ 4012.697577] usb 8-1: Device not responding to setup address.
[ 4012.904438] usb 8-1: Device not responding to setup address.
[ 4013.111009] usb 8-1: device not accepting address 111, error -71
[ 4014.070878] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4014.071476] usb usb8-port1: config error
[ 4015.011405] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4016.897586] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4016.898253] usb usb8-port1: config error
[ 4019.720852] usb 8-1: Device not responding to setup address.
[ 4019.927660] usb 8-1: Device not responding to setup address.
[ 4020.134073] usb 8-1: device not accepting address 115, error -71
[ 4022.601159] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4509.422662] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4509.612789] usb 8-1: Device not responding to setup address.
[ 4509.819318] usb 8-1: Device not responding to setup address.
[ 4510.025812] usb 8-1: device not accepting address 118, error -71
[ 4510.985988] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4514.215818] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4515.322667] usb 8-1: Device not responding to setup address.
[ 4515.529122] usb 8-1: Device not responding to setup address.
现在就是要搞清楚这是什么问题, 以及如何解决?
目前进行了多次的测试, 发现这个问题, 是一个很奇怪的现象, 仔细对该场景进行描述一下:
7.1. 场景描述:
很简单, 就是一个 fpga, 内部有一个 usb3.0 的芯片, 要通过他的 usb3.0 接口插到 lemo3588 上. 然后 lemo3588 正常就应该与最上面的调试输出一样, 检测到 usb3.0 的设备再有相应的调试信息, 但是一开始无论怎么测试, 都会报错:
[ 4012.697577] usb 8-1: Device not responding to setup address.
[ 4012.904438] usb 8-1: Device not responding to setup address.
[ 4013.111009] usb 8-1: device not accepting address 111, error -71
[ 4014.070878] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4014.071476] usb usb8-port1: config error
[ 4015.011405] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
[ 4016.897586] usb usb8-port1: Cannot enable. Maybe the USB cable is bad?
一开始直接插在 lemo3588 的 usb 口上就会一直报这样的错误, 原本以为是驱动的问题, 但是思来想去不清楚是那一部分的驱动跟这个相关, neardi 的可以直接使用, lemo3588 的应该也没问题的, 然后抱着侥幸的姿态先插上 usb3.0 的拓展坞之后再插上 fpga, 此时发现竟然可以正常检测设备了 ! , 不过 lsusb 输出显示不是直接找到 FX3 摄像头(即 neardi 直插显示 fpga usb3.0 芯片 + FX3 摄像头), 使用拓展坞则显示 (fpga usb3.0 芯片 + 拓展坞), 不过 /dev 下面有相应的摄像头节点显示, 即目前似乎可以达到和 neardi 一样的效果.
开始测试, 依然使用拓展坞进行连接, 打开 vlc 显示, 视频流很卡顿, 虽然不是直接卡死, 但是看起来很不流畅, 当然, 这个可能与 ssh 远程连接显示有一定关系, 但绝不是远程传输直接导致如此卡顿的. 此时为了使用屏幕进行输出, 插上键盘 usb 口到拓展坞上(fpga 也正连接着), 发现此时在打开视频流容易在前几秒画面波动较大的时候直接卡死, 有时即使画面波动不大开启摄像头几秒也会卡死, 将键盘 usb 拔出后发现卡死现象不会再发生, 但画面依然卡顿.
为了测试 usb 的速率, 开始一直插拔 fpga 的 usb 口, 然后使用lsusb -t
查看挂载情况, 发现一般情况下都是挂载在 usb-8 总线(5000M/s)上, 但是有时连续插拔可以发现 usb-8-1 总线无法识别该设备, 也显示 Cannot enable. Maybe the USB cable is bad?
, 不过这时候下面的 usb7-1 总线会成功检测到这个设备, 也会产生/dev/video40 节点, 但是注意后面的速率显示是 480M/s, 即标准的 usb2.0 的最大传输速率, 这时候再去播放肯定就很容易卡顿了(不至于直接卡死), 因为 usb2.0 的速率根本就不过传输正常可以播放的原始视频流. 所以之前测试的卡顿很可能就是识别并挂载到了 usb2.0 上
继续多进行几次测试发现, 后面连续 5, 6 次都显示可以直接挂载到 usb3.0 总线上, 并且显示都很流程丝滑(dp 输出以及 ssh). 没有再遇到卡顿和卡死的情况 (记得 usb3.0 好像要比 usb2.0 插得快一点, 会不会和这个有原因?), 甚至! 直接将 fpga 插入到 lemo 唯一的一个之前怎么插入失败的 usb 端口也可以成功并显示节点, 并且 vlc 显示也很丝滑流畅, 是 3.0 无疑了.
7.1.1. 现象继续观测总结
neardi 直插 usb 口:
neari 先插 usb 拓展坞, 再插 fpga:
可以看到似乎传输速率是 usb2.0?
将两个设备分别拔出来后可以看到 bus 01 发生了变化, 也就是默认的速度也只是 usb2.0?
因为这是我自己制作的镜像, 所以使用可能有些问题, 这边使用之前的镜像进行插拔测试
7.1.2. 老镜像(非自己做的)
可以看到即使是老镜像, 行云路店, 依旧是直接挂载到 480M 的 bus-01 总线上. 因为只有一个拓展坞, 不过感觉也不用进行测试, 也就是 2.0 的速度. 并且自研的与 lemo 有一个不同的是: lemo 是挂载 usb3.0 失败了才会挂载到 usb2.0 上 并且 3.0 的总线一直在尝试挂载但失败, 不过自研的板子都是直接挂载到 usb2.0, 压根就没往 3.0 上进行挂载.
咨询了学长之后了解, 我们自己的板子不支持 usb3.0 接口.
7.1.3. lemo 现象
7.2. 怀疑原因:
- usb3.0 的插拔速度: usb3.0 根据其硬件接口的定义, 插入的速度快慢可能会影响传输速率:
- 硬件或电力问题:
- USB 3.0 设备需要更多的电力支持。如果电源不稳定或不足,设备可能无法正常启动 USB 3.0 协议,从而退回到 USB 2.0 模式。
- USB 3.0 接口的电力供应比 USB 2.0 更高,如果电力无法满足要求,设备可能不会被识别为 USB 3.0 设备,而是作为 USB 2.0 设备挂载。
如何测量供电的问题呢? 将 neardi 的 usb3.0 连接之后测量线路的瞬间电压, 电流情况以及稳定后的电压和电源情况.
- usb 协商问题 (属于现象级别)
usb 设备和主机之间的初始化过程包括协议协商, 决定使用的 usb 总线类型, 如果设备初始化过程遇到问题(比如电源不稳定, 信号干扰)导致 3.0 协商失败, 可能又概率退回到较低的速率.
- usb 端口或线缆问题
- 不同的 USB 端口和连接线缆质量可能会影响连接质量。如果 USB 3.0 端口或线缆存在物理损坏或质量问题,信号可能无法正确传输,导致无法启用 USB 3.0 模式。这种情况下,设备可能会回退到 USB 2.0 模式。
- USB 3.0 和 USB 2.0 在硬件上有不同的接触点,如果 3.0 接口出现接触不良,也可能会导致无法正常工作。
可以尝试更换线缆, 购买更粗更短, 信号稳定性更强的线缆.
7.3. 需要理清楚的重要点:
上面的原因分析排查基本就这样只不过不确定具体是哪一个影响, 不过中间遇到的一些知识点需要自己深入探究一下:
7.3.1. rk3588 软硬件 usb 总线
rk3588 上总线究竟是如何划分的? 为什么一个物理端口可以对应不同的多个总线? 需要看文档等学习一下.
7.4. USB 控制器供电及功耗管理
USB 控制器的功耗控制策略如下:
- 对于不使用的 USB 控制器, 需要将对应的控制器 DTS 节点配置为 disabled;
- 对于内核已启⽤的 USB 控制器,内核 USB 驱动已经⽀持 USB 控制器 Auto suspend 功能 (当 USB HOST 接口不接任何外设时,控制器⾃动进⼊ suspend 低功耗状态),因此,开发者不需要对 USB 控制器的动态功耗管理进⾏调试。
内核 disable USB2.0 HOST0/1 的方法如下:
# Disable USB 2.0 HOST0
&usb_host0_ehci {
status = "disabled";
};
&usb_host0_ohci {
status = "disabled";
};
# Disable USB 2.0 HOST1
&usb_host1_ehci {
status = "disabled";
};
&usb_host1_ohci {
status = "disabled";
};
7.5. USB 2.0 PHY 的功耗控制策略如下:
- 为了⽀持 Maskrom USB 下载固件的功能,必须保证 USB 2.0 PHY 的供电正常;
- 系统上电后,所有 USB 2.0 PHY 默认处于 Normal mode,软件在 U-Boot SPL 阶段,配置 USB 2.0 PHY1/PHY2/PHY3 处于最低功耗 IDDQ mode(SDK 已经⽀持),在进⼊系统后,内核 USB 驱动会 根据应⽤需求,设置对应的 USB 2.0 PHY 退出 IDDQ mode;
- 对于不使⽤的 USB 2.0 PHY,需要将对应的 USB 2.0 PHY DTS 节点配置为 disabled (参考表 9);
- 对于内核已启⽤的 USB 2.0 PHY,内核 USB 2.0 PHY 驱动会⾃动对 PHY 进⾏动态功耗控制,当检 测到有设备插⼊时,⾃动设置 USB 2.0 PHY 处于 Normal mode,当检测到没有设备插⼊时,⾃动设 置 USB 2.0 PHY 处于 Suspend mode;
USB 2.0 PHY 和 USB 控制器连接关系
内核 disable USB2.0 PHY2/3 的方法如下:
&u2phy2 {
status = "disabled";
};
&u2phy3 {
status = "disabled";
};
&u2phy2_host {
status = "disabled";
};
&u2phy3_host {
status = "disabled";
};
7.6. USB 3.1 PHY 供电及功耗管理
USB 3.1 Combo PHY 和 USB 控制器的连接关系
这两种 USB 3.1 Combo PHY 对应的供电电源和功耗控制⽅式都不⼀样,下⾯分别进⾏说明。
7.6.1. USB3.1/DP Combo PHY
RK3588 ⽀持两个独⽴的 USB 3.1/DP Combo PHY 。RK3588S 相⽐ RK3588 少了 1 个 USB 3.1/DP Combo PHY1。在芯⽚内部,两个 USB 3.1/DP Combo PHY 都属于 PD_BUS (Alive),在芯⽚外部,两个 PHY 有 独⽴的供电电源 pin,如图 14 所⽰。
USB 3.1/DP Combo PHY 的功耗控制策略如下:
- 为了⽀持 Maskrom USB 下载固件的功能,必须保证 Type-C0 USBDP PHY0 的供电正常;
- 当 Type-C1 接口不使⽤时,对应的 Type-C1 USBDP PHY1 可以不供电;
- 系统上电后,USBDP PHY 处于未初始化状态时的功耗最低;
- 对于不使⽤的 USBDP PHY,需要将对应的 USBDP PHY DTS 节点配置为 disabled,也即让 PHY 处 于未初始化状态,功耗最低;
- 对于内核已启⽤的 USBDP PHY,内核 USBDP PHY 驱动会⾃动对 PHY 进⾏动态功耗控制,当检测 到有设备插⼊时,⾃动设置 USBDP PHY 处于 P0 State,当检测到没有设备插⼊时,⾃动设置 USBDP PHY 处于 P3 State (应⽤于 Type-A 接口)或者处于 reset state (应⽤于 Type-C 接口);
内核 disable USBDP PHY1 的方法如下:
&usbdp_phy1 {
status = "disabled";
};
&usbdp_phy1_dp {
status = "disabled";
};
&usbdp_phy1_u3 {
status = "disabled";
};
7.6.2. USB 3.1/DATA/PCIe Combo PHY
RK3588 ⽀持 1 个 USB3.1/SATA/PCIe Combo PHY。在芯⽚内部,这个 PHY 属于 PD_BUS (Alive),在芯 ⽚外部,PHY 有独⽴的供电电源,如图 15 所⽰。
USB 3.1/SATA/PCIe Combo PHY 的功耗控制策略如下:
- 芯⽚上电时,USB 3.1/SATA/PCIe Combo PHY 默认处于⼯作状态。软件在 U-Boot SPL 阶段,配置 设置 PHY 处于 reset state,以保持 PHY 处于最低功耗。进⼊内核后,USB 控制器驱动会通过调⽤ rockchip_combphy_init() 函数释放 PHY 的 reset
- PHY 的动态功耗控制:当 Combo PHY ⼯作在 USB mode 时,PHY 的 PIPE state (P0/P1/P2/P3) 由 USB 控制器硬件⾃动控制,根据不同的⼯作场景,动态进⼊和退出 P0/P1/P2/P3 state。⽐如,未插 ⼊任何 USB 设备时,PIPE 处于 P3 state;插⼊ U3 disk 时,则切换到 P0 state;当接 U3 HUB 时,只 要 HUB 的下⾏端口没有接其他 USB 外设,则 PIPE state 会⾃动进⼊ P3 state 低功耗。当有 USB 外 设插⼊U3 HUB,则 PIPE state ⾃动切换为 P0。(注:P0 为正常⼯作状态,P3 为最低功耗状态)
- 当明确不使⽤ USB 3.1 HOST2 接口时,对应的 USB 3.1/SATA/PCIe Combo PHY 可以不供电;
- 在 PHY 供电的情况下,如果不使⽤这个PHY,需要将对应的 PHY DTS 节点配置为 disabled,也即 让 PHY 处于 reset state,功耗最低;
内核 disable USB 3.1/DATA/PCIe Combo PHY 的方法如下:
&combphy2_psu {
status = "disabled";
};
// 明显这个也是控制pcie和相应的sata的phy
7.7. RK3588 USB DTS 配置
RK3588 USB DTS 配置,包括:芯⽚级 USB 控制器/PHY DTSI 配置和板级 DTS 配置。
详细的配置方法, 请参考内核文档:
\1. kernel/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
\2. kernel/Documentation/devicetree/bindings/usb/generic-ohci.yaml
\3. kernel/Documentation/devicetree/bindings/usb/generic-ehci.yaml
\4. kernel/Documentation/devicetree/bindings/connector/usb-connector.yaml
\5. kernel/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
\6. kernel/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
\7. kernel/Documentation/devicetree/bindings/phy/phy/phy-rockchip-naneng-combphy.txt
7.7.1. USB 芯片级 DTSI 配置
RK3588 DTSI 文件中 USB 控制器和 PHY 相关的主要节点如下所示, 因为 USB DTSI 节点配置的是 USB 控制器和 PHY 的公共资源和属性, 建议一般不要改动
USB 接口和 USB DTS 节点对应的关系如下表所示:
这些节点一般的配置情况在这里就不进行深究了, 具体要使用的时候可以参考file:///D:/BaiduNetdiskDownload/LPM3588/LPM3588SDK/Linux%E5%8E%9F%E5%8E%82%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3/Common/USB/Rockchip_RK3588_Developer_Guide_USB_CN.pdf
文档进行配置.
7.8. type-c VBUS 节点配置
7.8.1. vbus5v0_typec 节点
该节点对应的是 typec 口附近的 SY6280 供电模块.
neardi 节点配置:
该节点的 GPIO 使能引脚配置为 GPIO4_PA1
友善官方配置:
节点的 GPIO 使能引脚配置为: GPIO1_PD2
查看原厂板子原理图:
该节点背负着所有其它的 USB3.0 的供电模块引脚配置. 所以需要找出友善中对应的其它普通 usb3.0 将其修改上去.
7.8.1.1. 修改 typec 接口的供电模块使能引脚
fbus 所使用的 SY6280 供电模块引脚:
发现 neardi 中将 GPIO1_PD2 分配给了 TYPE-A 接口的模块, 但是目前使用不上. 直接注释掉.
// 2024-12-03 09:06:35 USB2.0 USB 3.0 HOST PORT 供电模块使能引脚控制
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
// vcc5v0_host_pwren: vcc5v0-host-pwren {
// rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
// };
};
// 2024-12-03 09:06:51 TYPC-C PORT 供电模块使能引脚控制
usb-typec {
usbc0_int: usbc0-int {
//rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
};
// typec5v_pwren: typec5v-pwren {
// rockchip,pins = <4 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
// };
typec5v_pwren: typec5v-pwren {
rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
这边也要对应进行修改.
切记, 一个节点如果使用了 pinctrl, 那么节点本身的 gpio 属性一般还会自己引用一次这个节点.
这样修改之后 TYPE-C 和 TYPE-A 接口均可以正常使用 USB3.0 接口, 并且 typec 的 DP 显示输出正常. 不清楚 TYPE-A 接口 USB3.0 的稳定性如何.
8. 小总结
这只是V1版本的一部分修改适配移植总结,一些像是USB3.0的这种不稳定情况如果没有专业的设备去分析是很难确定具体的问题的,因为硬件条件的不允许,我这边也就没有去做这个具体的硬件分析了。可以尝试软件上从寄存器层面 tuning 一下。
有什么问题也可以评论或者私信我,看看能不能帮上什么小忙呢
那就先这样吧。。。。
能看到这里说明你真的不简单,一看就是嵌入式先天圣体。
点赞关注一下吧,谢谢咯。