2413637_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2413637_zh-CN

2413637_zh-CN

Linux 无法访问 LPSPI3 寄存器(读取设备内存时出现总线错误)——P11 EXP 上的外部 SPI 设备

摘要

我正在尝试在 FRDM-IMX93 板的P11 EXPI 接头上使用LPSPI3在 GPIO_IO08-11 上启动两个外部 MCP2515 CAN 控制器(Waveshare 2-CH CAN HAT,已确认在真正的 Raspberry Pi 上工作)(引脚与 UM12181 表 21 中 Raspberry Pi 兼容接头的位置相匹配)。

在修复了我能找到的所有设备树级问题(电源、引脚复用、片选、引脚控制断言-GPIO)之后,SPI 时钟 (SCK)始终无法在物理接头引脚上切换,并且直接读取 LPSPI3 块的寄存器会导致总线错误。另一个已知工作正常的外部设备(LPUART1)可以从相同的地址空间正常读取数据。这表明存在资源/总线访问限制(RDC 或类似限制),而不是 Linux 设备树中可以修复的问题。

板/软件

  • 开发板:FRDM-IMX93(恩智浦),SoC:MIMX9352CVVXMAB
  • BSP:NXP i.MX 发布发行版,内核版本 6.18.2-1.0.0-gf49f45233f7b
  • 目标外设:lpspi3(spi@42550000,别名在 /aliases 中为 spi2,通过 /proc/device-tree/__symbols__ 确认实际 dts 标签为 lpspi3)
  • 被测外部设备:CS0/CS1 上的 2 个 MCP2515(Waveshare 2 通道 CAN HAT)

已确认有效(已排除)

  1. 给排气歧管供电。reg_vexp_3v3 / reg_vexp_5v 是默认禁用的调节器固定节点(regulator_summary 显示 use=0)。通过覆盖片段添加了 regulator-always-on + regulator-boot-on,目标为 &reg_vexp_3v3 / &reg_vexp_5v(通过 __symbols__ 确认了真实标签)。事后验证 P11 上实际存在 3.3 V / 5 V 电压。
  2. Pinmux。使用 imx93-pinfunc.h 中的官方宏,GPIO_IO08‑11 已正确复用到 LPSPI3_PCS0/SIN/SOUT/SCK。对于这三个函数,input_reg/input_val 均为 0x0000/0x0,因此不需要 DAISY 链选择(通过宏检查排除,不需要单独的寄存器)。
  3. 芯片选择。cs-gpios = , (位操作 GPIO CS,与 NXP 针对此节点的上游板级支持模式相匹配)。通过 cat /sys/kernel/debug/gpio 和万用表/逻辑分析仪确认: CS0 切换正常,并且物理上连接到了接头引脚。
  4. pinctrl-assert-gpios。NXP自己的上游 &lpspi3 参考中包含 pinctrl-assert-gpios = <&pcal6408 0 GPIO_ACTIVE_HIGH>;(此行并未出现在大多数公开指南中,仅出现在板自己的 dts 补丁中)。已添加;通过 /proc/device-tree/__symbols__ 确认 pcal6408 已解析,并通过 cat /sys/kernel/debug/gpio 确认,一旦请求 lpspi3 的默认 pinctrl 状态,GPIO 就会被钳位(输出 hi)。
  5. 覆盖层涂抹顺畅。U-Boot 的 fdt apply 没有出现 FDT_ERR_NOTFOUND;/sys/bus/spi/devices/ 显示 SPI 内核已注册 spi2.0 和 spi2.1。
  6. ERR051608(LPSPI TCR[PRESCALE] 勘误)。已检查 spi-fsl-lpspi.c历史记录——该修复(fsl、imx93-spi 的 prescale_max = 1)已于 2024 年 8 月合并到主线版本 / 稳定版 6.6.51。& 6.10.10 2024 年 9 月,远早于此内核版本 (6.18.2),并且兼容字符串 (fsl,imx93-spi) 已存在于主板 dts 中,因此驱动程序应该自动应用此限制。虽然不能完全排除这种可能性(没有直接的注册确认实际写入了 PRESCALE 字段),但时间线强烈表明此事已经处理完毕。

