Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(DRM Lima 編)







# 注意(2022年10月12日追記)


この記事は2021年4月に投稿したものであり、古い内容が含まれています。2022年10月に以下の記事を投稿しましたので参照してください。

・[『ZynqMP 向け Ubuntu22.04で Lima を動かしてみた(DRM Lima 編)』@Qiita]


# はじめに


[Lima] とは Mali-400/450 用のオープンソースなグラフィックドライバです。筆者は Lima を Ultra96/Ultra96-V2 向け Ubuntu 20.04 で試験的に動かしてみました。動かすのに少々苦労したので、その方法を何回かに分けて説明します。



  * [概要編] 
  *  __DRM Lima 編(この記事)__  
  * [DRI Lima 編]
  * [共有バッファ編]
  * [ストライド問題編]
  * [インストール編]
  * [Ubuntu Desktop ビルド編]



この記事では DRM Lima を Linux Kernel に組み込む方法を説明します。



  __なお、現時点(2021年4月)では、Ubuntu 20.04 の gnome-shell が動作するところまで確認していますが、すべてのアプリケーションで動作を確認したわけでは無いことに注意してください。__  


# DRM Lima とは


DRM Lima はMali-400/450 を制御するための Linux カーネルの DRM(Direct Rendering Manager) ドライバです。DRM ドライバは [DRI(Direct Rendering Infrastructure)] の Linuxカーネル部分のコンポーネントです。 


![Fig.1 DRM Lima](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/c10f5a19-3c4c-1f16-c92c-cfa122ed741a.jpeg "Fig.1 DRM Lima")

Fig.1 DRM Lima

<br />




# DRM Lima のビルド



## Kernel への組み込み


Linux Kernel 5.2 からはメインラインに DRM Lima が組み込まれています。ドライバのソースコードは drivers/gpu/drm/lima にあります。

linux-xlnx v2020.2 は Linux Kernel 5.4 をベースにしているので、DRM Lima が追加されています。しかしUltra96/Ultra96-V2 用に提供されているカーネルコンフィギュレーションファイル(xilinx_zynqmp_defconfig) では DRM Lima が組み込まれません。arch/arm64/configs/xilinx_zynqmp_defconfig に CONFIG_DRM_LIMA=y または CONFIG_DRM_LIMA=m を追加するか、 make menuconfig で Device Drivers > Graphics support > LIMA (DRM support for ARM Mali 400/450 GPU) を選択してください。


## Device Tree の設定


linux-xlnx v2020.2 の zynqmp 用の Device Tree には次の記述があります。


```devicetree:arch/arm64/boot/dts/xilinx/zynqmp.dtsi
	:
	(中略)
	:
	gpu: gpu@fd4b0000 {
		status = "disabled";
		compatible = "arm,mali-400", "arm,mali-utgard";
		reg = <0x0 0xfd4b0000 0x0 0x10000>;
		interrupt-parent = <&gic>;
		interrupts = <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>;
		interrupt-names = "IRQGP", "IRQGPMMU", "IRQPP0", "IRQPPMMU0", "IRQPP1", "IRQPPMMU1";
		clock-names = "gpu", "gpu_pp0", "gpu_pp1";
		power-domains = <&zynqmp_firmware PD_GPU>;
	};
	:
	(後略)

```


また、Ultra96 用の Device Tree には次の記述があります。




```devicetree:arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
/dts-v1/;
#include "zynqmp.dtsi"
	:
	(中略)
	:
&gpu {
	status = "okay";
};
	:
	(後略)

```




このことから、Ultra96 では GPU は有効になっているはずです。しかし、このままでは DRM Lima は動きません。実は、上で紹介した Device Tree は、DRM Lima 用ではなく Mali Driver 用だからです。

Device Tree を DRM Lima に対応させるためには、 gpu ノードのinterrupt-names プロパティとclock-names プロパティの値を変更する必要があります。




### 　interrupt-names プロパティ


Mali Driver と DRM Lima では割り込みの名前が異なります。DRM Lima では interrupt-names プロパティを次のようにします。


```devicetree:arch/arm64/boot/dts/xilinx/zynqmp.dtsi
		interrupts = <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>;
		interrupt-names = "gp", "gpmmu", "pp0", "ppmmu0", "pp1", "ppmmu1";
;

```





