はじめに
筆者は MPFS-DISCO-KIT(Microchip PolarFire SoC FPGA Discovery Kit) で動作する Ubuntu 22.04 を独自に構築しています。この記事では、この MPFS-DISCO-KIT 向け Ubuntu 22.04 で USER LED を GPIO ドライバを使って制御する方法を説明します。
MPFS-DISCO-KIT とは
MPFS-DISCO-KIT(Microchip PolarFire SoC FPGA Discovery Kit) は、Microchip Technology 社の PolarFire SoC FPGA(MPFS095T_1FCSG325E) を搭載した開発用のキットです。
- PolarFire SoC FPGA with 95k LEs
- 1GByte main memory
- 1x Gigabit Ethernet
- 3x UART
- 1x micro-SD interface
- Form factor 4.1" x3.3"
- 8x USER LED
- 8x DIP SWITCH
詳細は次の URL を参照してください。
MPFS-DISCO-KIT 向け Ubuntu 22.04 とは
筆者は MPFS-DISCO-KIT(Microchip PolarFire SoC FPGA Discovery Kit) で動作する Ubuntu 22.04 を独自に構築しています。以下の URL で公開しています。
なお、これらはオフシャルなものではなく、筆者の魔改造がはいっています。ご使用の際はこの点にご留意してください。
準備
polarfire-soc-discovery-kit-reference-design
この記事では FPGA(Fabric) にプログラムするデザインとして、polarfire-soc-discovery-kit-reference-design を利用します。これは MPFS-DISCO-KIT 用に Fabric部(FPGA部)に SRAM、I2C、GPIO、DMAなどを実装したリファレンスデザインです。この記事では USER LED の制御に Fabric部(FPGA部) にある GPIO を使います。
このリファレンスデザインのダウンロード、ビルド、MPFS-DISCO-KIT へのプログラムに関しては、以下の記事を参照してください。
MPFS-DISCO-KIT 向け Ubuntu 22.04 の起動
SD-Card に MPFS-DISCO-KIT 向け Ubuntu 22.04 を書き込んで MPFS-DISCO-KIT を起動します。
詳細は以下の記事を参照してください。
- 『MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(SD-Card 作成編)』@Qiita
- 『MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(SD-Card 起動編)』@Qiita
gpiod のインストール
この記事では gpio を制御するアプリケーションとして gpiod を使います。 パッケージをインストールしてください。
shell$ sudo apt install gpiod
デバイスツリーの用意
MPFS-DISCO-KIT 向け Ubuntu 22.04 では、FPGA(Fabric) にプログラムした IP を制御するためのデバイスドライバは Device Tree Overlay を使って Linux 起動後に動的にロードします。polarfire-soc-discovery-kit-reference-design では、USER LED は CoreGPIO という gpio コンポーネントに接続されています。そこで、次のような DTS(Device Tree Blob Source) を用意します。この DTS は gpio コンポーネントを Microchip 社提供の GPIO ドライバを使って制御するためのものです。
/dts-v1/; /plugin/;
/ {
fragment@0 {
target-path = "/fabric-bus@40000000";
#address-cells = <2>;
#size-cells = <2>;
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
clock_and_reset_0_fic_3_clk: clock_and_reset_0_fic_3_clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
};
core_gpio_c0: coregpio@40000100 {
compatible = "microchip,coregpio-rtl-v3";
reg = <0x0 0x40000100 0x0 0x0100>;
clocks = <&clock_and_reset_0_fic_3_clk>;
status = "okay";
};
};
};
};
これを dtc(Device Tree Compiler) を使って DTB(Device Tree Blob) に変換します。
shell$ dtc -I dts -O dtb -o core-gpio-c0.dtb core-gpio-c0.dts
デバイスツリーのオーバーレイ
core-gpio-c0.dtb を Device Tree に Overlay します。
shell$ sudo mkdir /sys/kernel/config/device-tree/overlays/core-gpio-c0
shell$ sudo cp core-gpio-c0.dtb /sys/kernel/config/device-tree/overlays/core-gpio-c0/dtbo
これで /sys/class/gpio に coregpio が見えるようなるはずです。以下の例では gpiochip568 として見えています。
shell$ ls -la /sys/class/gpio/
total 0
drwxr-xr-x 2 root root 0 Nov 22 2023 .
drwxr-xr-x 48 root root 0 Nov 22 2023 ..
--w------- 1 root root 4096 Nov 22 2023 export
lrwxrwxrwx 1 root root 0 Nov 22 2023 gpiochip512 -> ../../devices/platform/soc/20121000.gpio/gpio/gpiochip512
lrwxrwxrwx 1 root root 0 Nov 22 2023 gpiochip536 -> ../../devices/platform/soc/20122000.gpio/gpio/gpiochip536
lrwxrwxrwx 1 root root 0 Dec 24 10:44 gpiochip568 -> ../../devices/platform/fabric-bus@40000000/40000100.coregpio/gpio/gpiochip568
--w------- 1 root root 4096 Nov 22 2023 unexport
動作
gpioinfo
shell$ sudo gpioinfo
gpiochip0 - 24 lines:
line 0: unnamed unused output active-high
line 1: unnamed unused output active-high
line 2: unnamed unused output active-high
line 3: unnamed unused output active-high
line 4: unnamed unused output active-high
line 5: unnamed unused output active-high
line 6: unnamed unused output active-high
line 7: unnamed unused output active-high
line 8: unnamed unused output active-high
line 9: unnamed "led8" output active-high [used]
line 10: unnamed unused output active-high
line 11: unnamed unused output active-high
line 12: unnamed unused output active-high
line 13: unnamed unused output active-high
line 14: unnamed unused output active-high
line 15: unnamed unused output active-high
line 16: unnamed unused output active-high
line 17: unnamed unused output active-high
line 18: unnamed unused output active-high
line 19: unnamed unused output active-high
line 20: unnamed unused output active-high
line 21: unnamed unused output active-high
line 22: unnamed unused output active-high
line 23: unnamed unused output active-high
gpiochip1 - 32 lines:
line 0: unnamed unused output active-high
line 1: unnamed unused output active-high
line 2: unnamed unused output active-high
line 3: unnamed unused output active-high
line 4: unnamed unused output active-high
line 5: unnamed unused output active-high
line 6: unnamed unused output active-high
line 7: unnamed unused output active-high
line 8: unnamed unused output active-high
line 9: unnamed unused output active-high
line 10: unnamed unused output active-high
line 11: unnamed unused output active-high
line 12: unnamed unused output active-high
line 13: unnamed unused output active-high
line 14: unnamed unused output active-high
line 15: unnamed unused output active-high
line 16: unnamed unused output active-high
line 17: unnamed "led1" output active-high [used]
line 18: unnamed "led2" output active-high [used]
line 19: unnamed "led3" output active-high [used]
line 20: unnamed "led4" output active-high [used]
line 21: unnamed "led5" output active-high [used]
line 22: unnamed "led6" output active-high [used]
line 23: unnamed "led7" output active-high [used]
line 24: unnamed unused output active-high
line 25: unnamed unused output active-high
line 26: unnamed unused output active-high
line 27: unnamed unused output active-high
line 28: unnamed unused output active-high
line 29: unnamed unused output active-high
line 30: unnamed unused output active-high
line 31: unnamed unused output active-high
gpiochip2 - 32 lines:
line 0: unnamed unused output active-high
line 1: unnamed unused output active-high
line 2: unnamed unused output active-high
line 3: unnamed unused output active-high
line 4: unnamed unused output active-high
line 5: unnamed unused output active-high
line 6: unnamed unused output active-high
line 7: unnamed unused output active-high
line 8: unnamed unused output active-high
line 9: unnamed unused output active-high
line 10: unnamed unused output active-high
line 11: unnamed unused output active-high
line 12: unnamed unused output active-high
line 13: unnamed unused output active-high
line 14: unnamed unused output active-high
line 15: unnamed unused output active-high
line 16: unnamed unused output active-high
line 17: unnamed unused output active-high
line 18: unnamed unused output active-high
line 19: unnamed unused output active-high
line 20: unnamed unused output active-high
line 21: unnamed unused output active-high
line 22: unnamed unused output active-high
line 23: unnamed unused output active-high
line 24: unnamed unused output active-high
line 25: unnamed unused output active-high
line 26: unnamed unused output active-high
line 27: unnamed unused output active-high
line 28: unnamed unused output active-high
line 29: unnamed unused output active-high
line 30: unnamed unused output active-high
line 31: unnamed unused output active-high
USER LED1 点灯
shell$ sudo gpioset gpiochip2 0=1
USER LED1 消灯
shell$ sudo gpioset gpiochip2 0=0
USER LED2 点灯
shell$ sudo gpioset gpiochip2 1=1
USER LED2 消灯
shell$ sudo gpioset gpiochip2 1=0
後始末
デバイスツリーのリリース
オーバーレイしたデバイスツリーをリリースします。
shell$ sudo rmdir /sys/kernel/config/device-tree/overlays/core-gpio-c0
shell$ ls -la /sys/class/gpio
total 0
drwxr-xr-x 2 root root 0 Nov 22 2023 .
drwxr-xr-x 48 root root 0 Nov 22 2023 ..
--w------- 1 root root 4096 Nov 22 2023 export
lrwxrwxrwx 1 root root 0 Nov 22 2023 gpiochip512 -> ../../devices/platform/soc/20121000.gpio/gpio/gpiochip512
lrwxrwxrwx 1 root root 0 Nov 22 2023 gpiochip536 -> ../../devices/platform/soc/20122000.gpio/gpio/gpiochip536
--w------- 1 root root 4096 Nov 22 2023 unexport
ポイント
この記事のポイントは、DTS(Device Tree Blob Source) です。
/dts-v1/; /plugin/;
/ {
fragment@0 {
target-path = "/fabric-bus@40000000";
#address-cells = <2>;
#size-cells = <2>;
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
clock_and_reset_0_fic_3_clk: clock_and_reset_0_fic_3_clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
};
core_gpio_c0: coregpio@40000100 {
compatible = "microchip,coregpio-rtl-v3";
reg = <0x0 0x40000100 0x0 0x0100>;
clocks = <&clock_and_reset_0_fic_3_clk>;
status = "okay";
};
};
};
};
実はこの DTS の前は、次のような DTS を用意していました。
/dts-v1/; /plugin/;
#include "dt-bindings/clock/microchip,mpfs-clock.h"
/ {
fragment@0 {
target-path = "/fabric-bus@40000000";
#address-cells = <2>;
#size-cells = <2>;
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
core_gpio_c0: coregpio@40000100 {
compatible = "microchip,coregpio-rtl-v3";
reg = <0x0 0x40000100 0x0 0x0100>;
clocks = <&ccc_nw CLK_CCC_PLL0_OUT3>;
status = "okay";
};
};
};
};
この DTS は、Microchip Technology 社謹製の linux のデバイスツリーを元にしています。 残念ながら、この DTS では上手くいきませんでした。具体的には /sys/class/gpio に coregpio が見えなかったのです。どうやらデバイスドライバのロードに失敗しているようでした。
いろいろ調べてみたところ、clocks オプションで指定した clock ドライバ ccc_nw の status が disable になっているに気がつきました。試しに ccc_nw の stutus を okay にしてみましたが Linux Kernel が Panic を起しました。
polarfire-soc-discovery-kit-reference-design では Fabric に供給するクロックとして ccc(Clock Conditioning Circuitry) を使っています。ただし DRI(Dynamic Reconfiguration Interface) を disable にしていて、出力するクロックの週波数等は固定値に設定されています。
これは推測ですが、Linux Kernel にある ccc のデバイスドライバ drivers/clk/microchip/clk-mpfs-ccc.c は DRI が有効なときにしか動かないのではないでしょうか。
そこで、週波数が固定な clock ドライバ(fixed-clock)を定義して coregpio の clocks に設定してみました。そうすると、coregpio がロードされるようになりました。
これが最良な方法なのかわかりませんが、とりあえずご報告まで。
参考
MPFS-FPGA-Example-1-DISCO-KIT
ここで紹介した DTS(Device Tree Blob Source) は以下の URL で公開しています。
-
https://github.com/ikwzm/MPFS-FPGA-Example-1-DISCO-KIT
- examples/core-gpio/
MPFS-DISCO-KIT 向け Ubuntu 22.04 に関する記事
- 『MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(イントロ編)』@Qiita
- 『MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(HSS編)』@Qiita
- 『MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(SD-Card 作成編)』@Qiita
- 『MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(SD-Card 起動編)』@Qiita
- https://github.com/ikwzm/MPFS-FPGA-Ubuntu22.04
MPFS-DISCO-KIT 関連
CoreGPIO 関連
- https://www.microchip.com/en-us/products/fpgas-and-plds/ip-core-tools/coregpio
- https://ww1.microchip.com/downloads/aemdocuments/documents/fpga/ProductDocuments/SupportingCollateral/CoreGPIO_HB.pdf