
1. 项目概述从零开始点亮一块RK3568的EDP屏最近在风火轮的YY3568开发板上折腾一块11.6寸的EDP显示屏整个过程从硬件连接到内核驱动修改再到问题排查算是把RK3568的显示子系统又摸了一遍。EDP接口现在在商显、工控、车载这些领域用得越来越多了相比老旧的LVDS带宽高、线缆少确实是未来的趋势。如果你手头也有RK3568的平台需要接一块EDP屏不管是做产品原型还是自己玩这篇记录应该能帮你省下不少查资料和踩坑的时间。我会尽量把原理、操作和那些容易忽略的细节都讲清楚让你不仅能“点亮”屏幕更能明白背后每一步是为什么。2. 硬件准备与接口原理剖析2.1 核心硬件选型与连接我这次用的主板是风火轮科技的YY3568开发板主控是瑞芯微的RK3568。这块板子的一个优点就是原生带了一个标准的30Pin EDP接口对于显示调试来说非常方便。屏幕配套用的是风火轮的11.6寸EDP屏这样硬件兼容性上基本没有悬念。硬件连接极其简单如果你的目标只是让屏幕显示图像那么只需要用一根标准的EDP连接线将开发板的EDP接口与屏幕的接口连接起来即可。供电通常由开发板通过连接线提供给屏幕的逻辑板。这里要提一句EDP接口本身也包含了I2C等引脚用于读取屏幕的EDID扩展显示标识数据信息但最基本的显示功能只需要差分数据对和电源。一个关键的硬件细节我查看YY3568的底板原理图发现它的EDP座子虽然是30Pin标准接口但实际只引出了两组差分数据对LANE0和LANE1。这是完全符合标准的因为对于1080P60Hz这种常见分辨率两组Lane的带宽已经绰绰有余。RK3568的EDP控制器最高支持4组Lane核心板是全引出的但底板做了简化。这一点在你未来调试更高分辨率屏幕时需要留意如果带宽不够可能需要自己改动底板启用LANE2和LANE3。2.2 关键信号引脚与功能取舍除了数据线EDP接口上还有几个重要的控制信号在原理图和设备树配置中会频繁遇到EDP_HPD (热插拔检测)这个信号由屏幕发出通知主机“屏幕已连接”。在YY3568底板上这个信号通过GPIO_C2引入。但是原理图上有一个电阻R192默认是不焊接的。这意味着如果你不主动焊上这个0欧姆电阻热插拔功能在硬件上就是断开的。对于嵌入式设备屏幕通常是固定连接所以这个功能很多时候可以不要。但如果你需要就得自己动手补上R192。背光使能 (BL_EN)这个引脚用于控制屏幕背光板的电源开关。在底板上它对应GPIO1_A4并且通过一个上拉电阻默认置为高电平背光常开。如果你希望通过系统软件来控制背光的开关比如待机时熄屏就需要焊接电阻R199将这个GPIO的控制权交给SoC。背光调节 (PWM)调节屏幕亮度。YY3568上使用的是PWM14_M0。这是一个关键功能实现无级调光就靠它。设备树里必须正确配置否则要么背光不亮要么无法调节亮度。理解这几个引脚的状态对于后续软件配置时决定是使用force-hpd还是hpd-gpios以及背光为什么不受控有根本性的帮助。硬件状态决定了软件配置的起点。3. 软件环境搭建与内核编译基础3.1 SDK获取与编译系统选择风火轮为YY3568提供了完善的SDK支持Android 11和Debian 10两种系统。这两个系统的内核虽然同源但编译和烧录方法截然不同。Android SDK采用Android标准的编译环境如lunch选择产品make -jN编译。它会生成包括boot、dtb、system等在内的多个image文件通常使用瑞芯微的AndroidTool进行烧录。Debian/Linux SDK更接近标准的Linux开发流程可能使用buildroot或yocto。编译内核通常是在kernel目录下执行make ARCHarm64 rockchip_defconfig和make ARCHarm64 menuconfig等命令。烧录则可能使用upgrade_tool或者直接写SD卡。我的选择与建议对于纯显示调试我推荐使用Linux系统如Debian的SDK。原因有三首先内核驱动框架DRM是通用的调试逻辑完全一致其次Linux环境下命令行工具更丰富调试更灵活比如后面会用到的modetest最后编译和烧录内核通常只是boot.img的周期比编译整个Android系统快得多效率更高。实操心得无论你选择哪个系统第一步一定是按照官方Wiki YY3568 Wiki 成功编译出原始的、未修改的固件并烧录启动。确保基础环境是正常的这能避免后续很多问题都归结于环境错误。3.2 内核驱动框架DRM与显示通路RK3568的显示系统完全基于Linux的DRMDirect Rendering Manager框架。理解这个框架是成功调试的基石。你可以把它想象成一个高度模块化的显示流水线Framebuffer这是一块在系统内存中划出来的区域里面存放着要显示的图像数据。应用层最终把画面画在这里。CRTCCathode Ray Tube Controller可以理解成显示控制器。在RK3568上它就是VOP2Video Output Processor 2。VOP2内部有3个Video PortVPVP0, VP1, VP2。它们共享6个图层Layer。你的图像数据Framebuffer需要被“贴”到某个图层上而这个图层必须分配给一个VP才能输出。VP0性能最强支持4KVP1支持2KVP2较弱主要用于RGB/LVDS接口。Encoder编码器它负责把VOP处理好的数字视频信号“翻译”成特定物理接口能理解的信号。RK3568有多个Encoder如HDMI Encoder、eDP Encoder、DSI Encoder等。我们这里要用的就是eDP Encoder。Connector连接器它代表物理接口本身比如那个30Pin的座子负责探测屏幕的连接状态热插拔、读取屏幕能力EDID。Encoder和Connector通常是紧密关联的。Panel这就是具体的屏幕硬件。驱动需要知道它的分辨率、时序等参数。数据流向应用 - Framebuffer - VOP图层 - 分配给某个VP - eDP Encoder - eDP Connector - Panel。我们的调试工作主要就是在设备树Device Tree中正确配置这条通路上的各个组件并让它们正确地连接起来。4. 内核设备树关键配置详解设备树是告诉内核硬件如何连接的关键。RK3568的显示配置分散在芯片级设备树rk3568.dtsi和板级设备树如rk3568-youyeetoo.dts中。我们不需要改动芯片级文件只需在板级文件中进行覆盖和配置。4.1 VOP与Encoder的绑定策略首先需要决定让哪个VPVOP的Video Port来驱动eDP接口。这涉及到性能分配。以常见的HDMI eDP双显场景为例HDMI接口可能接4K显示器需要更高的带宽。eDP屏通常是笔记本或中小尺寸屏分辨率多为1080P或2K。因此合理的分配是VP0绑定HDMIVP1绑定eDP。这样把性能更强的VP0留给可能的高分辨率需求。在设备树中这种绑定关系体现在ports节点// 在板级设备树中例如 rk3568-youyeetoo.dts edp { status okay; // 强制使能HPD因为底板默认无热插拔检测 force-hpd; ports { // 端口0连接VOP port0 { reg 0; // 关键将edp的输入源设置为vop的vp1 edp_in_vp1: endpoint { remote-endpoint vp1_out_edp; }; }; // 端口1连接物理Panel port1 { reg 1; edp_out_panel: endpoint { remote-endpoint panel_in_edp; }; }; }; }; // 同时需要确保VP0到eDP的链接被禁用VP1到eDP的链接被启用 vp0 { vp0_out_edp: endpointROCKCHIP_VOP2_CLUSTER0 { status disabled; // 禁用VP0到eDP // remote-endpoint edp_in_vp0; }; }; vp1 { vp1_out_edp: endpointROCKCHIP_VOP2_CLUSTER1 { status okay; // 启用VP1到eDP remote-endpoint edp_in_vp1; }; };为什么是remote-endpoint设备树通过这种“端点-远程端点”的配对来描述设备间的连接关系。vp1_out_edp和edp_in_vp1就像两个插头名字对应上软件就知道它们连在一起了。4.2 eDP控制器与Panel节点配置接下来配置eDP控制器本身和具体的屏幕参数。edp { status okay; force-hpd; // 关键属性 // hpd-gpios gpio0 RK_PC2 GPIO_ACTIVE_HIGH; // 如果焊接了R192就用这行代替force-hpd ports { ... // 同上端口配置 }; // 关联的PHY必须使能 edp_phy: phy0 { status okay; }; }; // 定义一个Panel节点 panel { compatible simple-panel; // 使用通用的simple-panel驱动 status okay; // 电源使能引脚对应BL_EN (GPIO1_A4) enable-gpios gpio1 RK_PA4 GPIO_ACTIVE_HIGH; // 背光控制引用PWM节点 backlight backlight_edp; // 显示时序这是屏的核心参数 display-timings { native-mode timing0; timing0: timing0 { clock-frequency 148500000; // 像素时钟单位Hz 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; // 水平同步极性0低有效1高有效 vsync-active 0; // 垂直同步极性 de-active 1; // 数据使能极性 pixelclk-active 0; // 像素时钟极性0上升沿采样 }; }; // 电源上电时序部分屏有严格要求 power-supply vcc3v3_lcd0_n; // 可以添加 power-up-delay-ms, reset-delay-ms 等属性 }; // 背光节点配置 pwm14 { status okay; pinctrl-names default; pinctrl-0 pwm14m0_pins; // 确保引脚复用正确 }; backlight_edp: backlight_edp { status okay; compatible pwm-backlight; pwms pwm14 0 25000 0; // 使用PWM14周期25000ns (40kHz) brightness-levels 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... // 通常定义0-255级 255; default-brightness-level 200; // 默认亮度非常重要 enable-gpios gpio1 RK_PA4 GPIO_ACTIVE_HIGH; // 背光使能可与panel共用 };关于display-timings这些参数必须与屏幕规格书严格一致。如果屏幕支持EDID系统启动时会自动读取你可以不写这个节点。但对于大多数嵌入式屏尤其是成本控制的工控屏都不带EDID必须手动配置。参数错误会导致无显示、花屏、闪屏等问题。风火轮通常会提供他们屏幕的display-timings数据。关于force-hpd因为我们的底板没焊R192硬件上无法检测热插拔。这个属性就是告诉eDP控制器“别管HPD信号了强制认为屏幕一直连着”。如果焊了R192就应该删除force-hpd并配置hpd-gpios。4.3 编译与烧录内核配置好设备树后在SDK的kernel目录下执行编译# 对于 Linux SDK make ARCHarm64 rockchip_defconfig make ARCHarm64 rk3568-youyeetoo.img -j$(nproc) # 生成的 boot.img 在 kernel/boot.img 或 rockdev/ 目录下 # 对于 Android SDK通常在内核目录直接执行 ./make.sh linux # 或者通过Android顶层编译单独编译kernel make bootimage -j$(nproc)将生成的boot.img烧录到开发板。对于Linux系统可能只需要更新这个分区对于Android可能需要连同dtb.img一起更新。5. 调试过程与问题排查实录烧录新内核后通过串口查看内核启动日志这是最重要的调试窗口。5.1 正常启动日志分析如果配置正确你应该能看到类似以下的关键日志[drm] Initialized rockchip 1.0.0 ... rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops) rockchip-drm display-subsystem: bound ff470000.edp (ops rockchip_edp_component_ops) ... rockchip-drm display-subsystem: [drm] connector eDP-1: get mode 1920x1080 for detailed timing edp ff470000.edp: [drm] *ERROR* wait panel signal timeout edp ff470000.edp: [drm] *ERROR* train link error edp ff470000.edp: [drm] Link Training successful at rate 2.70 Gbps, 2 lanes ... [drm] connector eDP-1: get mode 1920x1080 for detailed timing [drm] Setting mode 1920x108060Hz for connector eDP-1这些日志说明了DRM框架成功初始化。VOP和eDP控制器被成功绑定到显示子系统。eDP链路训练成功这是eDP接口建立连接的关键握手过程。最终为eDP-1 connector设置了1920x108060Hz的模式。看到最后一行关于设置模式的日志基本上屏幕就应该点亮了。5.2 常见问题排查手册5.2.1 背光不亮这是最常见的问题。首先检查背光系统是否成功创建。检查背光节点ls /sys/class/backlight/你应该能看到backlight_edp名字取决于设备树里的compatible或节点名。如果不存在说明背光驱动没加载。检查PWM驱动dmesg | grep -i pwm14查看是否有PWM14相关的错误。常见错误是引脚复用冲突。比如日志出现rockchip-pwm ff680010.pwm: failed to get pinctrl这意味着PWM14所用的引脚被其他功能比如GPIO占用了。你需要去设备树的pinctrl部分确保pwm14m0_pins是启用的并且没有其他节点复用相同的引脚组。检查默认亮度cat /sys/class/backlight/backlight_edp/brightness如果输出是0那背光自然是黑的。这是因为设备树里default-brightness-level属性可能没设置或设置为了0。必须确保这个值大于0比如200。修改设备树后重新编译烧录。硬件测量如果以上软件都正常就用万用表测量背光接口的电压。BL_EN引脚是否为高电平PWM引脚是否有波形如果没有可能是硬件连接或屏幕背光板本身的问题。5.2.2 背光亮但无图像黑屏背光亮说明屏幕已经上电但没收到有效图像数据。用modetest工具DRM的瑞士军刀来诊断。编译modetestAndroid在SDK根目录执行mmm external/libdrm/tests/modetest/ -j8产物在out/target/product/YY3568/data/nativetest64/modetest/modetest。Linux通常已内置或可通过包管理器安装libdrm-tests。查看连接器状态 将modetest推送到开发板并执行./modetest -c查看输出中关于eDP connector的部分connector id encoder status name size (mm) modes encoders 359 358 connected eDP-1 260x160 1 358 modes: index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot) 0 1920x1080 60.00 1920 1968 2000 2200 1080 1084 1089 1125 148500 flags: nhsync, nvsync; type: preferred, driverstatus必须显示为connected。如果显示disconnected原因有二一是硬件上没焊HPD电阻但设备树却配置了hpd-gpios应改用force-hpd二是硬件焊了电阻但连接不良或屏幕未上电。modes这里列出的分辨率必须和你的屏幕物理分辨率一致。如果不一致说明设备树中的display-timings配置错误或者EDID读取异常。强制显示测试图案 如果状态是connected且分辨率正确可以强制输出一个测试画面来绕过上层应用。./modetest -s 3591080:1920x1080 -v # 或简写 ./modetest -s 359:1920x1080这个命令会占用eDP connectorid 359并显示一个彩条图案。如果屏幕能显示出彩条证明从VOP到Panel的整个硬件通路是完好的问题出在上层应用没有去设置这个显示输出比如Android的SurfaceFlinger没起来或者Linux的桌面环境没配置对显示器。5.2.3 花屏、残影、闪屏这类问题通常与时序、电源或链路稳定性有关。首要怀疑对象display-timings。像素时钟clock-frequency算错是最常见的。计算公式是总像素 × 总行数 × 刷新率。 对于上面的例子2200 (htotal) × 1125 (vtotal) × 60 ≈ 148.5 MHz。必须完全匹配规格书。极性hsync-active, vsync-active错误也可能导致图像错位。电源时序有些屏幕对Power Supply、Reset、Data Enable信号的上电顺序有严格要求。比如要求电源稳定后延迟几十毫秒再拉高Reset再延迟一段时间才能发送图像数据。这需要在Panel节点的power-supply和enable-gpios配置中添加power-up-delay-ms、reset-delay-ms、prepare-delay-ms等属性。仔细阅读屏幕规格书的“Power Sequence”章节。链路训练不稳定观察内核日志看是否有“Link Training error”或“wait panel signal timeout”等错误但随后又训练成功了。这可能在高分辨率或长线缆下出现。可以尝试在edp节点下添加属性降低链路速率edp { max-link-rate 2700; // 单位 Mbps可尝试从2700降到1620 // 或者强制使用2个lane即使硬件是4个 // lanes 2; };5.2.4 仅部分区域显示或图层错误查看内核日志如果出现类似警告rockchip-vop2 ff460000.vop: VP1 win0 plane[0] atomic check error: invalid window size 1920x108000 for video port1这通常意味着分配给该VP的图层plane能力不足。VOP2的6个图层类型不同Smart、Esmart、Cluster等其缩放、叠加能力和最大支持的分辨率也不同。解决方案在设备树的VOP配置中确保为eDP所在的VP如VP1分配了至少一个ROCKCHIP_VOP2_SMART类型的图层并且将其设置为primary-plane。参考配置vp1 { cursor-win-id ROCKCHIP_VOP2_ESMART0; primary-plane ROCKCHIP_VOP2_SMART1; // 关键将SMART图层设为主平面 plane-mask /bits/ 8 ROCKCHIP_VOP2_SMART1 // 主平面支持缩放、旋转等 ROCKCHIP_VOP2_ESMART1 ROCKCHIP_VOP2_CLUSTER1 ; };高分辨率输出必须使用SMART图层作为主平面因为它的带宽和处理能力最强。6. 进阶调试技巧与工具当基本显示功能调通后你可能会需要更深入的调试。查看详细的DRM状态cat /sys/kernel/debug/dri/0/summary这个文件提供了VOP、各图层、各CRTC/Encoder/Connector的详细状态包括帧率、带宽占用等对于分析复杂显示问题如多屏异显、图层混合非常有用。使用dmesg -w实时监控在调试时开启一个串口终端持续监控内核日志任何驱动报错或状态变化都能第一时间看到。测量实际像素时钟如果你有示波器可以测量eDP接口的差分时钟对上的频率与display-timings中计算的clock-frequency对比这是验证时序配置最直接的方法。EDID读取测试如果屏幕宣称支持EDID可以尝试不配置display-timings让驱动自动读取。然后通过modetest -c或cat /sys/class/drm/card0-eDP-1/edid | edid-decode来查看读取到的信息。这能验证I2C通信是否正常。7. 总结与个人体会调试一块屏幕从黑屏到完美显示这个过程就像在解一个多维度的谜题。硬件连接、设备树配置、驱动状态、电源时序任何一个环节出错都会导致失败。RK3568的DRM驱动已经相当成熟大部分工作都集中在设备树的正确描述上。我最深的体会是日志是最好的老师。串口打印的内核日志尤其是DRM和eDP驱动相关的[drm]和edp信息几乎指明了所有问题的方向。其次理解框架比死记配置更重要。明白了VOP、Encoder、Connector、Panel在DRM流水线中的角色你就能推理出配置的逻辑而不是盲目地复制粘贴。最后硬件状态是根基。像HPD电阻、背光使能电阻焊还是不焊直接决定了软件该用force-hpd还是hpd-gpios。动手前花十分钟仔细看看原理图能省下后面数小时的调试时间。这次在YY3568上调试11.6寸EDP屏的过程很顺利得益于风火轮提供的硬件和相对完善的SDK。希望这份详细的记录能帮你更顺畅地在你自己的RK3568项目上点亮屏幕。