みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoProject DEBIX Model Aのカーネルを5.15に対応する

はじめに

DEBIX Model AをYoctoProjectで使いやすくするためにmeta-debixを作成した。

u-bootとカーネルは、DebixのGitHubリポジトリで公開されているものを使用していた。 それでは下記のような問題がある。

  • カーネルやu-bootのバージョンがあげられない
  • YoctoProjectのバージョンをあげたときにGPUドライバなどが使用できなくなる

imx-yocto-bspのカーネルとu-bootをDEBIX Model Aに対応するために、meta-debixにimx8mp-debix-aというマシンを定義する。 imx8mp-debix-aのポーティングは、DebixのGitHubリポジトリの修正をもとに筆者が独自に行う。

使用するYoctoProjectバージョン、マシンとカーネル、u-bootのバージョンの関係を以下に示す。

マシン カーネル u-boot YPバージョン
debix-a 5.10 2021.04 hardknott, kirkstone
imx8mp-debix-a 5.15 2022.04 kirkstone

DEBIX Model Aのモデルによって搭載されているペリフェラルに差異があるが、最低限オプションボードなどなしで、動かないと問題がありそうなペリフェラルだけに対応する。

現状で考えられるのは下記のペリフェラル

今回購入したのがeMMCなしのバージョンであることもあり、下記のペリフェラルはとりあえず対応しない。

特に無線関連は技適の問題もある。

対応状況

なにもパッチをあてない状態でどの程度動作するかを確認する。

ペリフェラル 動作 対応範囲
SDカード OK -
UART OK -
LPDDR4 NG u-boot
LAN(EQOS) NG u-boot
USB3.0 NG カーネル
HDMI OK

幸いなことにSDカードとUARTはリファレンスボードから変更が無い構成であるため、 比較的作業を開始しやすい。 このあたりが変更されている場合、回路図やデータシートなどが必要になってしまう。

LPDDR4に関してはタイミング設定のパラメータなどは基本的にツールで出力されたものをそのまま取り込むようにするはずなので、 DEBIXのリポジトリのものをそのまま取り込む。

LANとUSB3.0は必ずしも対応しなくてもよいが、無いといろいろ不便なので対応しておきたい。

作業手順

  • マシン定義の追加
  • u-bootのレシピ作成
  • カーネルのレシピ作成

今回はソースコードリポジトリはimx-yocto-bspのままでDEBIX Model Aに対応するため、 まずはhardknottで使用しているバージョンのリポジトリを比較し差分を調査してみる。

マシン定義の追加

すでにDEBIX Model A用に定義したdebix-aとは区別できるようにマシン定義を追加する。 imx-yocto-bspのカーネル、u-bootをベースにすることがわかりやすいように、imx8mp-debix-aとする。

u-bootのレシピ作成

u-bootでのリファレンスボードからの変更は下記のようになっている。

  1. LPDDR4
  2. LAN(EQOS)

LPDDR4

前述の通り、LPDDR4に関してはタイミング設定のパラメータなどは基本的にツールで出力されたものをそのまま取り込むようにするはずなので、 DEBIXのリポジトリのものをそのまま取り込むしか無い。

ただし使用するクロックの定義が足りていなかったので追加している。 これらの変更は両方ともdebixのリポジトリのものを参考にしている。

また、メモリのサイズも異なっているのでそれを調整するための修正も行っている。

LAN(EQOS)

MDIOで接続されるPHYのアドレスが変更されているのでそれに伴う修正を行う。 リセット信号の制御ピンが変更されているので、こちらも対応する。

また、u-bootのドライバがリセットピンの制御を簡略化したようでphy-reset-gpiosのプロパティが効かなくなっているので、 対応する必要がある。 debixのリポジトリでは、ドライバに直接修正を行いリセットピンが常にアクティブになるようになっている。

これらのことを踏まえて、リセットピンであるGPIO4_IO18に対してgpio-hogの機能を使用して、信号を出し続けるように設定変更する。

diff --git a/arch/arm/dts/imx8mp-evk.dts b/arch/arm/dts/imx8mp-evk.dts
index 61e8a70196..b2938d3075 100644
--- a/arch/arm/dts/imx8mp-evk.dts
+++ b/arch/arm/dts/imx8mp-evk.dts
@@ -130,10 +130,12 @@
        #address-cells = <1>;
        #size-cells = <0>;
 
-      ethphy0: ethernet-phy@1 {
+       ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
-          reg = <1>;
-          eee-broken-1000t;
+           reg = <0>;
+           at803x,led-act-blind-workaround;
+           at803x,eee-disabled;
+           at803x,vddio-1p8v;
        };
    };
 };
@@ -151,20 +153,33 @@
    phy-mode = "rgmii-id";
    phy-handle = <&ethphy1>;
    fsl,magic-packet;
-  status = "okay";
+   status = "disabled";
 
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;
 
-      ethphy1: ethernet-phy@1 {
+       ethphy1: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
-          reg = <1>;
-          eee-broken-1000t;
+           reg = <0>;
+           at803x,led-act-blind-workaround;
+           at803x,eee-disabled;
+           at803x,vddio-1p8v;
        };
    };
 };
 
