背景#
最近、5 インチ程度で 1080P 解像度、タッチ機能付きの MIPI ディスプレイを探している組み込みプロジェクトがあります。淘宝で検索したところ、適切で安価な 5.5 インチのディスプレイモジュールが約 95 元で見つかりました。さらにコストを削減するために、スマートフォンのディスプレイを利用できないか考え始めました。全面ディスプレイの時代以前、5.5 インチ、1080P はスマートフォンの主流の構成であり、選択肢はかなり多いはずです。ストックが豊富なため、ディスプレイモジュールの価格も競争力があるかもしれません。長い間、古いスマートフォンのディスプレイを見て羨ましく思っていました。これらのディスプレイは古いデバイスからのものであるにもかかわらず、表示品質は一般的な組み込みディスプレイモジュールをはるかに超えることが多く、利用できれば良いと思っています。
ただし、すべてのスマートフォンのディスプレイが簡単に使用できるわけではありません。スマートフォンのディスプレイを点灯させるための核心的な障害は、情報の欠如です。単独で販売される完成品のディスプレイモジュールは、一般的に仕様書や初期化資料を直接提供しますが、スマートフォンのディスプレイは公開されているソフトウェアやハードウェアの資料がほとんどありません。スマートフォンのディスプレイを駆動するには、2 つの大きな課題を解決する必要があります。
1 つ目は、ハードウェア上でディスプレイコネクタの型番とピン定義を知る必要があり、正しく電源と信号を接続できることです。理論的には、表示制御 IC の密集したピンから 1 つずつ追跡してコネクタに至ることができますが、大佬のように操作できる人もいますが、工数は非常に大きいです。より便利な方法は、スマートフォンの修理回路図を入手することです。膨大なスマートフォン修理市場のおかげで、多くの機種の回路図はネット上やいくつかの修理ツールで見つけることができます。回路図からは、ディスプレイコネクタのインターフェース定義やコネクタの型番を直接確認できます。
2 つ目は、ソフトウェア上でディスプレイの初期化シーケンスとタイミングを知る必要があります。これは一般的にスマートフォンのファームウェアから抽出できます。Qualcomm プラットフォームのデバイスの場合、デバイスツリーからタイミングと初期化シーケンスを取得できます(云犀 Box の記事のデバイスツリー抽出部分を参照)。このプロセスでは、実際にデバイスを所有する必要はなく、一般的にフラッシュパッケージがあれば抽出できます。また、一部の特別なデバイスはオープンソースコミュニティのサポートを受けており、比較的活発なプロジェクトである postmarketOS のようなものがあります。このようなデバイスについては、オープンソースコードリポジトリから必要なディスプレイ情報を直接取得できます。
そこで、私はソフトなターゲットを探し、適切なディスプレイを持ち、ハードウェアに回路図があり、ソフトウェアにソースコードがあるデバイスを見つけることに決めました。postmarketOS のサポートデバイスリストで探した結果、最終的に小米 5X(xiaomi-tissot)と紅米 5Plus(xiaomi-vince)に絞り込みました。これらのディスプレイモジュールは淘宝での価格が 40 元近くまで下がっています。私は 2 つのディスプレイを比較しました。
小米 5X のディスプレイは 5.5 インチ、1080x1920(16:9)、403 PPI、68% NTSC 色域です。モジュールは GFF 全貼り合せを採用しており、光学接着剤でタッチ層を上層のガラスカバーに貼り付けています。工法はシンプルですが、厚さがあり視覚効果がやや劣ります。画面が点灯していないときも、黒が純粋ではないと感じます。
紅米 5Plus のディスプレイは 5.99 インチ、1080x2160(18:9)、403 PPI、84% NTSC 色域です。同じディスプレイは小米 6X や紅米 5Plus にも使用されています。モジュールは Incell 全貼り合せ工法を採用しており、タッチユニットが下にあり LCM と融合しており、モジュールは薄く視覚効果が非常に透き通っています。
私は Android の 3 つのナビゲーションキーを全く必要としないため、ほぼ同じモジュールサイズでより大きな表示面積を得て、ある程度の「全面ディスプレイ」効果を得ることは非常に魅力的です。紅米 5Plus は間違いなくより優れた選択です。しかし、私が使用する予定の RV1126 SoC はデータシートでサポートされる最大解像度が 1920x1080 と記載されており、2160x1080 のディスプレイを駆動できるかどうかは疑問です。そこで、私は 2 種類のディスプレイを購入し、両方をテストする予定です。もし紅米 5Plus のディスプレイが完璧に互換性がない場合は、保険として小米 5X のディスプレイを選ぶしかありません。
ハードウェア#
回路図を分析した結果、小米 5X(上)と紅米 5Plus(下)のディスプレイインターフェース定義は非常に近いですが、使用されているコネクタは異なります。小米 5X が使用しているのは BM23PF0.8-40DS-0.35V(880)で、ピン間隔は 0.35mm です。紅米 5Plus が使用しているのは BM20B(0.8)-40DS-0.4V(51)で、間隔は 0.4mm です。両者はピン数は同じですが、間隔が異なり、互換性はありません。
回路図に基づいて、私はアダプタボードを作成しました。一方では信号変換を行い、ディスプレイの MIPI-DSI 信号、I2C 信号およびその他の制御 IO を、易百納 EB-RV1126-DC-201 開発ボードに適合するコネクタに接続します。もう一方では、開発ボードが提供する 3.3V 電源を利用して、バックライトに必要な高電圧、LCD に必要な正負電圧、および開発ボードが直接提供しない 1.8V IO 電圧を生成するための電源回路を搭載しています。
アダプタボードのハンダ付けが完了し、2 つのディスプレイがアダプタボードに接続され、これでハードウェアが準備完了し、ソフトウェアでディスプレイを操作できるようになります。
ソフトウェア#
Rockchip が提供するRockchip_DRM_Panel_Porting_Guideは、MIPI-DSI ディスプレイの一般的な操作を説明しています。これは Linux カーネルのpanel-simple-dsi
ドライバを利用しており、一般的なディスプレイの場合、個別にドライバを追加する手間を省き、デバイスツリーを修正するだけでドライバを完成させることができます。
panel-simple-dsi
の設定には、2 つの主要な情報を提供する必要があります。
- 初期化シーケンス(panel-init-sequence):一連の初期化コマンドを含み、各コマンドのルールは、各コマンドがヘッダーとデータペイロード(Payload)で構成され、すべて 16 進数で表されます。ヘッダーは 3 バイトで構成され、データタイプ(Data Type)、送信後の遅延(Delay, ms)、ペイロード長(Payload Length)を定義します。4 バイト目以降のデータは、長さが Payload Length のペイロードを表します。Data Type には以下の種類があります:
- 0x05: DCS Short WRITE. パラメータなし;
- 0x15: DCS Short WRITE. 1 パラメータ;
- 0x39: DCS Long Write/write LUT Command;
- 0x03: Generic Short WRITE, パラメータなし;
- 0x13: Generic Short WRITE. 1 パラメータ;
- 0x23: Generic Short WRITE, 2 パラメータ;
- 0x29: Generic Long Write;
- 表示タイミング(display-timings):ディスプレイのリフレッシュプロセス中の各時間パラメータを定義し、以下の各部分を完全に知る必要があります。
- Htotal = Hactive + Hfront-porch + HSync + Hback-porch
- Vtotal = Vactive + Vfront-porch + VSync + Vback-porch
- pixel-clock = Htotal × Vtotal × フレームレート
コミュニティのサポートが良好な小米 5X と紅米 5Plus については、msm8953-mainline
プロジェクトの lk2nd デバイスツリーからディスプレイ互換のドライバ名を見つけることができ、カーネルコード内で具体的なディスプレイドライバを見つけることができます。
例えば、小米 5X の場合、lk2nd/dts/msm8953-xiaomi-vince.dts at main · msm8953-mainline/lk2ndというデバイスツリーで使用されているディスプレイと対応する互換ドライバを見つけることができます。実際、以下に示すように、同じモデルのスマートフォンは複数のサプライヤーのディスプレイが関与している可能性があり、ディスプレイドライバ IC やタッチソリューションが異なる場合があるため、複数のエントリがあります。通常、ディスプレイモジュールの LCD_ID ピンに基づいて、または MIPI-DSI を介して特定のレジスタを読み取ることでディスプレイソリューションを判断し、異なる初期化を行う必要があります。しかし、今回は 1 つのディスプレイのテストだけを行うため、最も簡単な手動での逐次試行を選択しました。
panel {
compatible = "xiaomi,vince-panel";
qcom,mdss_dsi_td4310_fhdplus_video_e7 {
compatible = "xiaomi,td4310-fhdplus-e7";
touchscreen-compatible = "syna,rmi4-i2c";
// touchscreen-compatible = "novatek,nt36525-i2c";
};
// ...
qcom,mdss_dsi_nt36672_csot_fhdplus_video_e7 {
compatible = "xiaomi,nt36672-csot-fhdplus-e7";
touchscreen-compatible = "syna,rmi4-i2c";
// touchscreen-compatible = "novatek,nt36525-i2c";
};
};
その中の 1 つのxiaomi,nt36672-tianma-fhdplus-e7
の例として、対応するドライバコードはlinux/drivers/gpu/drm/panel/msm8953-generated/panel-xiaomi-nt36672-tianma-fhdplus-e7.c at 6.12/main · msm8953-mainline/linuxにあり、コードから情報を抽出し、正しい形式でpanel-simple-dsi
に対応するデバイスツリーのノードに記入するだけです。記入が完了すると、次のようになります:
&dsi {
status = "okay";
rockchip,lane-rate = <1000>;
dsi_panel: panel@0 {
status = "okay";
compatible = "simple-panel-dsi";
reg = <0>;
reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&dsi_rst_gpio>;
backlight = <&backlight>;
reset-delay-ms = <200>;
enable-delay-ms = <100>;
prepare-delay-ms = <20>;
unprepare-delay-ms = <20>;
disable-delay-ms = <20>;
init-delay-ms = <120>;
dsi,flags = <(MIPI_DSI_MODE_VIDEO |MIPI_DSI_MODE_VIDEO_BURST |MIPI_DSI_MODE_LPM |MIPI_DSI_MODE_EOT_PACKET)>;
dsi,format = <MIPI_DSI_FMT_RGB888>;
dsi,lanes = <4>;
/* panel-xiaomi-nt36672-tianma-fhdplus-e7.c/nt36672_tianmaplus_e7_on()関数に基づく */
panel-init-sequence = [
// DCS Short Write
05 78 01 11
// Generic Short Write
13 00 02 B0 04
// Generic Short Write
13 00 02 D6 01
// Generic Long Write
29 00 27 C7 00 19 28 3b 4a 55 6d 7d 8a 96 48 54 62 76 7f 8b 99 a4 b2 00 19 28 3b 4a 55 6d 7d 8a 96 48 54 62 76 7f 8b 99 a4 b2
// Generic Long Write
29 00 38 C8 03 00 01 03 ff fe 00 00 fe 01 fd f7 00 00 01 ff fb f2 00 00 01 03 01 ec 00 00 fe 01 fd f5 00 00 01 fe fa fe 00 00 01 03 ff fe 00 00 fe 01 fd ec 00 00 fe 01 fb d3 00
// DCS Long Write
39 00 03 51 ff 00
// DCS Short Write
15 00 02 53 24
// DCS Short Write
15 00 02 55 00
//DCS Short Write
15 00 02 35 00
// DCS Short Write
05 14 01 29
];
/* panel-exit-sequence */
panel-exit-sequence = [
05 14 01 28
05 78 01 10
];
disp_timings1: display-timings {
native-mode = <&dsi_timing0>;
dsi_timing0: timing0 {
clock-frequency = <148500000>;// (480+50+60+10)*(800+20+34+2)*60
hactive = <1080>;
hfront-porch = <108>;
hback-porch = <12>;
hsync-len = <60>;
vactive = <1920>;
vfront-porch = <166>;
vback-porch = <84>;
vsync-len = <33>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
swap-rb = <0>;
swap-rg = <0>;
swap-gb = <0>;
};
};
// ...
};
さらに、バックライト昇圧 IC には PWM 信号が必要で、これが有効化および調光制御に使用されます。ハードウェアはすでに接続されており、デバイスツリーにpwm-backlight
の汎用ドライバノードを追加するだけで、上記の dsi ノードもこのバックライトノードを参照しています。
backlight: backlight {
compatible = "pwm-backlight";
brightness-levels = <0 1 2 3 ... 255>;
default-brightness-level = <200>;
pwms = <&pwm7 0 25000 0>; // PWM7, 25kHz
};
テスト#
新しいデバイスツリーを持つカーネルイメージを書き込み、ターミナルに入った後、modetest -M rockchip -s 83@69:1080x1920
を使用してテストできます。
ディスプレイが真っ暗になるのが最も恐ろしいことで、ソフトウェアが正しく書かれていない場合やハードウェアが正しく接続されていない場合、同じように真っ暗になります。残念ながら、初回のテストではさまざまな初期化シーケンスを試みましたが、ディスプレイは真っ暗で、まったく反応しませんでした。Rockchip_DRM_Panel_Porting_Guideもトラブルシューティング方法を提供しており、MIPI-DSI の読み取り操作を通じて通信リンクが正常かどうかを判断できます。読み取りコマンドを panel-simple ドライバに追加することで、起動時に読み取りエラーが発生するかどうか、モードに変化があるかを観察できます。テストの結果、PCB のコネクタにケーブルを強く押し付けているときだけ正しく読み取れることがわかりました。実は、ハンダ付けが不十分な初歩的なミスでした。この種のコネクタはピン間隔が狭く、ピンパッドが非常に小さいため、ハンダ付けが難しく、何度も試行してようやくしっかりとハンダ付けできました。この問題を除去した後、ディスプレイは非常にスムーズに点灯しました。
最終効果#
小米 5X のディスプレイは正常に表示され、テスト画面や動画再生も正常で、期待通りの効果を達成しました。
予想通り、紅米 5Plus のディスプレイは RV1126 の制限により完璧には表示されません。デバイスツリーで直接vactive
を 2160 に設定すると、ドライバのprobe
段階で長さと幅がハードウェアの最大能力と比較され、最大能力 1920 を超えると初期化できなくなります。このチェックロジックを削除して強制的に初期化を試みても、表示内容は完全に乱れます。なんとか使える方法は、vactive
をハードウェアがサポートする 1920 に縮小し、余分な 240 をタイミングの他の部分に割り当てることです。こうすることで、ディスプレイは 1080x1920 の領域を正常に表示できますが、1080x240 は正常に表示できません。
結語#
この経験を通じて、スマートフォンのディスプレイを点灯させることは、ソフトウェアとハードウェアの資料が支援されている限り、時には難しくないことがわかりました(ネットで共有されているものでも、自分で逆解析したものでも)。スマートフォンのディスプレイが基本的に一般的な MIPI-DSI プロトコルを使用している場合、修理回路図とオープンファームウェアを持つスマートフォンのほとんどは、再利用の巨大な潜在能力を持っており、アマチュアの組み込みプロジェクトにとっては実行可能で経済的な選択肢です。
面白い例は、スマートフォン修理業界の「万能」ディスプレイテスターで、異なるケーブルと設定を交換することで大量のモバイルデバイスのディスプレイをテストできるものです。彼らがどのようにして大量のデバイスのタイミングと初期化シーケンスを取得しているのか、非常に興味があります。ドライバ IC の型番を把握して公版データを適用するのか、それともロジックアナライザを使用して DSI の低速初期化シーケンスをキャプチャして逆解析するのか、気になります。
最後に、今回使用したディスプレイは約 8 年前の製品であり、現在のスマートフォンディスプレイは大きな進歩を遂げています。たとえ紅米 Note 11T Pro のような LCD ディスプレイであっても、画面占有率が高く、高リフレッシュレート、広色域を持っています。さらに強力な OLED は言うまでもありません。今後は、より新しいスマートフォンのディスプレイに挑戦できることを期待しています。また、もう一つ研究したいのは、組み込み Linux 環境で ArgyllCMS などのオープンソースツールを利用してディスプレイのキャリブレーションを行い、プロジェクト内でも一定の専門的な色彩管理を実現し、これらのディスプレイに表示されるコンテンツが色彩的に正確であるようにすることです。