实际症状

使用万用表探测物理 P11 引脚上的 CS0/CS1、MISO、MOSI、SCK,然后使用逻辑分析仪以 10–20 MSa/s 的采样率在 CS0 下降沿触发,同时不断重试传输(在循环中使用 spidev_test,以及通过 echo spi2.0 > /sys/bus/spi/drivers/mcp251x/bind 反复强制 mcp251x 重新探测):

  • CS0切换。经万用表和逻辑分析仪验证。
  • SCK 从不切换。平坦,无任何活动,无论持续尝试转移。
  • MOSI 从不切换。
  • 两个 MCP2515 的故障情况完全相同:mcp251x spi2.0/spi2.1:MCP251x 在复位后未进入配置模式 / 探测失败,错误代码为 110 (ETIMEDOUT) — 即驱动程序自身的 SPI 级复位 + 读取 CANSTAT 序列未得到响应,这与 SCK 从未离开 SoC 的情况一致。

根本原因已缩小到时钟/总线访问,而非设备树。

 
# clk_enable_count AND clk_prepare_count are both 0, despite the controller
# actively being used in a continuous retry loop
$ cat /sys/kernel/debug/clk/clk_summary | grep -i lpspi3
       lpspi3_root      0  0  0  50000000  0  0  50000  N  deviceless        no_connection_id
          lpspi3        0  0  0  50000000  0  0  50000  N  42550000.spi      per

$ cat /sys/kernel/debug/clk/lpspi3/clk_prepare_count
0

即使 42550000.spi(真正的绑定消费者)正在循环中积极尝试传输(spidev_test 循环,以及通过 echo spi2.0 > /sys/总线/spi/drivers/mcp251x/bind 反复强制 mcp251x 重新探测),lpspi3 的功能(每个)时钟显示 clk_enable_count=0 和 clk_prepare_count=0。clk_prepare() 是 clk_enable()之前的步骤——它甚至从未被调用,这表明驱动程序的传输路径(或其前面的 pm_runtime_get())从未到达该设备的时钟管理代码,而不是请求时钟然后无法开启。

我没有内核构建工具来添加跟踪点,所以我还无法判断这是 pm_runtime 恢复时静默执行空操作,还是缺少依赖项(例如,此板的 lpspi3 节点需要但没有的功率域引用),或者是此特定内核构建的 spi-fsl-lpspi.c 中的其他问题。

决定性的寄存器级测试——直接读取 devmem:

 
$ devmem 0x44380000 32        # LPUART1 base — known-good peripheral
0x04040007

$ devmem 0x42550000 32        # LPSPI3 base (VERID register)
Bus error (core dumped)

一个完全无关的、工作正常的外部设备(LPUART1,用于调试控制台)从相同的 CPU/总线上下文中读取数据正常; LPSPI3 的基地址在普通的 32 位读取中出现故障。我最初怀疑是该板特有的资源域控制器 (RDC) 式访问限制,但 NXP 社区的几个帖子(i.MX25/i.MX6ULL“devmem 返回总线错误”,i.MX8MP I2C 来自 DSP 的帖子)指出,同样的症状是触摸时钟被关闭的 AIPS 总线外设的正常预期结果,而不一定是安全/域限制。这与上面的 clk_enable_count=0 一致,现在让我觉得这是该设备的驱动程序/PM 路径中的时钟使能错误,而不是(不一定)RDC 块——尽管在没有底层工具的情况下,我无法完全排除 RDC 的可能性。

这并非 i.MX93 LPSPI3 的普遍限制