+&gpio4 {
+   eqos-reset-hog {
+       gpio-hog;
+       gpios = <18 GPIO_ACTIVE_HIGH>;
+       output-high;
+       line-name = "eqos-reset";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_reg_eqos>;
+   };
+};
+
 &flexspi {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexspi0>;
@@ -505,7 +520,12 @@
            MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3       0x1f
            MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f
            MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK   0x1f
-          MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22       0x19
+       >;
+   };
+
+   pinctrl_reg_eqos: eqosreggrp {
+       fsl,pins = <
+           MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18  0x19
        >;
    };
 
@@ -525,7 +545,14 @@
            MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3     0x1f
            MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL  0x1f
            MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC     0x1f
-          MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02      0x19
+           MX8MP_IOMUXC_SAI1_RXD1__ENET1_1588_EVENT1_OUT   0x1f
+           MX8MP_IOMUXC_SAI1_RXD0__ENET1_1588_EVENT1_IN    0x1f
+       >;
+   };
+
+   pinctrl_reg_fec: fecreggrp {
+       fsl,pins = <
+           MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19  0x19
        >;
    };

カーネルのレシピ作成

カーネルでのリファレンスボードからの変更はいくつもあるようだが、現時点で対応するのはUSB3.0ハブのみとする。

USB3.0ハブ

USB3.0もdebixのリポジトリでは、リセットピンと、電源ピンをアクティブに固定するような修正が入っている。 いろいろ試した結果、電源ピンだけアクティブに固定すればUSB3.0が動作しているようなので、こちらもgpio-hogで対応する。

バイスツリーのファイルをimx8mp-debix-a.dtsとして新たに作成し、こちらを使用する。

+diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
+index 9a7319c6b4e3..3a6f6b9ae138 100644
+--- a/arch/arm64/boot/dts/freescale/Makefile
++++ b/arch/arm64/boot/dts/freescale/Makefile
+@@ -115,6 +115,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb imx8mp-evk-rm67191.dtb imx8mp-evk-it626
+             imx8mp-evk-hifiberry-dac2.dtb \
+             imx8mp-evk-usdhc1-m2.dtb imx8mp-evk-rm67199.dtb \
+             imx8mp-evk-dpdk.dtb imx8mp-evk-8mic-swpdm.dtb imx8mp-evk-rpmsg-lpv.dtb imx8mp-evk-revA3-8mic-revE.dtb
++dtb-$(CONFIG_ARCH_MXC) += imx8mp-debix-a.dtb
+ dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
+ dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-rpmsg.dtb imx8mp-ab2.dtb
+ dtb-$(CONFIG_ARCH_MXC) += imx8mp-ddr4-evk.dtb
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-a.dts
+new file mode 100644
+index 000000000000..e26e9209a4c8
+--- /dev/null
++++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-a.dts
+@@ -0,0 +1,40 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright 2019 NXP
++ * Copyright 2023 Yusuke Mitsuki <mickey.happygolucky@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "imx8mp-evk.dts"
++
++/ {
++  model = "DEBIX Model A board";
++
++  memory@40000000 {
++      device_type = "memory";
++      reg = <0x0 0x40000000 0 0x80000000>;
++  };
++};
++
++&usb_dwc3_1 {
++  dr_mode = "host";
++  status = "okay";
++};
++
++&gpio4 {
++  eqos-reset-hog {
++      gpio-hog;
++      gpios = <26 GPIO_ACTIVE_HIGH>;
++      output-high;
++      line-name = "dwc3-vbus";
++      pinctrl-names = "default";
++      pinctrl-0 = <&pinctrl_usb1_vbus>;
++  };
++};
++
++&pinctrl_usb1_vbus {
++  fsl,pins = <
++      MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26  0x19
++  >;
++};
+-- 
+2.25.1

ビルド・動作確認

imx-yocto-bspの5.15ベースのカーネルを使用するようにしたので、GPUドライバも使用可能となっている。 kirkstoneで5.10ベースのカーネルを使用する際の制限はなくなっているため、waylandなども使用できるようになっている。

一方でMIPIカメラなどのドライバは未対応となっているため、別途実装が必要になる可能性がある。

imx-image-full

imx-image-fullを作成する。

$ bitbake imx-image-full

westonとQt6ベースのデモアプリが動作している。

まとめ

DebixのGitHubリポジトリとimx-yocto-bspのソースコードを比較してみると、 Debix対応のために直接ソースコードを修正しているが、修正内容を精査するとデバイスツリーとコンフィグの修正だけで対応できるものが多いことがわかった。 今回の対応は基本的に電源やリセットの信号線をアクティブにする修正しか行っていない。

この様な対応でDEBIX Model Aで、5.15ベースのカーネルでもが使用できることがわかった。 GPU関連の機能も問題なく使用できているようだ。

本稿で記載した修正内容は抜粋であるため、ビルド可能なレイヤはGitHubのmeta-debixに格納してある。

DEBIX Model Aは比較的安価なi.MX8M Plus搭載のボードであるため、 5.15カーネルで動作できるようになったことで、活用の幅が広がれば良いなと思っている。