FPGA

【ZynqMP】1.1 AXI-GPIOが使えない?

1.記事一覧

記事は複数回に分けて投稿する予定です。AMD/XilinxのARM64 SoC(ZynqMP Kria K26 SOM)で動作する、AMD/Xilinx公式認定Ubuntuやベアメタル開発を勉強していく覚書きです。

Zynq7000(armv7)版はこちら

2.【概要】PL書込み後にGPIOが出てこない

【追記2023/9】このトラブルの原因の発端は私がデバイスツリー生成時にcloneしたDTGを適切なブランチにチェックアウトせず、masterブランチのまま生成したため、古い内容のDTSが生成されたのが原因です。つまるところXilinxさん側に何ら原因はなく、私が公式Docをよく読んでいなかったことに非があります。ただし、この原因調査ネタはそもそも謎解きネタとして書いているので、この経験は私の勉強としては価値があったと感じています。

前回の“1.認定UbuntuでPLのGPIO>>6-4. Devicetree Overlayソースを見てみる”のところで、Vivadoハードウェアエクスポートしたデータから自動生成したデバイスツリーソースを修正することになりました。その経緯を残しておこうと思います。

2-1. AXI-GPIOドライバ不具合の現象

不具合が見つかったのはxmutilコマンドによるオリジナルPLbitstreamの書込み後です。ファン制御が戻ったのを確認後、AXI-GPIOのI/Fを確認するため、/sys/class/gpio以下を見に行った際、新しく生成されるはずのgpiochipXXXが見つからないというものでした。

2-2. ドライバprobe時のエラーログ確認

デバイスツリーOverlay実行時に行われる、modprobeで何か不具合がないかログを確認しました。

ubuntu@kria:~$ cat /var/log/syslog |tail -n 30
[...]
Sep  3 00:02:12 kria kernel: [11734.154589] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-full/firmware-name
Sep  3 00:02:12 kria kernel: [11734.164713] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-full/resets
Sep  3 00:02:12 kria kernel: [11734.174395] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/overlay0
Sep  3 00:02:12 kria kernel: [11734.184246] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/overlay1
Sep  3 00:02:12 kria kernel: [11734.194094] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/afi0
Sep  3 00:02:12 kria kernel: [11734.203588] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/clocking0
Sep  3 00:02:12 kria kernel: [11734.213518] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/overlay2
Sep  3 00:02:12 kria kernel: [11734.223370] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/axi_gpio_0
Sep  3 00:02:13 kria kernel: [11734.241258] gpio-xilinx a0000000.gpio: #gpio-cells mismatch
Sep  3 00:02:13 kria kernel: [11734.246911] gpio-xilinx: probe of a0000000.gpio failed with error -22
[...]

11行目でgpio-xilinxデバイスドライバが”#gpio-cells mismatch”のメッセージを出して、その後probeエラーとなったようです。

2-3. ドライバのソースコードの確認

デバイスドライバの当該箇所のメッセージを出しているコードを確認します。Xilinx-Wikiを参考に、認定Ubuntuのソースコードを取ってきます。

KR260の現在のkernelを確認します。

ubuntu@kria:~$ uname -r
5.15.0-1023-xilinx-zynqmp

開発PCでLinux kernelソースコードをcloneします。
上記Xilinx-WikiではUbuntu20.04focalの例なので、22.04jammyに変更します。

$ git clone https://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-xilinx-zynqmp/+git/jammy
$ cd jammy
#KR260で動作している現在のkernelを探してチェックアウト
$ git tag |grep 1023
Ubuntu-xilinx-zynqmp-5.15.0-1023.27
$ git checkout Ubuntu-xilinx-zynqmp-5.15.0-1023.27

VSCodeなどのエディタでメッセージを探すと見つかりました。
/drivers/gpio/gpio-xilinx.c L.597

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Xilinx gpio driver for xps/axi_gpio IP.
 *
 * Copyright 2008 - 2013 Xilinx, Inc.
 */
//[...略]
static int xgpio_probe(struct platform_device *pdev)
{
//[...略]
    u32 cells = 2;
//[...略]
	/* Update cells with gpio-cells value */
	if (of_property_read_u32(np, "#gpio-cells", &cells))
		dev_dbg(&pdev->dev, "Missing gpio-cells property\n");

	if (cells != 2) {
		dev_err(&pdev->dev, "#gpio-cells mismatch\n");
		return -EINVAL;
	}
//[...略]
}
//[...略]
static struct platform_driver xgpio_plat_driver = {
	.probe		= xgpio_probe,
//[...略]
};
//[...略]