上下文:NXP 社区的另一个帖子([iMX93AUTO EVK] QCA7006AQ 的 SPI 配置,community.nxp.com/t5/i-MX-Processors/iMX93AUTO-EVK-SPI-Configuration-for-QCA7006AQ-with-imx93AUTO-EVK/m-p/1839847)展示了如何使用 LPSPI3 在i.MX93-11x11-EVK (同一 SoC)的相同 GPIO_IO08-11 引脚上成功驱动外部 SPI 设备:

 
c
&lpspi3 {
    compatible = "fsl,imx93-spi", "fsl,lpspi";
    cs-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
    status = "okay";
    ...
};
&iomuxc {
    pinctrl_lpspi3_qca: lpspi3grp {
        fsl,pins = <
            MX93_PAD_GPIO_IO11__LPSPI3_SCK   0x3fe
            MX93_PAD_GPIO_IO10__LPSPI3_SOUT  0x3fe
            MX93_PAD_GPIO_IO09__LPSPI3_SIN   0x3fe
            MX93_PAD_GPIO_IO08__LPSPI3_PCS0  0x3fe   /* native PCS0, not plain GPIO */
        >;
    };
};

我在 FRDM 板上尝试了完全相同的变体(使用原生 LPSPI3_PCS0/LPSPI3_PCS1 而不是普通的 GPIO2_IO08/GPIO2_IO07,加上显式兼容覆盖)——没有变化,devmem 0x42550000 32 仍然出错,clk_enable_count/clk_prepare_count 仍然为 0。这排除了引脚复用/兼容字符串选择是此板卡上的原因,并且——结合 EVK 的成功——让我怀疑是FRDM 板卡特有的问题(要么在 imx93-11x11-frdm.dts 中)。处理 lpspi3(或该板的 U-Boot/ATF 级 RDC/电源域设置)而不是一般的 i.MX93 SoC 或主线驱动程序的限制。

向恩智浦提出的问题

  1. 即使 SPI 内核正在积极地向绑定的 spi2.0/spi2.1 设备进行传输,lpspi3 的 clk_prepare_count/clk_enable_count 仍然保持为 0,并且普通的寄存器读取 0x42550000 会导致总线故障——FRDM-IMX93 的 lpspi3 设备树节点(或板级 RDC/电源域设置)缺少什么,而正常工作的 EVK 配置不需要这些?
  2. FRDM-IMX93 上的 LPSPI3 是否故意保留给另一个功能域(例如,Cortex-M33 / 安全世界,或板载 MAYA-W2 三射频模块路径)在板的默认 RDC/ATF 配置下,与 EVK 不同?
  3. 是否有类似 imx93-11x11-frdm-lpspi.dts 的参考文件,用于在该特定电路板上通过 P11 外部使用 LPSPI3?

如何重现

  1. 底板 dtb:随 i.MX 版本 发行版镜像一起提供的标准 imx93-11x11-frdm.dtb(未修改的 NXP lpspi3 + pcal6408 + reg_vexp_3v3/reg_vexp_5v 节点 — 全部通过 __symbols__ 确认存在)。
  2. 应用上述覆盖(稳压器始终开启,pinctrl + cs-gpios + pinctrl-assert-gpios on &lpspi3; 尝试了 plain-GPIO 和 native-PCS0/PCS1 pinmux 变体,两次结果相同)。
  3. 手动将 spidev(内置,CONFIG_SPI_SPIDEV=y)绑定到 spi2.0:
 
   echo spidev > /sys/bus/spi/devices/spi2.0/driver_override
   echo spi2.0 > /sys/bus/spi/drivers/spidev/bind
  1. spidev_test -D /dev/spidev2.0-s 1000000 -v — “成功”(无 I/O 错误),但即使 MOSI/MISO 物理短路,RX 数据也不是 TX 的环回;无论如何,逻辑分析仪上的 SCK 都不会切换。
  2. cat /sys/kernel/debug/clk/clk_summary | grep lpspi3 → clk_enable_count=0.
  3. cat /sys/kernel/debug/clk/lpspi3/clk_prepare_count → 0。
  4. devmem 0x42550000 32 → 总线错误。devmem 0x44380000 32 (LPUART1) → 正常成功。

如果需要,我很乐意提供完整的 overlay 源代码、dmesg 和 clk_summary/gpio 转储。

タグ(1)
評価なし
バージョン履歴
最終更新日:
1週間前
更新者: