Armadilloフォーラム

Linux起動後USBデバイスを認識しない

hagihara

2023年4月21日 10時36分

お世話になっております。

Armadillo-610を搭載した弊社のカスタムボードでLinux起動後にUSBデバイスを認識しない症状が起こりました。
弊社ボードはUSBポート1をホストモードで使用し、ポート2は未使用です。
USBデバイスを接続した状態で起動すると認識しますが、起動後に抜き差しをするとまた認識しなくなります。

Armadillo-610 拡張ボードとの違いは、拡張ボードはハブIC(USB2513BT/M2)を使用しておりますが、弊社ボードはArmadillo-610とUSBデバイスを直繋ぎする構成です。
おそらくこれが原因ではないかと考えております。

調べたところ、同じような症状の報告のLinux kernelのメールアーカイブを見つけました。
https://lore.kernel.org/all/Y2F4tCMaB4x2fZck@francesco-nb.int.toradex.c…

上記ページを参考に以下のパッチをあてたところ、Linux起動後もUSBデバイスを認識するようになりました。

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index b4f0183f..1527a0bf 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -63,8 +63,7 @@ static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
-       .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-               CI_HDRC_TURN_VBUS_EARLY_ON |
+       .flags = CI_HDRC_TURN_VBUS_EARLY_ON |
                CI_HDRC_DISABLE_DEVICE_STREAMING,
 };
 
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 0e2f1a36..394e1fa9 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -155,7 +155,6 @@ static const struct mxs_phy_data imx6sx_phy_data = {
 };
 
 static const struct mxs_phy_data imx6ul_phy_data = {
-       .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 };
 
 static const struct of_device_id mxs_phy_dt_ids[] = {

この修正で問題無いかご教授いただけないでしょうか。
もしくは他の修正方法があればそれもご教授いただきたいです。

よろしくお願いします。

kernelはLinux 4.14-at50をベースに独自のドライバを追加しています。(USBとは関係ないドライバです。)
Linux 4.14-at50-gad519d16303b-dirty #5 Fri Apr 21 09:37:26 JST 2023

コメント

デバイスツリーのUSB部分は以下の通りです。

&usbotg1 {
	vbus-supply = <&reg_11>;
	dr_mode = "host";
	disable-over-current;
	status = "okay";
};
 
/ {
	regulators {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <0>;
 
        extreg_3v3: ext-regulator-3v3 {
                compatible = "regulator-fixed";
                regulator-name = "3V3";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
        };
		reg_11: regulator-11 {
			pinctrl-names = "default";
			pinctrl-0 = <&pinctrl_reg_11>;
			compatible = "regulator-fixed";
			regulator-name = "REG_11";
			regulator-min-microvolt = <5000000>;
			regulator-max-microvolt = <5000000>;
			startup-delay-us = <0>;
			regulator-ramp-delay = <0>;
			gpio = <&gpio1 19 GPIO_ACTIVE_HIGH>;
			enable-active-high;
		};
 
	};
 
	chosen {
		stdout-path = &uart1;
	};
 
	aliases {
 
	};
 
	vbus_sel: vbus-sel {
		compatible = "imx6-vbus-sel";
		otg1-vbus-reg-supply = <&reg_11>;
	};
 
};

溝渕です。

> Armadillo-610を搭載した弊社のカスタムボードでLinux起動後にUSBデバイスを認識しない症状が起こりました。
> 弊社ボードはUSBポート1をホストモードで使用し、ポート2は未使用です。
> USBデバイスを接続した状態で起動すると認識しますが、起動後に抜き差しをするとまた認識しなくなります。
>
> Armadillo-610 拡張ボードとの違いは、拡張ボードはハブIC(USB2513BT/M2)を使用しておりますが、弊社ボードはArmadillo-610とUSBデバイスを直繋ぎする構成です。
> おそらくこれが原因ではないかと考えております。

まず、USBコネクタのVBUS信号は、Armadillo-610(i.MX6ULL)のUSB_OTG1_VBUS(OTG2を利用している場合はUSB_OTG2_VBUS)に接続されていますか?

接続していない場合は、標準ソフトウェアではホットプラグ検出ができないと思います。

> この修正で問題無いかご教授いただけないでしょうか。

こちらで同様のハードウェア構成で動作させた実績が無いので何とも言えませんが、正しく動作しているのであれば良いのではないかと思います。

ただ、この修正だとUSBデバイスが接続されていない場合の消費電力が増大するように思います。もし消費電力に制限があり、どの程度増大するかを確認したい場合はruntime PMの有効/無効時で実測してみてください。

> もしくは他の修正方法があればそれもご教授いただきたいです。

ハードウェアの改版が可能で、かつUSB_OTG1_VBUS(またはUSB_OTG2_VBUS)が未接続の場合は、接続するのが良いと思います。

>まず、USBコネクタのVBUS信号は、Armadillo-610(i.MX6ULL)のUSB_OTG1_VBUS(OTG2を利用している場合はUSB_OTG2_VBUS)に接続されていますか?

接続しております。電圧測ったところ、約4.4Vでした。

Armadillo-610 拡張ボードを弊社カスタムボードと同じになるように以下の変更を加えて試しました。(USBポート1をホストモード、USBポート2を無効)

diff --git a/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi b/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi
index 27ce402f..30737022 100644
--- a/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi
+++ b/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi
@@ -199,21 +199,25 @@
 };
 
 &usbotg1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg1>;
+       // pinctrl-names = "default";
+       // pinctrl-0 = <&pinctrl_usbotg1>;
+       // vbus-supply = <&reg_usbotg1_vbus>;
+       // dr_mode = "otg";
+       // disable-over-current;
+       // status = "okay";
        vbus-supply = <&reg_usbotg1_vbus>;
-       dr_mode = "otg";
-       disable-over-current;
-       status = "okay";
-};
-
-&usbotg2 {
-       vbus-supply = <&reg_usbotg2_vbus>;
        dr_mode = "host";
        disable-over-current;
        status = "okay";
 };
 
+// &usbotg2 {
+//     vbus-supply = <&reg_usbotg2_vbus>;
+//     dr_mode = "host";
+//     disable-over-current;
+//     status = "okay";
+// };
+
 &usbphy2 {
        fsl,tx-d-cal = <106>;
 };

すると、弊社カスタムボードと同じ動きをしました。(起動後にUSBデバイスを接続しても認識しない。接続した状態で起動すると認識するが、起動後に抜き差しすると認識しなくなる。)
これに最初に投稿しましたパッチを当てると起動後でも認識するようになります。これも弊社カスタムボードと同じ動きです。

次にUSBポート1、2共にホストモードにしたところ、両ポートとも問題無く動作しました。
デバイスツリーの変更は以下の通りです。

diff --git a/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi b/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi
index 27ce402f..c309f8f1 100644
--- a/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi
+++ b/arch/arm/boot/dts/armadillo-610-extboard-eva-common.dtsi
@@ -199,10 +199,14 @@
 };
 
 &usbotg1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg1>;
+       // pinctrl-names = "default";
+       // pinctrl-0 = <&pinctrl_usbotg1>;
+       // vbus-supply = <&reg_usbotg1_vbus>;
+       // dr_mode = "otg";
+       // disable-over-current;
+       // status = "okay";
        vbus-supply = <&reg_usbotg1_vbus>;
-       dr_mode = "otg";
+       dr_mode = "host";
        disable-over-current;
        status = "okay";
 };

USBポート1だけをホストモードで使うというのは問題無い使い方なのでしょうか。
何かわかることあれば教えていただきたいです。

よろしくお願いします。

溝渕です。

> USBポート1だけをホストモードで使うというのは問題無い使い方なのでしょうか。

i.MX6ULLのエラッタERR010661には、次のように記載されています.
> Only four scenarios are supported:
> • One for OTG/Device, another for Host.
> • One for OTG/Device, another is un-used.
> • One for Host, another for Host.
> • One for Host, another is un-used.

上記より、一方をホスト、他方を未使用とする利用方法は問題ありません。

> 何かわかることあれば教えていただきたいです。

同様に、エラッタERR010661の"Workarounds"は次のように記載されています。
> Only one port can be used as OTG or device. The other port must be
> used as host. Set the PMU_REG_3P0.vbus_sel bit to select the host
> port.

i.MX6ULLの初期値では、USB_OTG2_VBUSをUSB coreの電源として利用しています。その対策として、以下のドライバを追加しています。
arch/arm/mach-imx/vbus_sel-imx6.c
デバイスツリーでは、compatible = "imx6-vbus-sel"でデバイスを作っています。

