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 = 2rstGpio = 105intGpio = 106solutionX = 1024solutionY = 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_phy0route_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 全 NACKI2C 速率;排线400 kHz;座子插错
点下去左右反HDF 镜像公版 X/Y 对调没拿掉
改了 dts,clk 仍 51200`/proc/device-tree`;p4生效 dtb 在 resource
dd 成功画面不变`ls -l /dev/block/mmcblkXp4`路径少了 `/block/`
card0 不建DSI compatibleHDF 误抓 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

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