eDP屏幕输出—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
RGB 的时钟和极性讲过了。今天看 eDP:笔记本那套接口,有热插拔检测,没接屏却打开会挤掉别的口。
现象:dts 里 &edp 已经 okay,card0-eDP-1 的 status 永远 disconnected,桌面没有。或者接了一块 eDP 转 HDMI 的转接板,显示器报「时序不对」。或者根本没接 eDP 屏,LVDS 那路反而只剩背光。
原因要拆开。RK3568 的 eDP 走片内 DP 控制器,驱动是 drivers/gpu/drm/rockchip/dw-dp.c。它不是 simple-panel 那种「声明了就当插着」。它有 HPD。simple-panel 的 edp_panel 若同时 okay,又会像 LVDS 一样永远报 connected,把别的口挤掉。没接屏时这两件事叠在一起:控制器 disconnected、panel 撒谎 connected,composer 选谁都是错的。所以——没有屏,不要 okay。

产品名 rk3568_evb。改的文件:
device/board/rk/rk3568_evb/kernel/rk3568-evb-linux.dts
eDP 走 VOP2 的 VP0,连接器名字 card0-eDP-1。HDMI 也爱占 VP0。这两路尤其不能同时 okay。原配玻璃常见 2560×1600@60,264.3 MHz。转接板不缩放,把这组 timing 直送给 1080p 显示器,显示器不认,要改成 1920×1080@60,148.5 MHz。真屏必须按屏厂的表写,不要在两档之间猜。
四选一在显示总论那篇。这里当已经成立:开 eDP,HDMI / LVDS / RGB / MIPI 全部关掉。
现象:没接 eDP,LVDS 或 HDMI 的桌面没了
真屏只有背光。summary 里出现 eDP-1,或者主显示挂在一份你没接的连接器上。
原因
edp_panel 是 simple-panel,status=okay 就永远 connected。四选一被它抢走。控制器 &edp 开着但没 HPD,又是 disconnected。主显示选到一份「假 connected」的 panel 上,真屏停 logo。

Linux 镜像有时 RGB 和 eDP 同时打开,Weston 当扩展桌面。开源鸿蒙的 composer 不行。抄 Linux 的双开 dts 过来,结果不是双屏,是真屏停 logo。
代码:默认全关
没屏的日常镜像,四件套全部 disabled。不要为了「接口写进 dts 就算交付」留一个撒谎的 simple-panel。
edp_panel: edp-panel {
status = "disabled";
compatible = "simple-panel";
bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
bpc = <8>;
};
&edp_in_vp0 { status = "disabled"; };
&edp {
status = "disabled";
pinctrl-names = "default";
pinctrl-0 = <&edpdpm0_pins>;
hpd-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
};
&route_edp { status = "disabled"; };
hpd-gpios 可以留在 disabled 的节点里当注释。只有手上有屏、或明确在测转接板时,才把 panel、&edp、&edp_in_vp0、&route_edp 一起改 okay,并关掉 HDMI/LVDS/RGB/DSI。
dtsi 里 &route_edp 默认 disabled。开 eDP 时必须显式打开,和 RGB 那路的 &route_rgb 同一个坑。漏了,控制器 okay,VOP 不把 VP0 接到 eDP 出口。
现象:接了 2560×1600 的屏,或转接板报时序不对
原配常见 2560×1600@60,像素时钟 264.3 MHz。转接板不缩放,直接把这组 timing 送给 1080p 显示器,显示器菜单里写「不支持的时序」。
原因
eDP 没有 HDMI 那种 EDID 自动选模的舒服路径。有些屏有 DPCD/EDID,simple-panel 这条仍按 dts 写死的 timing 扫。写错分辨率就是黑或花。转接板是另一块「屏」,参数跟玻璃不是同一份。
HDMI 那篇强调不要写死 1024×600。eDP 这篇反过来:必须写死,而且写的是手上那块东西的数字。原配玻璃、转接板、另一块 1080p 真屏,三组 porch 不要混。
代码:原配 2560×1600
edp_panel: edp-panel {
status = "okay";
compatible = "simple-panel";
bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
bpc = <8>;
backlight = <&backlight>;
display-timings {
native-mode = <&edp_timing0>;
edp_timing0: edp-timing0 {
clock-frequency = <264300000>;
hactive = <2560>;
vactive = <1600>;
hfront-porch = <24>;
hsync-len = <35>;
hback-porch = <59>;
vfront-porch = <3>;
vsync-len = <6>;
vback-porch = <49>;
hsync-active = <0>;
vsync-active = <1>;
de-active = <1>;
pixelclk-active = <1>;
};
};
port {
panel_in_edp: endpoint {
remote-endpoint = <&edp_out_panel>;
};
};
};
转接板 + 1080p 显示器,改成 CEA 1920×1080@60、148.5 MHz:
edp_timing0: edp-timing0 {
clock-frequency = <148500000>;
hactive = <1920>;
vactive = <1080>;
hfront-porch = <88>;
hsync-len = <44>;
hback-porch = <148>;
vfront-porch = <4>;
vsync-len = <5>;
vback-porch = <36>;
hsync-active = <0>;
vsync-active = <1>;
de-active = <1>;
pixelclk-active = <1>;
};
真玻璃必须按屏厂的分辨率、porch、时钟改。猜错的表现是 connected 但花或黑——HPD 已经过了,错在扫描。
控制器和路由,VP0:
&edp_in_vp0 { status = "okay"; };
&edp {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&edpdpm0_pins>;
hpd-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
ports {
port@1 {
reg = <1>;
edp_out_panel: endpoint {
remote-endpoint = <&panel_in_edp>;
};
};
};
};
&route_edp {
status = "okay";
connect = <&vp0_out_edp>;
};
关掉其余口。HDMI 和 eDP 抢同一条 VP0,这一组特别不能省:
&hdmi { status = "disabled"; };
&hdmi_in_vp0 { status = "disabled"; };
&hdmi_in_vp1 { status = "disabled"; };
&route_hdmi { status = "disabled"; };
&video_phy0 { status = "disabled"; };
&lvds { status = "disabled"; };
&lvds_in_vp2 { status = "disabled"; };
&route_lvds { status = "disabled"; };
&lvds_panel { status = "disabled"; };
&rgb { status = "disabled"; };
&rgb_in_vp2 { status = "disabled"; };
&route_rgb { status = "disabled"; };
&tft_lcd_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"; };
connect = <&vp0_out_edp> 必须和 edp_in_vp0 一致。写成 VP1,扫描和连接器不在一路。
现象:屏已经插上,status 恒 disconnected
ls /sys/class/drm/ 看得到 card0-eDP-1。cat status 永远 disconnected。summary 里这路不是 ACTIVE。桌面没有。
原因
dw-dp.c 的 dw_dp_hpd_init 分叉,记住这两条,少改一次驱动。
设备树有 hpd-gpios:驱动置 DPTX_CCTL 的 FORCE_HPD。控制器内部把 HPD 当成高,链路训练不靠外部电平。连接检测只读那根 GPIO。GPIO 是低,status 就是 disconnected,哪怕 FORCE_HPD 让训练能走。当前板级常见 <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>,也就是 GPIO4_C4。
设备树没有 hpd-gpios:检测走 DPTX_HPD_STATUS 寄存器,需要板载上拉,并开 HPD 中断。脚浮空,寄存器也是低,同样 disconnected。
真屏经常不拉 HPD 线。你写了 hpd-gpios,这根脚若浮空或被拉低,status 永远 disconnected。转接板有的会拉 HPD,有的不会。同一份 dts,换一块下游设备,现象就变。
FORCE_HPD 只保证控制器内部不因为 HPD 低而拒绝训练。它不把 sysfs 的 status 改成 connected。connected 来自 GPIO 或寄存器。把这两件事当成一件,会去改 timing,越改越远。
代码:按这个顺序修,不要一上来改驱动
- 万用表看屏的 HPD 脚是否被拉高。能拉高,保证 dts 的 gpio 就是这根,极性对。GPIO4_C4 在 debugfs 里应当能看到电平。
- 板子有可靠上拉、想走寄存器检测:删掉
hpd-gpios,让驱动走DPTX_HPD_STATUS。 - 前两步做不到,才考虑在驱动里强制 connected。那是改
dw-dp.c、重编内核,不是 dts 开关。bring-up 可以,量产要心里有数:热插拔没了。
/* 走 GPIO 检测(当前板级常见) */
&edp {
hpd-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
};
/* 改走寄存器检测时: */
&edp {
/delete-property/ hpd-gpios;
};
读到的现象对应:
hdc shell "cat /sys/class/drm/card0-eDP-1/status"
hdc shell "cat /sys/class/drm/card0-eDP-1/enabled"
| status | 画面 | 含义 |
|---|---|---|
| connected | 有 | HPD 和时序都对 |
| connected | 黑或花 | 时序或背光,不是 HPD |
| disconnected | 无 | HPD 路径,按上面三步 |
GPIO 值和内核日志:
hdc shell "mount -t debugfs none /sys/kernel/debug"
hdc shell "cat /sys/kernel/debug/gpio | grep -iE 'PC4|132'"
hdc shell "dmesg | grep -iE 'dp|edp|hpd|dw-dp'"
GPIO4_C4 是 132 号(4×32+16+4,C 是 16)。脚是低,status 就不会变成 connected。硬件拉高它,比改驱动快。
现象:connected,有时序,玻璃全黑
summary 里 VP0 ACTIVE,connector eDP-1,时钟是 264300 或 148500。人眼看是一块黑玻璃。hdc 还在。
原因
很多 eDP panel 节点抄过来时没有 backlight、没有 power-supply。链路训练过了,像素在出,背光没开。LVDS 那路习惯写 backlight = <&backlight>(PWM4),eDP 漏了。真屏还要 VDD。座子上的供电和 PWM 不是同一根。原配 dts 有时两样都不写,接转接板能亮是因为显示器自带背光;接真屏就不亮。
这和 HDMI 的「无信号」不同。HDMI 显示器自带电源。eDP 玻璃常常要你供。也和 37 秒 orphan regulator 不同。那一刀会在 dmesg 里留下 disabling。这里是从来没开过。
代码
edp_panel: edp-panel {
backlight = <&backlight>;
/* 若屏的 VDD 由 gpio regulator 控制,加上:
power-supply = <&vcc_edp_panel>;
*/
};
&backlight { status = "okay"; };
&pwm4 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&pwm4_pins>;
};
&pwm5 保持 disabled,别抢相机 PWDN。HDF 侧 lcd_config.hcs 的 pwmDevNum = 4。示波器量 PWM4。没波形先查 HDF 背光,有波形仍黑再查屏的使能脚和 VDD。
不要用 power-shell wakeup 当这一步的药。那条命令唤醒 DRM blank。背光没配,wakeup 之后还是黑。
真正生效的 DTB 在 resource
从 LVDS 切到 eDP,只刷 p5,U-Boot 仍加载 p4 的旧树。summary 仍是 LVDS-1、clk 51200。你会以为 DP 控制器没起来。
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,dd 建普通文件,md5 对,画面不变。SD 启动也写 eMMC 的 p4,U-Boot 常从那里取 rk-kernel.dtb。
主机上确认 dtb 里的时钟是你想要的那档:
dtc -I dtb -O dts -o /tmp/now.dts 那份.dtb
grep -n '264300000\|148500000\|edp-panel\|hpd-gpios' /tmp/now.dts
2560 那档应当看到 264300000。1080p 转接板应当看到 148500000。两串同时在,看 native-mode 指哪一个。指错,显示器报时序不对。
board 目录经常不在内核 DEPS 里。改 dts 之后:
rm -rf out/kernel/checkpoint
rm -f out/rk3568_evb/packages/phone/images/resource.img
./build.sh --product-name rk3568_evb --ccache
只换显示时刷 resource + boot_linux。改 dw-dp.c 强制 connected,才需要重编 Image,那是档 2 的 Image 路径,不是只换 dtb。
验收:先认盘,再认 eDP-1,再认时钟和 HPD
hdc shell "cat /proc/partitions"
hdc shell "mount | grep ' on / '"
hdc shell "ls -l /dev/block/mmcblk0p4 /dev/block/mmcblk1p4"
hdc shell "dmesg | grep -iE '\\[drm\\] Initialized|dw-dp|edp|hpd|simple-panel'"
hdc shell "ls -l /dev/dri/"
hdc shell "ls /sys/class/drm/"
hdc shell "cat /sys/class/drm/card0-eDP-1/status"
hdc shell "cat /sys/class/drm/card0-eDP-1/enabled"
hdc shell "cat /sys/class/drm/card0-eDP-1/modes 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 /sys/kernel/debug/gpio | grep -iE 'PC4|lcd'"
hdc shell "cat /proc/device-tree/edp-panel/status; echo"
hdc shell "cat /proc/device-tree/lvds-panel/status; echo"
hdc shell "pidof render_service composer_host"
hdc shell "hidumper -s RenderService | head -40"
合格大致是:
card0-eDP-1/status:connected
card0-eDP-1/enabled:enabled
summary:VP0 ACTIVE,connector eDP-1
clk:约 264300(2560×1600)或约 148500(1080p)
lvds-panel/status:disabled
hdmi:disabled 或未被选中
pidof render_service:有号
status=disconnected:先量 HPD,不要先改 porch。status=connected 但 enabled=disabled:主显示不是 eDP,回头查还有没有 simple-panel 抢在前面。时钟是 51200,刷的还是 LVDS 那份树。时钟是 264300、下游是 1080p 显示器,转接板会报时序不对——改 148.5 MHz,不是改 HPD。
eDP-1 的 connected 在写了 hpd-gpios 时,来自那根 GPIO,可以当「HPD 脚是高」的证据。edp_panel 若是 simple-panel,它自己也会报 connected,两份 connected 叠在一起时,以 summary 的 connector 名为准。
和 HDMI 对打一次
HDMI 和 eDP 都爱 VP0。建议真的切一次,否则「抢 VP0」只是句子。
切到 eDP:四件套 + route 打开,timing 按手上的屏或转接板写,hpd-gpios 按板级留着,HDMI / LVDS / RGB / DSI 全关。刷 p4 和 p5。插上屏或转接板。status 必须能变成 connected。变不了,量 GPIO4_C4。变了但黑,查时钟和背光。
切回 HDMI:按 HDMI 那篇打开 VP0 上的 HDMI,把 &edp、&edp_in_vp0、&route_edp、edp_panel 全部 disabled。刷同一对分区。拔 HDMI 线,card0-HDMI-A-1/status 必须变成 disconnected。eDP 在写了 hpd-gpios 时,拔屏应当 GPIO 变低、status 变 disconnected——前提是屏真的在拉那根脚。真屏不拉,你会看到「拔了还是 disconnected」,没有对比度,那是 HPD 路径的问题,不是切屏失败。
窗口取向跟分辨率走。2560×1600 和 1920×1080 都是横的。不要把 MIPI 的 800×1280 竖屏策略留在 eDP 上。触摸:外接转接板常常配 USB 鼠标;真屏若带触摸,按那颗芯片另配,不要假设还是 GT911。
黑屏对照表
| 现象 | 先查 | 常见原因 |
|---|---|---|
| 没接屏,别的口只剩背光 | edp_panel status | simple-panel 恒 connected |
| 转接板报时序不对 | dtb 里的 clock-frequency | 写死 2560×1600,下游是 1080p |
| 真屏花/黑,HPD 已 connected | porch、时钟、lanes | timing 不是这块玻璃的 |
| 恒 disconnected | GPIO4_C4 电平 | HPD 不拉高;FORCE_HPD 不管 sysfs |
| connected 全黑 | backlight / VDD | 漏了 PWM4 phandle |
| HDMI 和 eDP 抢 VP0 | summary 的 connector | 两路都 okay |
| 无 eDP-1 | `&edp` / `&route_edp` | route 默认 disabled |
| 改 dts 无效 | `/proc/device-tree`;p4 | 没刷 resource |
| dd 成功画面不变 | `ls -l /dev/block/mmcblkXp4` | 路径少了 `/block/` |
| card0 不建 | DSI compatible | HDF 误抓 simple-panel-dsi |
| Cluster plane init failed | 旧包是否也有 | 红鲱鱼 |
| `power-shell wakeup` 能醒 | hilog blank | 电源超时,不是 eDP |
eDP 的契约可以压成四句。
没屏就关,不要留一个撒谎的 simple-panel。
有屏就四件套齐、别人全关,route 必须显式 okay。
HPD 按 dw-dp.c 的两条路径理解:有 hpd-gpios 就 FORCE_HPD 加纯 GPIO 检测;没有就走寄存器。sysfs 的 connected 来自检测,不是来自 FORCE_HPD。
时序按手上那块玻璃或转接板写。2560×1600 用 264.3 MHz,1080p 用 148.5 MHz,不要从 LVDS 抄 1024×600,也不要学 HDMI 去「不写 timing」。
现场一条最短路径
手上有屏或转接板。dts 已按本文打开 eDP、关掉其余,timing 是这下游的那一档。串口 1500000 开着。
上电看 Linux version,看 [drm] Initialized,看 dmesg 有没有 dw-dp。没有,停。查 &edp 和 route。
hdc 连上。cat /proc/partitions。resource、boot_linux 按 /dev/block/ 写到 p4、p5,eMMC 的 p4 也写。reboot。
起来后读 card0-eDP-1/status。disconnected:量 GPIO4_C4,不要先改 porch。connected:读 summary。VP0、eDP-1、clk 对应当前 timing。时钟是 264300、下游是 1080p,改 148.5 MHz 再刷 p4。时钟是 51200,刷的还是 LVDS。
对上了再看画面。黑:PWM4 和 VDD。花:porch。pidof render_service 为空:so 和 hilog,不是 eDP 控制器。
这条路径里没有「给 eDP 写 JEIDA」这一步,也没有「不写 timing 跟 EDID 走」。那是 LVDS 和 HDMI 的脾气。eDP 两边都要:既要写死 timing,又要伺候 HPD。
系列第 21 篇 · 芯片:瑞芯微 RK3568 · OpenHarmony 4.1(API 11) · Linux 5.10
更多推荐


所有评论(0)