HDMI 显示驱动
本文档介绍 RK3588 HDMI 2.1 发送器在 Linux 6.1 内核中的驱动配置、设备树绑定和用户态调试(音频 + 视频)。
适用范围: RK3588 Linux 6.1 Debian 12 / Ubuntu 22.04 系统,C-3588LQ V1.0 + SHIMETAPI-M5-R2A V1.0 底板。
1. 概念基础
1.1 HDMI 是什么
HDMI(High-Definition Multimedia Interface)用一根线同时传视频和音频,RK3588 内置 HDMI 2.1 发送器:
| 特性 | 说明 |
|---|---|
| 最高分辨率 | 7680×4320(8K)@ 60 fps |
| 最高带宽 | 48 Gbps |
| 色深 | 8 / 10 / 12 bit |
| HDR | HDR10 / Dolby Vision |
| 音频 | 多通道 PCM / Dolby Atmos |
| CEC | HDMI CEC 控制 |
| HDCP | HDCP 2.2 / 1.4 |
表里的 CEC 是 HDMI 的设备控制通道(比如用电视遥控器操作板子),HDCP 则是版权保护协议,播放加密内容时要用到。
1.2 内核子系统
HDMI 在内核由三类驱动组成:
- Display Port / HDMI 物理层(PHY)
- HDMI 发送器(controller)
- ASoC HDMI Codec(音频)
视频走 DRM/KMS(内核显示接口),音频走 ASoC,两套接口在 HDMI 这里汇合。
2. 准备工作
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3588LQ 核心板 + SHIMETAPI-M5-R2A 底板 | 1 | HDMI 内置 |
| 调试串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| HDMI 显示器 | HDMI 2.0+ | 1 | 已连接 |
| HDMI 线 | HDMI 2.0 / 2.1 | 1 | 建议使用认证线缆 |
2.2 引脚
HDMI 接口在底板上已直接引出,TMDS 数据/时钟差分对见底板原理图标注。
3. 软件准备
3.1 内核配置
HDMI 要的配置比想象中多:视频走 DRM 那套,CEC 和音频各有开关:
CONFIG_DRM=y
CONFIG_DRM_ROCKCHIP=y
CONFIG_ROCKCHIP_VOP2=y
CONFIG_ROCKCHIP_DW_HDMI=y
CONFIG_DRM_DW_HDMI=y
CONFIG_DRM_DW_HDMI_CEC=y
CONFIG_SND_SOC_HDMI_CODEC=y /* HDMI 音频 codec */
CONFIG_HDMI=y
CONFIG_OF=y3.2 设备树
HDMI 控制器节点如下,phys 引用的 PHY 是物理层收发电路,负责把数字信号变成线上传输的差分信号:
hdmi_in: hdmi@fe0a0000 {
compatible = "rockchip,rk3588-dw-hdmi";
reg = <0x0 0xfe0a0000 0x0 0x20000>;
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_HDMI>, <&cru CLK_HDMI_REF>;
clock-names = "pclk", "ref";
resets = <&cru SRST_HDMI>;
reset-names = "hdmi";
phys = <&hdmi_phy>;
phy-names = "phy";
pinctrl-names = "default";
pinctrl-0 = <&hdmitx0_cec &hdmim0_tx_hpd>;
status = "okay";
};4. 设备端 HDMI
以下命令都在板子上执行,先确认连接状态,再核对分辨率信息。
4.1 HDMI 连接状态
cat /sys/class/drm/card0-HDMI-A-1/status实机输出:
connected这台板子的 HDMI 已识别,显示器也已连接。
4.2 当前分辨率与支持列表
cat /sys/class/drm/card0-HDMI-A-1/modes实机输出(节选):
1920x1080
1920x1080
1920x1080
1920x1080
1920x1080
1920x1080i
1680x1050
...主显示器支持 1920x1080(含逐行 / 隔行),列表里还有 1680×1050 等常见分辨率。
4.3 查看 EDID 信息(显示器标识)
EDID 是显示器存在自己芯片里、通过 HDMI 线上报的自述信息(厂商、型号、支持的分辨率),edid-decode 能把它翻译成人能读的内容:
apt install -y edid-decode
cat /sys/class/drm/card0-HDMI-A-1/edid | edid-decode4.4 当前 mode
cat /sys/class/drm/card0-HDMI-A-1/mode 2>/dev/null
# 不可用时尝试:
cat /sys/class/drm/card0-HDMI-A-1/status部分设备 / 内核版本没有
mode这个文件,此时可用modetest(见下一节)替代。
5. 用户态分辨率测试(modetest)
modetest 是 libdrm 自带的测试工具,不依赖桌面环境就能切换分辨率:
apt install -y libdrm-tests
# 列出所有 connector / CRTC
modetest -M rockchip -c输出节选:
Connectors:
id encoder status name
38 7 connected HDMI-A-1
CRTCs:
id fb pos size
46 47 (0,0) 1920x1080# 设置 38 这个 connector(HDMI)用 CRTC 46,1920x1080@60
modetest -M rockchip -s 38@46:1920x1080
# 4K 测试(显示器需支持)
modetest -M rockchip -s 38@46:3840x2160命令执行后屏幕出现测试图,说明 HDMI 通路正常。
6. HDMI 音频输出
HDMI 不只送视频,声音也从同一条线出去,内核里对应一张独立的声卡。
6.1 列出 HDMI 音频 PCM
aplay -l实机输出(节选):
card 1: rockchiphdmi1 [rockchip-hdmi1], device 0: rockchip-hdmi1 i2s-hifi-06.2 播放到 HDMI
# 直接指定 card=hdmi1 device=0
aplay -D plughw:1,0 /usr/share/sounds/alsa/Front_Center.wav
# 或通过 PulseAudio 默认 sink
pactl set-default-sink alsa_output.platform-hdmi1.analog-stereo第一种写法里 -D plughw:1,0 表示直接指定 1 号声卡的 0 号设备;第二种走 PulseAudio(桌面常用的音频服务),把默认输出切到 HDMI。
6.3 HDMI 音 / 视频同步测试
# 测试一段 H264 + AAC mp4
gst-launch-1.0 filesrc location=video.mp4 \
! qtdemux \
! h264parse ! mp4videodec ! v4l2h264enc \
! h264parse ! flvmux streamid=1 \
! rtmpsink location=rtmp://...实际镜像 / 编码 / 推流配置按你的业务调整。
7. 设备树添加 HDMI(PC 端)
[电脑端] 板级 .dts 修改 HDMI 节点头:
&hdmi_in {
status = "okay"; /* DTS 默认 disabled,需 enable */
};
/* 可选:调分辨率 / clk 父级 */
&vop2 {
assigned-clocks = <&cru DCLK_VOP0>;
assigned-clock-parents = <&cru PLL_V0>;
};电脑端 重新编译烧录:
./build.sh kernel
./mkfirmware.sh烧录重启后回到板子,重复 4.1 的命令,status 为 connected 就算配置成功。
另外,如修改 HDMI 物理特性(如 eDP 替 HDMI),需要同步调整 PHY 节点(不在此文档范围)。
8. 代码解读
8.1 驱动注册
HDMI 发送器驱动同样是 platform driver,按 compatible 匹配设备树:
// drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c(简化)
static struct platform_driver dw_hdmi_rockchip_driver = {
.probe = dw_hdmi_rockchip_probe,
.remove = dw_hdmi_rockchip_remove,
.driver = {
.name = "dw_hdmi-rockchip",
.of_match_table = dw_hdmi_rockchip_match,
},
};
static const struct of_device_id dw_hdmi_rockchip_match[] = {
{ .compatible = "rockchip,rk3588-dw-hdmi" },
{ /* sentinel */ }
};8.2 调用链
modetest 设置一次显示模式,内核里的完整路径:
用户空间: modetest
→ open(/dev/dri/card0)
→ ioctl(DRM_IOCTL_MODE_GETRESOURCES) /* 列出资源 */
→ ioctl(DRM_IOCTL_MODE_GETCONNECTOR) /* 列出 connector */
→ ioctl(DRM_IOCTL_MODE_SETCRTC)
→ dw_hdmi_rockchip_atomic_commit()
→ dw_hdmi_setup() /* 配置 PHY + 控制器 */
→ set PHY 时序
→ enable TMDS output
→ HDMI 物理层输出9. 故障排除
9.1 无输出
dmesg | grep -i hdmi
cat /proc/device-tree/soc/hdmi@fe0a0000/status
cat /sys/class/drm/card0-HDMI-A-1/status9.2 分辨率 / 模式错误
- 检查 HDMI 线(线缆质量影响带宽 → 影响 4K / HDR)
- 显示器 EDID 异常时手动用
modetest -s强设分辨率
9.3 HDMI 音频无声
aplay -l # 确认 HDMI 音频 PCM 出现
amixer contents | grep HDMI # 查看 HDMI 控件
pactl list short sinks # PA 默认 sink