### 　clock-names プロパティ


Mali Driver と DRM Lima とでは想定してるクロックが異なります。Mali Driver が想定しているクロックは "gpu"、"gpu_pp0"、"gpu_pp1" の３つですが、Lima が想定しているクロックは "bus"、"core" の二つです。

このように名前が異なるだけでなく、想定しているクロックの種類が異なるため、単純にクロックの名前を変えるだけでは「通常は」上手くいきません。「通常なら」 DRM Lima のソースコードレベルで変更が必要です。

しかし、ZynqMP に関しては少しトリッキーですが Device Tree を修正するだけで動かすことが可能です。具体的には次のように "gpu_pp0" を "core" に、"gpu_pp1" を "bus" に変更します。


```devicetree:arch/arm64/boot/dts/xilinx/zynqmp.dtsi
		clock-names = "gpu", "core", "bus";

```


DRM Lima はまず "bus" の名前を持つクロックを有効にします。しかしこの Device Tree では実質的には "gpu_pp1" のクロックが有効になります。続いて "core" の名前を持つクロックを有効にします。しかし実質的には "gpu_pp0" のクロックが有効になります。

じゃあ "gpu" クロックはどうなるのか？　という疑問がわきますが、ZynqMP の場合は問題ありません。というのも ZynqMP では "gpu_pp0"、"gpu_pp1"、"gpu" は階層構造になっていて、"gpu" -> "gpu_pp0"、"gpu" -> "gpu_pp1" のように "gpu" クロック出力は "gpu_pp0" クロックの入力および "gpu_pp1" クロックの入力に接続されています。Linux Kernel のクロックドライバは、あるクロックを有効にしたときに階層にさかのぼって有効にします。したがって、"gpu_pp0" クロックを有効にした時点で "gpu" クロックも有効になります。




# DRM Lima の起動


DRM Lima を組み込んだ Linux Kernel を起動すると次のようなログがコンソール(or dmesg)にでます。


```Shell
shell$ dmesg
	:
	(中略)
	:
[    7.269921] lima fd4b0000.gpu: IRQ pmu not found
[    7.274750] lima fd4b0000.gpu: IRQ ppmmu2 not found
[    7.279683] lima fd4b0000.gpu: IRQ ppmmu3 not found
[    7.284718] lima fd4b0000.gpu: gp - mali400 version major 1 minor 1
[    7.291112] lima fd4b0000.gpu: pp0 - mali400 version major 1 minor 1
[    7.297575] lima fd4b0000.gpu: pp1 - mali400 version major 1 minor 1
[    7.304059] lima fd4b0000.gpu: IRQ pp2 not found
[    7.308708] lima fd4b0000.gpu: IRQ pp3 not found
[    7.313368] lima fd4b0000.gpu: l2 cache 64K, 4-way, 64byte cache line, 128bit external bus
[    7.330325] lima fd4b0000.gpu: bus rate = 499999995
[    7.335463] lima fd4b0000.gpu: mod rate = 499999995
[    7.360178] [drm] Initialized lima 1.0.0 20190217 for fd4b0000.gpu on minor 1
	:
	(後略)

```




また、/dev/dri の下に renderD128 が出来ます。


```Shell
shell$ ls -la /dev/dri
total 0
drwxr-xr-x  3 root root        120 Feb 14  2019 .
drwxr-xr-x 14 root root      13820 Feb 14  2019 ..
drwxr-xr-x  2 root root        100 Feb 14  2019 by-path
crw-rw----  1 root video  226,   0 Feb 14  2019 card0
crw-rw----  1 root video  226,   1 Feb 14  2019 card1
crw-rw----  1 root render 226, 128 Feb 14  2019 renderD128
```





# DRM Lima の問題点


DRM Lima を組み込んだ linux-xlnx v2020.2 を動かしてみましたが、現時点では次の二つの問題が生じました。

  * zocl と共存できない
  * 再起動に失敗する


## zocl と共存できない


zocl は XRT(Xilinx Runtime) のカーネルモジュールです。zocl および XRT に関しては以下の記事を参照してください。