現状のこのドライバでは、PMU_REG_3P0.vbus_selを更新するタイミングが、VBUSのdisableだけであるので、今回のようなケースに対応できないかもしれません。

以下のパッチを適用の上で挙動を確認していただけませんか。

--- a/arch/arm/mach-imx/vbus_sel-imx6.c
+++ b/arch/arm/mach-imx/vbus_sel-imx6.c
@@ -16,6 +16,9 @@ static int imx6_vbus_sel_regulator_notify(struct notifier_block *nb,
        if (event == REGULATOR_EVENT_PRE_DISABLE) {
                /*1:USB_OTG1_VBUS, 0:USB_OTG2_VBUS*/
                imx_anatop_3p0_vbus_sel(&nb_otg1 != nb);
+       } else if (event == REGULATOR_EVENT_ENABLE) {
+               /*1:USB_OTG1_VBUS, 0:USB_OTG2_VBUS*/
+               imx_anatop_3p0_vbus_sel(&nb_otg1 == nb);
        }
 
        return NOTIFY_OK;

>以下のパッチを適用の上で挙動を確認していただけませんか。

ご提供いただいたパッチ試してみましたが症状変わりません。
追加したif文に入ってきて、&nb_otg1 == nbの部分がtrueになることは確認しました。

溝渕です。

> >以下のパッチを適用の上で挙動を確認していただけませんか。
>
> ご提供いただいたパッチ試してみましたが症状変わりません。
> 追加したif文に入ってきて、&nb_otg1 == nbの部分がtrueになることは確認しました。

usb core電源ののselectorの問題では無いのですね。

Armadillo-610 拡張ボードを使った再現手順をご提示いただいているので、こちらで再現及び修正を行ってみたいと思います。

> Armadillo-610 拡張ボードを使った再現手順をご提示いただいているので、こちらで再現及び修正を行ってみたいと思います。

お願いいたします。

USB_OTG1_VBUSの電圧が拡張ボードだと約4.38Vなのですが、以下の資料確認すると、範囲が4.40~5.5Vとなっています。
https://www.nxp.com/docs/en/data-sheet/IMX6ULLCEC.pdf
微妙に最低値を割っているのですが、これは問題にならないでしょうか。

溝渕です。

こちらでも同様の現象が再現できました。

環境は次の通りです。

ソースファイルは以下よりダウンロード可能なv4.14-at55を利用しています。

https://armadillo.atmark-techno.com/resources/software/armadillo-610/li…

ソースファイルの変更点は、ご提示いただいた通りです。
- usbotg1をhost modeに固定
- usbotg1のidピンのpinmuxを削除
- usbotg2を無効化

接続デバイスはUSBメモリで、microB to A変換アダプタを経由して、Armadillo-610 拡張ボードのCON6(USB OTG インターフェース)に接続しています。

電源投入後、USBデバイスを何度接続し直しても全数認識しませんでした。

> USB_OTG1_VBUSの電圧が拡張ボードだと約4.38Vなのですが、以下の資料確認すると、範囲が4.40~5.5Vとなっています。
> https://www.nxp.com/docs/en/data-sheet/IMX6ULLCEC.pdf
> 微妙に最低値を割っているのですが、これは問題にならないでしょうか。

vbus_sel-imx6.c
をカスタマイズして、USB core電源をOTG2に固定した上で、

"reg_usbotg2_vbus"に"regulator-always-on;"を追加(常時USB2_VBUSから供給)すると、USBメモリを認識するようになったので、ご指摘いただいた内容が問題を引き起している原因である可能性があります。

これから確認してみます。

溝渕です。

> > USB_OTG1_VBUSの電圧が拡張ボードだと約4.38Vなのですが、以下の資料確認すると、範囲が4.40~5.5Vとなっています。
> > https://www.nxp.com/docs/en/data-sheet/IMX6ULLCEC.pdf
> > 微妙に最低値を割っているのですが、これは問題にならないでしょうか。

これが問題です。ダイオードの電圧降下によって、i.MX6ULLのVBUSの要件を満せておりませんでした。

リファレンスとして不適切な部品を使用した結果、お手数をお掛けする結果となってしまい、大変申し訳ございません。

以下、確認した内容です。

Armadillo-610 拡張ボード(のUSB1_VBUSラインに)に搭載のダイオードをVfの小さいものに変更しました。変更後のダイオードは動作実績のあるArmadillo-640の同一箇所に利用されているものです。各型番は次の通りです。

Armadillo-610 拡張ボード: 1SS400SM
Armadillo-640: RB520S30T1G

変更後のUSB_OTG1_VBUSの電圧は約4.6Vとなり、i.MX6ULLのVBUSの要件を満たせております。この状態で、USBメモリの挿抜検出が可能であることが確認できました。

>変更後のUSB_OTG1_VBUSの電圧は約4.6Vとなり、i.MX6ULLのVBUSの要件を満たせております。この状態で、USBメモリの挿抜検出が可能であることが確認できました。

ご確認ありがとうございます。
弊社のカスタムボードでもUSB_OTG1_VBUSの電圧を上げて、USBデバイス認識することを確認できました。

ちなみにご提示いただいた以下のパッチを当てなくても動きました。

--- a/arch/arm/mach-imx/vbus_sel-imx6.c
+++ b/arch/arm/mach-imx/vbus_sel-imx6.c
@@ -16,6 +16,9 @@ static int imx6_vbus_sel_regulator_notify(struct notifier_block *nb,
        if (event == REGULATOR_EVENT_PRE_DISABLE) {
                /*1:USB_OTG1_VBUS, 0:USB_OTG2_VBUS*/
                imx_anatop_3p0_vbus_sel(&nb_otg1 != nb);
+       } else if (event == REGULATOR_EVENT_ENABLE) {
+               /*1:USB_OTG1_VBUS, 0:USB_OTG2_VBUS*/
+               imx_anatop_3p0_vbus_sel(&nb_otg1 == nb);
        }
 
        return NOTIFY_OK;

VBUS_SELの説明に以下のように「電圧が片方しか存在しない場合は自動選択する」とあるので、今回のようにポート2を未使用という使い方であればこのパッチは当てなくてよいという認識で合っているでしょうか。
If only one of the two VBUS voltages is present, it is automatically selected.

また、代用のダイオードの型番ご提示いただきありがとうございます。
ただ、このダイオードは必ず必要なものでしょうか。USB_OTG1_VBUSが入力専用であれば無くても大丈夫という認識ですが間違っているでしょうか。

溝渕です。

> VBUS_SELの説明に以下のように「電圧が片方しか存在しない場合は自動選択する」とあるので、今回のようにポート2を未使用という使い方であればこのパッチは当てなくてよいという認識で合っているでしょうか。
> If only one of the two VBUS voltages is present, it is automatically selected.

ご認識いただいている通り、パッチ適用の必要はありません。

> また、代用のダイオードの型番ご提示いただきありがとうございます。
> ただ、このダイオードは必ず必要なものでしょうか。USB_OTG1_VBUSが入力専用であれば無くても大丈夫という認識ですが間違っているでしょうか。

USB_OTG2_VBUSを利用しない前提であれば、ダイオードは不要です。

USB_OTG1_VBUSとUSB_OTG2_VBUSはi.MX6ULL内部で接続されているよう[※1]で、ダイオードが無い場合は、一方が他方に流れてしまいます。この為、VBUSにダイオードを接続しています。

※1: 一方に電圧を印加した場合、他方から断続的に出力される現象を確認しています。

>USB_OTG2_VBUSを利用しない前提であれば、ダイオードは不要です。
>USB_OTG1_VBUSとUSB_OTG2_VBUSはi.MX6ULL内部で接続されているよう[※1]で、ダイオードが無い場合は、一方が他方に流れてしまいます。この為、VBUSにダイオードを接続しています。

承知しました。

本件ご対応ありがとうございました。

溝渕です。

> 本件ご対応ありがとうございました。

こちらこぞ、本件についてご指摘いただき心より感謝しております。また、本件についてご迷惑をお掛けした事について重ねてお詫び申し上げます。

溝渕です。

本件で懸案となっている現象とは無関係と思いますが、

> 接続しております。電圧測ったところ、約4.4Vでした。

USBの規格上、USBホストから給電する場合のVBUSの電圧は4.75〜5.25Vが求められると思います。USBコネクタのVBUSの電圧も同等であれば動作しないUSBデバイスもあると思いますのでご注意ください。

ご注意ありがとうございます。
VBUSの電圧は5Vを確認しております。
Armadilloへの入力は拡張ボードと同じダイオードを使用しているので、その分の電圧降下です。