RGB并行屏输出—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
MIPI 那套软排会了。今天换并行 RGB:模组便宜,同步极性抄错就会花屏。
LVDS 走差分、JEIDA、同步低有效。RGB 并行把时钟、HSYNC、VSYNC、DE 和 24 根数据线直接拉到座子上。常见那块玻璃是 1024×600,像素时钟 65 MHz,RGB888。DRM 连接器名字叫 card0-DPI-1,不是 LVDS-1,也不是 HDMI-A-1。
两件和 LVDS 相反的事,抄错就花、或者能亮不能点。
第一件:同步极性。RGB 这组 hsync / vsync / de / pixelclk 全是高有效。LVDS 那组是 0。porch 数字也不是同一份。时钟从 51.2 改成 65,极性还留着 0,屏不锁。
第二件:pinctrl。公版 lcdc_ctl 把 24 根数据都占上。这块底板要把 d0–d2、d8–d9、d16–d18 裁掉,腾出 GPIO3_B1 / GPIO3_B2。这两只脚是 RGB 屏上那颗 FT5406 的 RST 和 INT。不裁,触摸脚变成 LCD 数据线,I2C 地址或许还能扫到,中断永远进不来。
产品名 rk3568_evb。改的文件:
device/board/rk/rk3568_evb/kernel/rk3568-evb-linux.dts
四选一:开 RGB,HDMI / LVDS / MIPI / eDP 全部关掉。video_phy0 也要关——那是 LVDS 的 PHY,和 RGB 管脚打架。dtsi 里 &route_rgb 默认 disabled,必须显式打开,否则 VOP 不连 RGB,控制器 okay 了也没扫描。


