恩智浦社区成员,你们好、
我有一块装有 IMX6ULL 和高通 BT+WiFi 组合芯片的定制板。
该项目基于 Yocto kirkstone、linux-imx 5.15.71 内核版本。
mx6ull 和 qca9377 之间的通信方式是 sdio。
关于 mx6ull 和 qca9377 之间的 sdio 通信过程中偶尔出现的通信错误,我有几个问题。
1. 将 dts 设置为使用 132MHz 的 sdio 时钟速度
imx6ul-14x14-evk.dtsi
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
bus-width = <4>;
vmmc-supply = <®_sd1_vmmc>;
pm-ignore-notify;
keep-power-in-suspend;
non-removable;
status = "okay";
};
&iomuxc {
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0x130b0
>;
};
pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
>;
};
pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
>;
};
};mmc0 信息
# cat /sys/kernel/debug/mmc0/ios
clock: 132000000 Hz
actual clock: 132000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 2 (4 bits)
timing spec: 6 (sd uhs SDR104)
signal voltage: 1 (1.80 V)
driver type: 0 (driver type B)3. 有时会打印出如下 sdio 通信错误日志
AR6000: SDIO bus operation failed! MMC stack returned : -84
__HIFReadWrite, addr:0X001000, len:00000256, Read , Sync
Debug Assert Caught, File /usr/src/debug/kernel-module-qca9377/3.1-r0/git/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c, Line: 1459, Test:status == A_OK || status == A_ECANCELED"Change sdio clock speed (132MHz -> 50MHz)"1. 将 DTS 设置为使用 sdio 时钟速度为 50MHz。
imx6ul-14x14-evk.dtsi
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1>;
bus-width = <4>;
vmmc-supply = <®_sd1_vmmc>;
pm-ignore-notify;
keep-power-in-suspend;
non-removable;
status = "okay";
};mmc0 信息
# cat /sys/kernel/debug/mmc0/ios
clock: 50000000 Hz
actual clock: 44000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 2 (4 bits)
timing spec: 2 (sd high-speed)
signal voltage: 0 (3.30 V)
driver type: 0 (driver type B)不显示 sdio 通信错误日志。
1.当 sdio 时钟设置为 132MHz 时,mx6ull 和 qca9377 之间的 sdio 通信似乎不稳定。有没有办法通过修改 dts 值来改进它?
2.如果不可能,您建议使用什么值作为 sdio 时钟值?
提前谢谢您。
致以最诚挚的问候
请参阅数据表,SDR104/SDR50 模式的信号电平为 1.8 V。请检查您的硬件并仔细确认这一点
感谢您的快速回复。
关于问题 1,我想我大错特错了。很抱歉。
我检查了你提到的如下内容
""SD/SDIO UHS-I 模式(SDR 模式下最高 208 MHz,DDR 模式下最高 50 MHz)"
因此,如果我们在 mmc0 中使用 sdr104,最大时钟频率为 208MHz,那么有可能保证 132MHz 的时钟频率吗?
1.对于 eMMC(mmc1),HS200(132MHz/1.8V)似乎是有保证的、但对于 SDIO(mmc0),在 SDR104 模式下似乎只能保证高达 104MHz 的频率。请检查?
>请参阅数据表,最高可达 UHS-I SDR104 模式 104MB/s,不是 104Mhz max,请参阅 RM:SD/SDIO UHS-I 模式(SDR 模式下最高 208MHz,DDR 模式下最高 50MHz)
2.
(我想确认 MX6ULL 芯片是否能保证 SDIO 132MHz 的时钟速度)。
>您可以参阅数据表,对于 SDR104,频率最高可达 200Mhz,我们已经在 mmc0 上测试了 SDR104,频率最高可达 198Mhz,参阅您的日志,似乎您的 mmc1 可以在 HS200 下工作?
是的,您可以参考默认设置为 132M 的 dtsi 文件,也可以转储时钟树来检查时钟是否为 132Mhz
谢谢 joanxie、
我会再检查一下,看看是否真的是时钟速度问题,然后再问。
谢谢。
亲爱的 joanxie
根据您提供的信息,我使用下面的寄存器进行了测试。
sdhci-esdhc-imx.c
#define ESDHC_MIX_CTRL_SMPCLK_SEL (1<< 23)
#define ESDHC_MIX_CTRL_AUTO_TUNE_EN (1<< 24)
#define ESDHC_MIX_CTRL_FBCLK_SEL (1<< 25)
SMPCLK_SEL 0
AUTO_TUNE_EN 1
FBCLK_SEL 1
1. 测试
1) 设置 AUTO_TUNE_EN 1-> 0
2) 日志
[39.150703] AR6000:取消向总线驱动程序 注册
3) wlan0 注册失败
$ ifconfig wlan0 up
ifconfig:SIOCGIFFLAGS:没有这样的设备
2. 测试 2
1) 设置 FBCLK_SEL 1-> 0
2) 日志
[39.160750] AR6000:取消向总线驱动程序注册
3) wlan0 注册也失败 $ ifconfig wlan0 up ifconfig:SIOCGIFFLAGS:没有这样的设备
3. 测试 3
1) 设置 AUTO_TUNE_EN 1-> 0 & & FBCLK_SEL 1-> 0
2) 系统在启动时死机,如下面的日志所示 [18.834619] wlan:加载驱动程序 v4.5.25.65
[ 18.894917] hifDeviceInserted:Dumping clocks (50000000,132000000)
我试着参考恩智浦社区的文章对其进行修改和测试,但结果并不令人满意。
请注意
感谢您的帮助
我咨询了无线团队,他们已经通过 usdhc 验证了 imx6ull 的 WIFI,并且可以设置最大时钟频率为 150Mhz,因此对于 imx6ull 端,可以支持这一点,而且我发现一些 WIFI 芯片会影响自动运行,因此我建议您可以禁用这些寄存器来检查,如果这些不是根本原因,我建议您需要检查您的硬件和 PCB 设计,如果您无法确认这一点,您可以提交票据进行 SCHEMATIC 审核。
我咨询了无线团队,他们已经通过 usdhc 验证了 imx6ull 的 WIFI,并且可以设置最大时钟频率为 150Mhz,因此对于 imx6ull 端,可以支持这一点,而且我发现一些 WIFI 芯片会影响自动运行,因此我建议您可以禁用这些寄存器来检查,如果这些不是根本原因,我建议您需要检查您的硬件和 PCB 设计,如果您无法确认这一点,您可以提交票据进行 SCHEMATIC 审核。
这就是我之前谈到的,关于自动调谐影响故障的详细信息
很高兴听到这些补丁起作用了,但事实上新的 电路板支持包 已经合并了,据我所知,我没听见 imx6ull 和 wifi 芯片之间存在任何其他问题
亲爱的 joanxie
感谢您的友好指导。
我参照您提供的链接调试了这个问题。
1. 补丁 1
1) 参考您提供的链接使用补丁
https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/uSDHC-auto-tuning-and-possible-SDIO-f...
2. 补丁 2
1) 在 dts 文件上添加"fsl,sdio-async-interrupt-enabled"
imx6ul-14x14-evk.dtsi:
&usdhc1 {
fsl,sdio-async-interrupt-enabled; //add this line2) 以下部分已启用
sdhci-esdhc-imx.c: usdhc_auto_tuning_mode_sel()
/*
* If sdio device use async interrupt, it will use DAT[1] to signal
* the device's interrupt asynchronous when use 4 data lines.
* Then hardware auto tuning circuit MUST NOT check the DAT[1] line,
* otherwise auto tuning will be impacted by this async interrupt,
* and change the delay cell incorrectly, which then cause data/cmd
* errors.
* This is the hardware auto tuning circuit limitation.
*/
if (imx_data->boarddata.sdio_async_interrupt_enabled)
auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;打上上述补丁后,通过调试,问题没有再出现。
(sdio 时钟变化测试(50MHz->100MHz->132MHz)、ping 测试、iperf3 测试等)。
再问一个问题,确认一下你们的补丁指南。
如果我打上这个补丁,问题就会得到解决、
谢谢 joanxie、
我还检查了另一个 yocto 版本(imx-6.6.52、fslc-6.1.72)
我在 yocto scarthgap imx-6.6.52 版本上找到了类似的补丁,如下所示
/*
* For USDHC, auto tuning circuit can not handle the async sdio
* device interrupt correctly. When sdio device use 4 data lines,
* async sdio interrupt will use the shared DAT[1], if enable auto
* tuning circuit check these 4 data lines, include the DAT[1],
* this circuit will detect this interrupt, take this as a data on
* DAT[1], and adjust the delay cell wrongly.
* This is the hardware design limitation, to avoid this, for sdio
* device, config the auto tuning circuit only check DAT[0] and CMD
* line.
*/
if (imx_data->init_card_type == MMC_TYPE_SDIO)
auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
ESDHC_VEND_SPEC2);但未在 yocto scarthgap fslc-6.1.72 上打补丁版本。
我将根据您的指导检查其他 yocto 版本。
感谢您的支持。