dev_err()で当該メッセージを出していました。cells変数が2以外はエラーのようです。

of_property_read_u32()は調べたところ、デバイスツリーの情報を読み出すAPIです。デバイスツリーの”#gpio-cells”の値を受け取っています。

XSCTで出力したデバイスツリーソースは#gpio-cells=<3>です。この値の違いがエラーの原因のようです。

ここまでのAXI-GPIOドライバの不具合をまとめ

  • KR260の現行AXI-GPIOドライバは、「#gpio-cells=<2>以外は絶対認めないマン」
  • VivadoとXSCTで生成したデバイスツリーでは#gpio-cells=<3>
  • なぜ食い違いが起こったのかは不明

2-4. そもそもデバイスツリーの#gpio-cellsとは何?

食い違いの原因が気になるので、#gpio-cellsの用途を調べます。カーネルソースの下記のパスにドライバのドキュメントがありました。

/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt

Xilinx plb/axi GPIO controller

Dual channel GPIO controller with configurable number of pins
(from 1 to 32 per channel). Every pin can be configured as
input/output/tristate. Both channels share the same global IRQ but
local interrupts can be enabled on channel basis.

Required properties:
- compatible : Should be "xlnx,xps-gpio-1.00.a"
- reg : Address and length of the register set for the device
- #gpio-cells : Should be two. The first cell is the pin number and the
  second cell is used to specify optional parameters (currently unused).
- gpio-controller : Marks the device node as a GPIO controller.

Optional properties:
- clocks : Input clock specifier. Refer to common clock bindings.
...

gpio-cells : 2つ必要。最初のセルはピン番号で、2番目のセルはオプションのパラメータを指定するのに使われる(現在は未使用).(機械翻訳)

だそうです。2番目が現在未使用で、1番目のみ使用しているにもかかわらず、生成ツリーでは3を指定しているということは、仕様のVerが食い違った可能性が高そうです。ドライバとデバイスツリー生成どちらの仕様が新しいのかはわからないですね。

2-5. XilinxのLinux kernelでコミットログを探る

認定UbuntuのLinux kernelはXilinxが提供しているものがベースと思われますので、コミットログを見てみたいと思います。

早速調査した結論を述べます。

★Xilinx Github のlinux-xlnxリポジトリのtag=xilinx-v2021.2 -> xilinx-v2022.1のリリース更新でAXI-GPIOドライバ(/drivers/gpio/gpio-xilinx.c)の仕様変更がありました。

Githubのリンクです。

ドキュメントは2021.1の時点で変更されたのですが、同時点でドライバのソースは新仕様から旧仕様に一度戻されてます。後方互換性維持のため戻したようです。移行猶予1年空けて次年度の2022.1で新仕様に移行しました。本当に最近ですね。

別の箇所でAXI-GPIOライン割込みのサポートが同時期に開発が進んでいたようなので、設計変更が活発に行われていたのだろうと思います。(ライン割込みどう使うんだろうか)

結局の所、XSCT(hsi)によるデバイスツリー生成の方は調べ方が不明なのでわからずじまいです。DTGのGithub見に行ったのですが、ここ数年のコミット履歴が無いのと、データ定義のようなファイル見ても最小限の情報しかなかったのでよくわかりませんでした。

2-6. AXI-GPIOドライバ不具合のまとめ

【追記】上でも書きましたが、根本原因はXSCTで使用したDTGで私が適切なブランチをチェックアウトせず、masterのままDevicetreeを生成したため、DTSが古いままになったのが原因です。つまり、公式Docをよく読んでいなかった私のミスです。

  • Xilinx提供カーネル linux-xlnx tag=v2022.1のとき、AXI-GPIOドライバ新仕様に移行
  • XSCT(hsi)によるデバイスツリー生成の更新具合は不明(追いついてないかも)
  • 暫定対応としてデバイスツリーは#gpio-cells = <2>に修正。ただしその影響範囲は不明
  • ツールとコードのVerのズレ、食い違いはよくあることなので、調査スキルが大事
  • デバイスツリーのパラメータ修正はドライバの書き方をよく理解していると良さそう
  • デバイスツリー対応のドライバ書いてみたい(願望)
  • 【追記】公式Docをよく読みましょう

ABOUT ME
sh-goto
組込エンジニア. 最近の遊びはLinuxの低レイヤいじりとXilinxのZynqとFPGAを使った電子工作
関連記事