本文基于RK3576等芯片Uboot下的dw_hdmi.c/h驱动源码,完整拆解HDMI数据处理全流程,分析补丁的根因、解决的问题,以及受影响的芯片范围。
一、Uboot下RK HDMI驱动整体架构
RK平台Uboot的HDMI驱动基于Synopsys DesignWare HDMI TX控制器(DW HDMI)开发,分为4个核心层级,全链路适配RK系列芯片的显示需求:
1.连接器抽象层:对接Uboot显示框架,统一热插拔、EDID解析、模式选择、显示使能/禁用的标准接口;
2.DW HDMI核心驱动层:dw_hdmi.c/h为核心,实现控制器寄存器配置、PHY控制、音视频数据处理、EDID读写、色彩空间转换(CSC)、InfoFrame配置、HDCP加密等核心逻辑;
3.PHY适配层:兼容Synopsys原厂HDMI PHY与RK自研Inno HDMI PHY,实现PLL配置、TMDS信号控制、电源管理;
4.平台适配层:对接RK芯片的GRF系统控制器、GPIO、时钟、DDC I2C总线,完成引脚复用、资源映射。
二、HDMI全流程数据处理详解
RK HDMI从初始化到画面输出,分为7个核心阶段,完整数据流与执行逻辑如下:

阶段1:
驱动初始化与硬件资源准备(rockchip_dw_hdmi_init)
该阶段为Uboot显示子系统启动时的入口,完成硬件与驱动的基础初始化:
1.内存与结构体初始化:申请struct dw_hdmi核心控制结构体、EDID显示模式缓冲区的内存,完成清零初始化;
2.平台资源解析:
○读取设备树(DTS)配置,解析HDMI寄存器基地址、寄存器访问位宽、HPD热插拔GPIO、DDC总线时序、PHY配置、HDCP使能等参数;
○映射GRF系统控制器寄存器,用于HDMI引脚复用、VOP显示通路选择;
○根据寄存器位宽配置读写函数,1字节位宽使用dw_hdmi_writeb/readb,4字节位宽使用dw_hdmi_writel/readl,适配不同RK芯片的寄存器访问规范。
3.DDC I2C总线初始化:配置DDC总线时钟分频、SCL高低电平时长,符合I2C标准模式(100KHz),复位I2C控制器,清空中断状态,为EDID读取做准备;
4.PHY检测与适配:读取HDMI_CONFIG2_ID寄存器识别PHY类型,匹配对应的驱动操作集(原厂PHY用dw_hdmi_synopsys_phy_ops,RK Inno PHY用自定义ops);
5.控制器核心初始化:读取控制器版本号,屏蔽所有非必要中断(仅保留HPD热插拔中断),关闭无关模块时钟,强制输出黑屏避免初始化异常画面。
阶段2:
热插拔检测与连接状态判断(rockchip_dw_hdmi_detect)
该阶段执行于初始化后,也用于周期性轮询,核心是判断HDMI线缆连接状态:
1.读取PHY状态寄存器HDMI_PHY_STAT0的HDMI_PHY_HPD位,HPD高电平为显示器已连接;
2.若外接HDMI桥接芯片,同步调用桥接芯片的检测函数,确认链路完整性;
3.返回连接状态,未连接则终止后续显示流程。
阶段3:
EDID数据读取与解析(rockchip_dw_hdmi_get_timing)
该阶段是显示模式匹配的核心,也是本次补丁修改的关键函数,核心数据流如下:
1.EDID数据读取:调用drm_do_get_edid,通过DDC I2C总线执行dw_hdmi_i2c_xfer读写,从显示器读取128字节为块的EDID数据,动态分配内存并存储到conn_state->edid;
2.EDID有效性校验与能力解析:
○若EDID读取成功:
i.调用drm_detect_monitor_audio(edid),解析EDID音频能力块,赋值hdmi->sink_has_audio;
ii.调用drm_detect_hdmi_monitor(edid),解析EDID的HDMI厂商数据块,区分HDMI/DVI显示器,赋值hdmi->sink_is_hdmi;
iii.调用drm_add_edid_modes,从EDID解析所有支持的显示模式(分辨率、刷新率、时序参数),存入模式缓冲区。
○若EDID读取失败:
i.强制设置sink_is_hdmi = true、sink_has_audio = true,兼容无EDID的显示器;
ii.加载默认CEA标准模式(720P、1080P等常用分辨率),设置首选显示模式。
3.显示模式过滤与排序:过滤超出控制器/PHY/VOP能力的模式(如像素时钟超限),按分辨率、刷新率优先级排序,确定最终首选模式preferred_mode。
阶段4:
输出格式与色彩空间配置
基于EDID解析结果,配置输出链路的核心参数:
1.选择输出总线格式:根据显示器能力,确定RGB/YUV444/YUV422/YUV420输出格式,以及8bit/10bit/12bit色深;
2.配置色彩编码与量化范围:根据CEA模式VIC选择BT.601/BT.709/BT.2020色彩编码,设置全范围(Full Range)/有限范围(Limited Range)量化参数;
3.配置VOP输出模式,匹配HDMI的数据通路与引脚复用。
阶段5:
HDMI链路与模式硬件配置(dw_hdmi_setup)
该阶段是控制器核心配置环节,将显示模式转化为寄存器配置,完成全链路硬件使能:
1.音视频时序计算(hdmi_av_composer):
○解析显示时序的有效区、消隐区、同步前后沿、同步极性,计算像素时钟与TMDS时钟(根据色深和格式调整,如10bit RGB为像素时钟×5/4,YUV420为像素时钟/2);
○高带宽场景(TMDS时钟>340MHz)通过SCDC寄存器配置显示器开启TMDS加扰,保证信号完整性;
○写入帧合成器(FC)时序寄存器,配置输入视频参数与DVI/HDMI模式。
2.PHY配置与上电(hdmi_phy_configure):
○先下电PHY并执行复位,根据像素时钟配置PLL参数、终端电阻、电压摆率;
○配置完成后上电PHY,等待PLL锁定(HDMI_PHY_STAT0的TX_PHY_LOCK位),锁定失败返回超时错误。
3.视频通路使能(dw_hdmi_enable_video_path):
○开启像素时钟、TMDS时钟、CSC模块时钟;
○配置TMDS通道前导码、控制周期时长,保证HDMI信号合规性;
○根据输入/输出色彩空间,配置CSC模块旁路或使能。
4.音频时钟再生配置:若显示器支持音频,根据采样率(默认48KHz)和TMDS时钟计算N/CTS值,写入音频寄存器实现时钟同步,开启音频通路。
5.InfoFrame配置:
○HDMI与DVI的核心差异在于InfoFrame,HDMI通过AVI InfoFrame传递色彩空间、量化范围、分辨率等信息,DVI不支持该特性;
○填充AVI InfoFrame并写入寄存器,配置色彩参数、内容类型(游戏/影院/图形);4K/3D场景额外配置厂商特定InfoFrame。
6.视频数据全链路配置:
○视频采样模块:配置输入数据映射格式,消隐期数据填充规则;
○CSC色彩空间转换模块:配置插值/抽取模式,写入色彩转换系数矩阵(如BT601/BT709与RGB互转、全范围转有限范围);
○视频打包模块:配置像素重复、色深处理、数据打包格式,将并行视频数据转为TMDS链路所需格式。
7.HDCP配置:若开启HDCP1.x,从厂商存储区读取密钥,配置HDCP控制器,完成认证与加密流程。
8.溢出修复:针对不同版本的DW控制器,执行TMDS软件复位,修复寄存器写入溢出问题,保证配置生效。
阶段6:
显示使能与输出(rockchip_dw_hdmi_enable)
保存当前显示模式,执行全链路配置后使能视频输出,显示器接收信号并渲染画面。
阶段7:
禁用与下电(rockchip_dw_hdmi_disable)
禁用PHY、下电TMDS发送器、关闭模块时钟、屏蔽中断,进入低功耗模式。
三、补丁详细分析
1.补丁修改点
diff --git a/drivers/video/drm/dw_hdmi.c b/drivers/video/drm/dw_hdmi.cindex 6bdee673b55..41bd5122c7a 100644--- a/drivers/video/drm/dw_hdmi.c+++ b/drivers/video/drm/dw_hdmi.c@@ -2635,13 +2635,14 @@int rockchip_dw_hdmi_get_timing(struct rockchip_connector *conn, struct display_int ret = 0, i, vic;struct connector_state *conn_state = &state->conn_state;struct dw_hdmi *hdmi = conn->data;-struct edid *edid = (struct edid *)conn_state->edid;+struct edid *edid;+const u8 def_modes_vic[6] = {4, 16, 2, 17, 31, 19}; if (!hdmi)return -EFAULT; conn_state->edid = drm_do_get_edid(&hdmi->adap);+edid = (struct edid *)conn_state->edid; if (conn_state->edid) {hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
2.根因分析
1.空指针赋值时序错误:conn_state->edid是动态分配的内存,仅当执行drm_do_get_edid后才会完成内存分配与EDID数据写入;修改前在函数开头就将edid指针赋值为conn_state->edid,此时该指针为NULL,后续即使drm_do_get_edid执行成功,edid指针仍为NULL,不会同步更新。
2.HDMI/DVI模式误判:drm_detect_hdmi_monitor(edid)传入NULL指针,函数执行失败并返回false,导致hdmi->sink_is_hdmi = false,驱动将HDMI显示器错误识别为DVI显示器。
3.紫屏故障触发逻辑:DVI仅支持RGB格式,不支持YUV格式与AVI InfoFrame;当驱动误判为DVI模式时,会关闭InfoFrame发送,若此时输出格式为YUV(RK平台默认常用配置),显示器将YUV数据按RGB格式解析,最终出现色彩完全错乱的紫屏、花屏。
4.附加风险:空指针访问还可能导致Uboot崩溃、HDMI音频功能异常、显示模式识别错误等问题。
3.补丁解决的核心问题
1.修复空指针访问,调整edid指针赋值时序,保证EDID读取完成后再给指针赋值,确保指针有效性;
2.修复HDMI/DVI模式误判,drm_detect_hdmi_monitor可正常解析EDID数据,正确识别HDMI显示器;
3.彻底解决YUV输出紫屏问题:正确识别HDMI模式后,驱动正常发送AVI InfoFrame,显示器可正确解析YUV/RGB格式,避免色彩错乱;
4.提升显示器兼容性,修复EDID读取成功但显示异常的问题,兼容更多电视、拼接屏、商用显示器等HDMI终端。
四、受影响的芯片范围与原因
1.受影响芯片
RK3576、RK3399、RK3328、RK3228、RK3229、RK3288、RK3399Pro、RK3568、RK3566、RK3528,所有使用Synopsys DesignWare HDMI 2.0 TX控制器的瑞芯微芯片。
2.受影响的核心原因
1.驱动代码共用:上述芯片的Uboot HDMI驱动完全共用dw_hdmi.c核心代码,rockchip_dw_hdmi_get_timing函数的时序bug存在于全平台;
2.控制器架构一致:所有芯片均集成Synopsys DW HDMI TX控制器,驱动逻辑与bug触发条件完全一致;
3.输出格式特性:RK中高端芯片默认优先使用YUV格式输出,更容易触发紫屏问题;低端芯片即使默认RGB输出,也存在模式误判、HDMI音频/高级功能失效的问题;
4.Uboot版本迭代影响:该bug出现在conn_state->edid改为动态内存分配的Uboot版本,所有升级到该版本的RK平台均会受影响。
五、补丁的应用场景与价值
1.Uboot启动画面保障:修复Uboot阶段HDMI紫屏、无画面问题,保证启动logo、升级界面、命令行界面正常显示;
2.工厂产线适配:避免产线烧录、整机测试时出现批量HDMI显示异常,提升生产良率;
3.系统Recovery/OTA升级:保证安卓/Linux系统Recovery模式、OTA升级界面正常显示,避免用户无法操作的故障;
4.工业嵌入式场景:适配基于Uboot的裸机显示、工业控制场景,保证HDMI输出稳定,避免无画面、色彩异常问题;
5.终端兼容性提升:修复对EDID时序特殊的显示器的兼容性,解决“有信号但无画面/紫屏”的行业常见问题。
审核编辑 黄宇
-
HDMI
+关注
关注
34文章
1914浏览量
161351 -
Uboot
+关注
关注
4文章
132浏览量
30023
发布评论请先 登录
BSP调试#04:HDMI TX(RK3588)
RK3568+Android11 GT911触控驱动移植与配置实战
RK平台声卡基础知识总结(基于ALSA框架)
Rockchip CIF驱动深度解析:从架构设计到电源计数补丁修复
深入解析RK平台GPIO驱动:从原理到调试,开发者必看指南
RK 平台 SPI 开发完全指南(驱动 + 配置 + 测试 + 优化)
RK3506 MIPI转HDMI显示开发实战:从硬件到驱动全解析
技术分享 | RK3588增加Xenomai3实时补丁
【迅为工业RK3568稳定可靠】itop-3568开发板Linux驱动开发实战:RK3568内核模块符号导出详解
Linux修改uboot启动延时方法详细攻略,触觉智能RK3568开发板演示
RK3562开发板uboot下GPIO的控制方法,触觉智能嵌入式方案商
RK平台Uboot HDMI驱动分析与补丁详解
评论