* [『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(概要編)』@Qiita]



DRM Lima を組み込んだ状態で zocl を組み込むと、zocl のデバイスファイルが /dev/dri/renderD129 になります(renderD128 はすでに lima driver が使っている）。この状態で例えば [ZynqMP-XRT-Example-1-Ultra96] のサンプルプログラムを起動しようとすると次のようにデバイスが見つからないと言われます。


```Shell
shell$ ./streaming_lap_filter5.exe streaming_lap_filter5.xclbin
Using FPGA binary file specfied through the command line: streaming_lap_filter5.xclbin
XRT build version: 2.6.0
Build hash: 7104cc336e010e3e0755264ff832d811ff605e2c
Build date: 2020-03-24 21:07:36
Git branch: 2019.2_Ultra96
PID: 610
UID: 1000
[Tue Jun 23 10:12:10 2020]
HOST: debian-fpga
EXE: /home/fpga/examples/ZynqMP-FPGA-XRT-Example-1-Ultra96/streaming_lap_filter5.exe
[XRT] ERROR: No devices found
../src/krnl_streaming_lap_host3.cpp:71 Error calling err = cl::Platform::get(&platforms), error code is: -1
```




どうやら /dev/dri/renderD128 が zocl に割り当てられてないとうまく動かないようです。試しに lima driver を rmmod してから zocl をロードして /dev/dri/renderD128 を zocl に割り当てると正常に動作しました。




## 再起動に失敗する


一度 DRM Lima を rmmod してから modprobe で再起動しようとすると、次のようなログがでて再起動に失敗します。


```Shell
shell$ dmesg
	:
	(中略)
	:
[ 1758.651570] lima fd4b0000.gpu: IRQ pmu not found
[ 1758.656223] lima fd4b0000.gpu: mmu gpmmu dte write test fail
[ 1758.662084] lima: probe of fd4b0000.gpu failed with error -5
```




この件に関しては現在保留中です。




# 参考


* Lima web (https://gitlab.freedesktop.org/lima/web)
* https://github.com/ikwzm/ZynqMP-FPGA-Ubuntu20.04-Lima-Ultra96
* [『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(概要編)』@Qiita]


[概要編]: https://qiita.com/ikwzm/items/642df8c14fd3a9e782b6 "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(概要編)』@Qiita"
[DRM Lima 編]: https://qiita.com/ikwzm/items/91adfcf05e767d33be70 "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(DRM Lima 編)』@Qiita"
[DRI Lima 編]: https://qiita.com/ikwzm/items/ec29ae456ead67438733 "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(DRI Lima 編)』@Qiita"
[共有バッファ編]: https://qiita.com/ikwzm/items/ed2ce2d8bb90391d7c65 "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(共有バッファ編)』@Qiita"
[ストライド問題編]: https://qiita.com/ikwzm/items/5c4c0114c15cfba8e95b "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(ストライド問題編)』@Qiita"
[インストール編]: https://qiita.com/ikwzm/items/4dfb8f06ddf9d59e310c "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(インストール編)』@Qiita"
[Ubuntu Desktop ビルド編]: https://qiita.com/ikwzm/items/21a59e68d30ad9faad6a "『Ultra96/Ultra96-V2 向け Ubuntu20.04で Lima を動かしてみた(Ubuntu Desktop ビルド編)』@Qiita"
[『ZynqMP 向け Ubuntu22.04で Lima を動かしてみた(DRM Lima 編)』@Qiita]: https://qiita.com/ikwzm/items/465bcb51ab5a6ed8dbfb "『ZynqMP 向け Ubuntu22.04で Lima を動かしてみた(DRM Lima 編)』@Qiita"
[Lima]: https://gitlab.freedesktop.org/lima/web "Lima Website"
[DRI]: https://dri.freedesktop.org/wiki "Mesa 3D and Direct Rendering Infrastructure wiki"
[DRI(Direct Rendering Infrastructure)]: https://dri.freedesktop.org/wiki "Mesa 3D and Direct Rendering Infrastructure wiki"
[『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(概要編)』@Qiita]: https://qiita.com/ikwzm/items/0d3a8adfe725cd17f932 "『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(概要編)』@Qiita"