2413637_ja-JP

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

2413637_ja-JP

2413637_ja-JP

LPSPI3レジスタがLinuxからアクセス不能(devmem読み取り時のバスエラー)— P11 EXP上の外部SPIデバイス

概要

FRDM-IMX93ボードの P11 EXPIヘッダーLPSPI3 を使って、2つの外部MCP2515 CANコントローラー(Waveshare 2-CHAN HAT、本物のRaspberry Piで動作確認)を起動しようとしています(GPIO_IO08 UM12181表21参照、Raspberry-Pi互換ヘッダー位置に一致するピンです)。

見つけたデバイスツリーレベルの問題(電源、ピンマックス、チップセレクト、pinctrl-assert-gpio)をすべて修正した後、SPIクロック(SCK)は物理ヘッダーピンを切り替え 、LPSPI3ブロックの直接レジスタ読み込みは バスエラーを引き起こします。別の既知の動作ペリフェラル(LPUART1)は同じアドレス空間から問題なく読み返します。これはLinuxデバイスツリーから修正できるものではなく、リソース/バスアクセス制限(RDCなど)を示しています。

ボード/ソフトウェア

  • ボード:FRDM-IMX93(NXP)、SoC:MIMX9352CVVXMAB
  • BSP: NXP i.MX リリース ディストリビューション、カーネル 6.18.2-1.0.0-gf49f45233f7b
  • ターゲット周辺機器:lpspi3(spi@42550000、/aliasesでエイリアスされたspi2、/proc/device-tree/で確認された本物のdtsラベル__symbols__ lpspi3)
  • テスト中の外部デバイス:CS0/CS1上の2× MCP2515(Waveshare 2-CH CAN HAT)

既に動作が確認されているもの(除外されたもの)

  1. ヘッダーに電力を供給します。reg_vexp_3v3 / reg_vexp_5v は、デフォルトで無効になっているレギュレータ固定ノードです (regulator_summary では use=0 と表示されています)。レギュレーター常時オン+レギュレーターブートオンを追加し、オーバーレイフラグメントのターゲティング&reg_vexp_3v3/&reg_vexp_5vを追加しました( __symbols__で実際のラベルが確認されました)。その後、P11に3.3V/5Vの電圧が物理的に存在していることを確認しました。
  2. Pinmux。GPIO_IO08-11 は、imx93-pinfunc.h の公式マクロを使用して、LPSPI3_PCS0/SIN/SOUT/SCK に正しく多重化されています。input_reg/input_valはこれら3つの機能に対して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 でメインラインに取り込まれました。2024年9月6.10日は、このカーネルバージョン(6.18.2)よりずっと前のもので、互換文字列(fsl、imx93-spi)はすでにベースボードのdtsに存在しているため、ドライバはこの制限を自動的に適用すべきです。完全に否定できるわけではないが(実際にPRESCALEフィールドが書き込まれたという直接的なレジスタ確認はない)、タイムラインから判断すると既に処理済みである可能性が高い。

実際の症状

CS0/CS1、MISO、MOSI、SCKが物理的なP11ピン(マルチメーター、CS0落ち込みエッジで10〜20 MSa/sのロジックアナライザーをトリガー)でプローブしつつ、転送を繰り返し再試行(ループ内でspidev_testし、Echo spi2.0 > /sys/bus/spi/drivers/mcp251x/bindを経て繰り返しMCP251xの再プローブを強制することで別々に実行しました):

  • CS0の切り替え。マルチメーターとロジックアナライザーの両方で確認済み。
  • SCKは切り替えません。継続的に転送を試みても、変化はなく、活動は見られない。
  • MOSIは切り替えません。
  • 両方のMCP2515が同じように失敗します:mcp251x spi2.0/spi2.1:リセット/プローブ失敗後、MCP251xはコンフモードに入らなかった。err=110(ETIMEDOUT)。つまり、ドライバ自身のSPIレベルのリセット+read-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

LPSPI3の機能クロック(per)はclk_enable_count=0 clk_prepare_count=0を示します。これは425550000.SPI(実際のバインドされた消費者)がループ(spidev_testループ、そしてEcho SPI2.>0を経て/sys/bus/spi/ドライバ/mcp251x/bindを繰り返し強制してMCP251Xを再プローブを繰り返し試みている間でもです)。clk_prepare()はclk_enable() の前の ステップです。呼び出されないことから、ドライバーの転送経路(またはその前のpm_runtime_get())がこのデバイスの独自のクロック管理コードに到達しないことを示唆しており、クロックを要求してゲートオンに失敗したわけではありません。

トレースポイントを追加するカーネルビルドツールは持っていないので、これがサイレントノーオプスの繰り返しpm_runtimeなのか、依存関係が欠落しているのか(例:power-domainsがこのボードの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 return bus error」やi.MX8MP I2C-from-DSPスレッド)は、 クロックが制限されているAIPSバス周辺機器に触れた場合の正常で予想される症状 であり、必ずしもセキュリティやドメイン制限ではないと指摘しています。これは上記のclk_enable_count=0と一致しており、これはこの デバイスのドライバー/PMパスのクロック有効化バグであり、必ずしもRDCブロックではないと考えています。ただし、低レベルのツールがなければRDCを完全に除外することはできません。

これは一般的な i.MX93 LPSPI3 の制限ではありません

参考までに:別のNXPコミュニティThread([iMX93AUTO EVK] SPI Configuration for QCA7006AQ, community.nxp.com/t5/i-MX-Processors/iMX93AUTO-EVK-SPI-Configuration-for-QCA7006AQ-with-imx93AUTO-EVK/m-p/1839847)i.MX93-11x11-EVK (同じSoC)の同じGPIO_IO08-11ピン上で、LPSPI3を介して外部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 ボードでこのまったく同じバリアント (通常の GPIO2_IO08/GPIO2_IO07 の代わりにネイティブ LPSPI3_PCS0/LPSPI3_PCS1、さらに明示的な互換性オーバーライド) を試しましたが、変化はありませんでした。devmem 0x42550000 32 は依然としてフォルトを起こし、clk_enable_count/clk_prepare_count は依然として 0 です。これにより、このボードではピンmux/compatible-stringの選択が原因ではないことがわかり、EVKの成功と合わせて、 FRDMボード固有の何か(imx93-11x11-frdm.dtsのlpspi3 の処理、またはこのボードの U-Boot/ATF レベルの RDC/電源ドメイン設定)によるものであり、一般的な i.MX93 SoC またはメインラインドライバの制限ではありません。

NXPへの質問

  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 トライラジオモジュールパス)は、EVK とは異なり、ボードのデフォルトの RDC/ATF 構成で動作しますか?
  3. この特定のボードでP11経由でLPSPI3を外部から使用するための参照ファイルimx93-11x11-frdm-lpspi.dts(imx93-11x11-evk-lpspi.dtsに相当)はありますか?

再現方法

  1. ベースボードdtb: i.MXリリースディストリビューションイメージに同梱されている標準のimx93-11x11-frdm.dtb(変更されていないNXP lpspi3 + pcal6408 + reg_vexp_3v3/reg_vexp_5vノード - すべて__symbols__経由で存在が確認されています)。
  2. 上記のオーバーレイを適用します(レギュレータ常時オン、&lpspi3 上で pinctrl + cs-gpios + pinctrl-assert-gpios を使用。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) → 正常に成功しました。

必要であれば、オーバーレイのソースコード、dmesgログ、clk_summary/gpioダンプなど、すべての情報を提供いたします。

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