现象:LVDS 那份 dts 改了时钟,屏花或者不亮
你以为 RGB 就是「LVDS 换个时钟」。clock-frequency 写成 65000000,其余从 lvds-panel 原样留下。
原因
bus-format 不同。LVDS 是 RGB888_1X7X4_JEIDA,差分四组。RGB 是 MEDIA_BUS_FMT_RGB888_1X24,并行 24 bit。JEIDA 留在 RGB 节点上,通道映射是错的。
极性不同。LVDS 四个 *-active = <0>。RGB 四个都是 <1>。注释里写过「TFT 高有效」,不是装饰。
连接器不同。summary 里要找 DPI-1,clk 约 65000。你还在盯 LVDS-1,会以为没起来。
座子也不同。LVDS 的排线插到 RGB 座上,电气对不上。软件全绿,玻璃仍是黑的。先认丝印,再改 dts。
代码:panel 节点
tft_lcd_panel: tft-lcd-panel {
status = "okay";
compatible = "simple-panel";
backlight = <&backlight>;
bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
display-timings {
native-mode = <&rgb_timing0>;
rgb_timing0: rgb-timing0 {
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hsync-len = <20>;
hback-porch = <160>;
vfront-porch = <12>;
vsync-len = <3>;
vback-porch = <23>;
hsync-active = <1>;
vsync-active = <1>;
de-active = <1>;
pixelclk-active = <1>;
};
};
port {
panel_in_rgb: endpoint {
remote-endpoint = <&rgb_out_panel>;
};
};
};
backlight = <&backlight> 不要省。PWM4 是这块板背光的唯一消费者。Linux 树里这份节点有时没写 phandle,开源鸿蒙这边要补上,否则链路在扫、玻璃不亮。
&lvds_panel 必须 disabled。两个 simple-panel 同时 okay,永远 connected 的那两路去抢主显示。RGB 常常比别的口晚注册,桌面渲到 LVDS-1 上,那头没接屏。真屏只有背光。
现象:控制器 okay 了,summary 里没有 DPI-1
&rgb { status = "okay"; } 写了。/sys/class/drm/ 没有 card0-DPI-1,或者有连接器但 VP 没 ACTIVE。
原因
四件套里漏了 &route_rgb。dtsi 默认它是 disabled。LVDS 那路你习惯写 &route_lvds,RGB 照抄的时候漏了这一段。VOP 不把 VP2 接到 RGB 出口,控制器独自 okay,扫描没有终点。
&rgb_in_vp2 也要 okay。入口和 route 的 connect = <&vp2_out_rgb> 必须成对。写成 VP0 的出口,和 HDMI / eDP 抢带宽,路由乱。
video_phy0 若还 okay,LVDS PHY 和 RGB 管脚打架。开 RGB 时 PHY 关掉。
代码:四件套加关 PHY
&video_phy0 { status = "disabled"; };
&rgb_in_vp2 { status = "okay"; };
&rgb {
status = "okay";
ports {
port@1 {
reg = <1>;
rgb_out_panel: endpoint {
remote-endpoint = <&panel_in_rgb>;
};
};
};
};
&route_rgb {
status = "okay";
connect = <&vp2_out_rgb>;
};
其余口成组关:
&hdmi { status = "disabled"; };
&hdmi_in_vp0 { status = "disabled"; };
&hdmi_in_vp1 { status = "disabled"; };
&route_hdmi { status = "disabled"; };
&lvds { status = "disabled"; };
&lvds_in_vp2 { status = "disabled"; };
&route_lvds { status = "disabled"; };
&lvds_panel { status = "disabled"; };
&edp { status = "disabled"; };
&edp_in_vp0 { status = "disabled"; };
&edp_panel { status = "disabled"; };
&dsi1 { status = "disabled"; };
&dsi1_in_vp0 { status = "disabled"; };
&dsi1_in_vp1 { status = "disabled"; };
&route_dsi1 { status = "disabled"; };
&dsi0 { status = "disabled"; };
&dsi0_panel { compatible = "simple-panel-dsi-disabled"; };
&dsi0_in_vp0 { status = "disabled"; };
&dsi0_in_vp1 { status = "disabled"; };
&route_dsi0 { status = "disabled"; };
DSI panel 只改 status 不够,compatible 也要改。HDF of_find_compatible_node("simple-panel-dsi") 不看控制器是否 disabled。MIPI 那篇写过,RGB 这条路上它会再咬一口:card0 不建,DPI-1 更不会出现。
RGB 和 VGA 插座若共用同一组 LCDC 管脚,不能一起 okay。开源鸿蒙不要学某些 Linux 镜像的双开。
现象:画面在,FT5406 扫得到,划不动
i2cdetect 在 I2C2 上看到 0x38。HDF 日志说 reset 过了。手指划过去,桌面没反应,或者偶发一个点。
原因
公版 lcdc_ctl 把 GPIO3_B1、GPIO3_B2 复用成 LCD 数据线(d16 / d17 附近那一组)。RGB 屏上的 FT5406,INT = GPIO3_B2(106),RST = GPIO3_B1(105)。脚被 LCD 占着,芯片靠上电能 ACK 地址,复位和中断是死的。
裁剪的规则:去掉 d0–d2、d8–d9、d16–d18,保留时钟、DE、HSYNC、VSYNC 和剩下的数据。24 bit 看起来少了几根,这块 1024×600 的屏按这个接法就是这么走的。不要为了「数据要齐 24 根」把触摸脚填回去。
HCS 必须用 105 / 106 这一对。MIPI 那颗 FT5406 用 82 / 36,LVDS 的 GT911 用 23 / 88。三套脚不能混。solutionX/Y = 1024/600。内核 edt-ft5x06 节点保持 disabled。
I2C2 降到 100 kHz。FPC 负载大,400 kHz 下 0x38 可以全部 NACK。
代码:裁 lcdc_ctl
&lcdc_ctl {
rockchip,pins =
/* lcdc_clk */
<3 RK_PA0 1 &pcfg_pull_none>,
/* lcdc_d3 */
<2 RK_PD3 1 &pcfg_pull_none>,
/* lcdc_d4 */
<2 RK_PD4 1 &pcfg_pull_none>,
/* lcdc_d5 */
<2 RK_PD5 1 &pcfg_pull_none>,
/* lcdc_d6 */
<2 RK_PD6 1 &pcfg_pull_none>,
/* lcdc_d7 */
<2 RK_PD7 1 &pcfg_pull_none>,
/* lcdc_d10 */
<3 RK_PA3 1 &pcfg_pull_none>,
/* lcdc_d11 */
<3 RK_PA4 1 &pcfg_pull_none>,
/* lcdc_d12 */
<3 RK_PA5 1 &pcfg_pull_none>,
/* lcdc_d13 */
<3 RK_PA6 1 &pcfg_pull_none>,
/* lcdc_d14 */
<3 RK_PA7 1 &pcfg_pull_none>,
/* lcdc_d15 */
<3 RK_PB0 1 &pcfg_pull_none>,
/* lcdc_d19 */
<3 RK_PB4 1 &pcfg_pull_none>,
/* lcdc_d20 */
<3 RK_PB5 1 &pcfg_pull_none>,
/* lcdc_d21 */
<3 RK_PB6 1 &pcfg_pull_none>,
/* lcdc_d22 */
<3 RK_PB7 1 &pcfg_pull_none>,
/* lcdc_d23 */
<3 RK_PC0 1 &pcfg_pull_none>,
/* lcdc_den */
<3 RK_PC3 1 &pcfg_pull_none>,
/* lcdc_hsync */
<3 RK_PC1 1 &pcfg_pull_none>,
/* lcdc_vsync */
<3 RK_PC2 1 &pcfg_pull_none>;
};
I2C2 和内核占位节点:
&i2c2 {
status = "okay";
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c2m1_xfer &ft5x06_int_pin &ft5x06_rst_pin>;
ft5406_rgb: touchscreen@38 {
compatible = "edt,edt-ft5406";
reg = <0x38>;
interrupt-parent = <&gpio3>;
interrupts = <RK_PB2 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;
touchscreen-size-x = <1024>;
touchscreen-size-y = <600>;
status = "disabled";
};
gt911_lvds: gt911@5d {
compatible = "goodix,gt911";
reg = <0x5d>;
status = "disabled";
};
};
HCS:moduleName = "HDF_TOUCH_FT5406",busNum = 2,rstGpio = 105,intGpio = 106,solutionX = 1024,solutionY = 600。公版芯片驱动里若还有按 720×1280 做的 X/Y 镜像,RGB 这条路上要拿掉,否则点下去左右反。FT5406 那篇写镜像,这里不重复。
验收:
hdc shell "i2cdetect -y -r 2"
hdc shell "i2cget -y 2 0x38 0xa3"
hdc shell "mount -t debugfs none /sys/kernel/debug"
hdc shell "cat /sys/kernel/debug/gpio | grep -E '105|106|PB1|PB2'"
hdc shell "cat /proc/bus/input/devices"
期望 0x38 有应答,0x5d 没有。105 / 106 是 GPIO,不是 lcdc 功能。被标成 lcdc 占用,裁剪没生效,dtb 还是旧的。
现象:改了 dts,summary 仍是 LVDS-1、clk 51200
原因
生效 DTB 在 resource 分区 p4 的 rk-kernel.dtb。只刷 p5,U-Boot 仍用旧树。RGB 的 65 MHz 写在你的 dts 里,板上走的是 LVDS 的 51.2 MHz。
GN 不盯 board 目录。你改了 rk3568-evb-linux.dts,ninja 认为内核没变,dtb 根本没重编。
代码
rm -rf out/kernel/checkpoint
cp device/board/rk/rk3568_evb/kernel/rk3568-evb-linux.dts \
out/kernel/src_tmp/linux-5.10/arch/arm64/boot/dts/rockchip/rk3568-evb-linux.dts
export PATH=$ROOT/prebuilts/clang/ohos/linux-x86_64/llvm/bin:$PATH
export KBUILD_OUTPUT=$ROOT/out/kernel/OBJ/linux-5.10
cd $ROOT/out/kernel/src_tmp/linux-5.10
make LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 \
O=$KBUILD_OUTPUT rockchip/rk3568-evb-linux.dtb -j$(nproc)
dtc=$KBUILD_OUTPUT/scripts/dtc/dtc
$dtc -I dtb -O dts -o /tmp/now.dts \
$KBUILD_OUTPUT/arch/arm64/boot/dts/rockchip/rk3568-evb-linux.dtb
grep -n '65000000\|tft-lcd-panel\|route_rgb' /tmp/now.dts
没有 65 MHz 这串数字,不要刷。有了,打进 resource 和 boot_linux:
hdc shell "cat /proc/partitions"
hdc file send resource.img /data/resource.img
hdc file send boot_linux.img /data/boot_linux.img
hdc shell "dd if=/data/resource.img of=/dev/block/mmcblk1p4 bs=4M conv=fsync"
hdc shell "dd if=/data/resource.img of=/dev/block/mmcblk0p4 bs=4M conv=fsync"
hdc shell "dd if=/data/boot_linux.img of=/dev/block/mmcblk1p5 bs=4M conv=fsync"
路径带 /dev/block/。少了 block,假成功。
验收:先认盘,再认 DPI-1,再认 65 MHz
hdc shell "cat /proc/partitions"
hdc shell "mount | grep ' on / '"
hdc shell "dmesg | grep -iE '\\[drm\\] Initialized|rgb|dpi|simple-panel|vop'"
hdc shell "ls -l /dev/dri/"
hdc shell "ls /sys/class/drm/"
hdc shell "cat /sys/class/drm/card0-DPI-1/status"
hdc shell "cat /sys/class/drm/card0-DPI-1/enabled"
hdc shell "cat /sys/class/drm/card0-LVDS-1/status 2>/dev/null"
hdc shell "cat /sys/class/drm/card0-HDMI-A-1/status 2>/dev/null"
hdc shell "mount -t debugfs none /sys/kernel/debug"
hdc shell "cat /sys/kernel/debug/dri/0/summary"
hdc shell "cat /proc/device-tree/tft-lcd-panel/status; echo"
hdc shell "cat /proc/device-tree/lvds-panel/status; echo"
hdc shell "pidof render_service composer_host"
hdc shell "i2cdetect -y -r 2"
合格大致是:
summary:VP2 ACTIVE,connector DPI-1,clk 约 65000
card0-DPI-1/status:connected(simple-panel,只能当「驱动认为有屏」)
lvds-panel/status:disabled
hdmi:disabled 或 disconnected 且未被选中
i2cdetect:0x38 在,0x5d 不在
pidof render_service:有号
时钟是 51200,还在扫 LVDS。时钟是 72000,还在扫 MIPI。名字是 HDMI-A-1,四选一没关干净。DPI-1 的 connected 和 LVDS-1 一样不可全信,要以 summary 为准。
U-Boot 阶段若仍打印 type: LVDS0 for VP2,U-Boot 自己的 dtb 还是 LVDS。内核起来之后以 summary 为准;logo 花一下再切到 RGB,是两阶段各用各的树,resource 没刷齐会这样。
没有 DCS,不要往 RGB 节点里塞 init sequence
MIPI 要 DCS。RGB 和 LVDS 一样,timing + bus-format + backlight 就是初始化。panel-init-sequence 写进 tft-lcd-panel,驱动不认。时序对了就会扫,错了就花。不要制造一份没人读的字节。
背光仍走 PWM4。&pwm5 保持 disabled,别抢相机 PWDN。
37 秒掉电那一刀,RGB 若也用 orphan regulator,同样会黑。LVDS 那篇写过 regulator-always-on。RGB 若供电走同一只脚,一起锁住。power-shell wakeup 救的是 DRM blank,救不了被关掉的 3.3 V。
和 LVDS 对打一次
同一份内核,换 dts 开关就能在两路之间切。建议真的切一次。
切到 RGB:panel 65 MHz 高有效、&rgb / &rgb_in_vp2 / &route_rgb 打开,video_phy0 关掉,lcdc_ctl 按上面裁,HDMI / LVDS / DSI / eDP 全关。刷 p4 和 p5。summary 必须是 DPI-1、clk 65000。触摸改 FT5406、105/106、1024×600。
切回 LVDS:按 LVDS 那篇把 JEIDA、51.2 MHz、video_phy0、route_lvds 打开,把 &rgb 和 &route_rgb 关掉,lcdc_ctl 若只为 RGB 裁过,LVDS 不走这组管脚,但 GPIO3_B1/B2 会空出来——没关系。触摸改回 GT911、0x5d。只换屏不换触摸,划起来是骗子。
窗口取向跟 1024×600 横屏走。不要把 MIPI 的 800×1280 竖屏策略留在 RGB 上。
黑屏对照表
| 现象 | 先查 | 常见原因 |
|---|---|---|
| 真屏只有背光,summary 是 LVDS-1 | 四选一;p4 | `&lvds_panel` 仍 okay,或没刷 resource |
| 无 DPI-1 | `&route_rgb`;`video_phy0` | route 默认 disabled,忘了显式打开 |
| 花屏 | 极性、bus-format、时钟 | 抄了 LVDS 的低有效和 JEIDA |
| 能亮不能点,0x38 能扫到 | lcdc_ctl;gpio 105/106 | 触摸脚被占成 LCD 数据线 |
| 0x38 全 NACK | I2C 速率;排线 | 400 kHz;座子插错 |
| 点下去左右反 | HDF 镜像 | 公版 X/Y 对调没拿掉 |
| 改了 dts,clk 仍 51200 | `/proc/device-tree`;p4 | 生效 dtb 在 resource |
| dd 成功画面不变 | `ls -l /dev/block/mmcblkXp4` | 路径少了 `/block/` |
| card0 不建 | DSI compatible | HDF 误抓 simple-panel-dsi |
| 约 37 秒后黑 | dmesg disabling | 孤儿 regulator |
| Cluster plane init failed | 旧包是否也有 | 红鲱鱼 |
RGB 这篇多出来的两刀,是 65 MHz 高有效这一组数字,和 lcdc_ctl 那次裁剪。漏第一刀,屏花。漏第二刀,屏亮,手是摆设。
porch 数字和 LVDS 也不是同一份。两边 hactive/vactive 都是 1024×600,容易看成一份。LVDS 的 hsync-len 是 70、vsync-len 是 20;RGB 是 20 和 3。vfront-porch 两边都是 12,不要因此以为可以整段拷。时钟 51.2 对 65,一行就能看出来;极性四个 0 对四个 1,才是抄错之后最难一眼看出来的。dts 里把 RGB 的四个 *-active 写成 0,屏可以亮,同步沿反了,花或者滚。验收时 summary 的 clk 是 65000 还不够,要反编译 dtb 看那四个 1 还在不在。
现场一条最短路径
dts 已按本文打开 RGB、关掉其余,lcdc_ctl 已裁。串口 1500000 开着。
上电看 Linux version,看 [drm] Initialized。hdc 连上。cat /proc/partitions。resource、boot_linux 按 /dev/block/ 写到 p4、p5,eMMC 的 p4 也写。reboot。
起来后读 summary。VP2、DPI-1、clk 65000。对不上:先看 LVDS-1 在不在。在,回去关 LVDS。名字是 HDMI-A-1,关 HDMI。没有 DPI-1,查 &route_rgb 和 PHY。
对上了再看 pidof render_service。空的去查 so 和 hilog。有号、屏黑:背光 PWM4,再等一分钟看 37 秒掉电。
触摸放到画面稳定之后。i2cdetect -y -r 2 看到 0x38,gpio 105/106 是 GPIO。看到 0x5d,你接的是 LVDS 那块。划不动,回头看 lcdc_ctl 裁剪有没有进 dtb。
这条路径里没有「给 RGB 加 DCS」这一步。DCS 是 MIPI 的。也没有「把时钟改成 51.2 试试」——那是另一块玻璃。
系列第 20 篇 · 芯片:瑞芯微 RK3568 · OpenHarmony 4.1(API 11) · Linux 5.10
更多推荐


所有评论(0)