本文基于RockPI 4A单板Debian系统Linux 4.4内核DRM框架介绍HDMI接口 EDID获取方法。
一、EDID介绍EDID(Extended display identification data):扩展显示器识别数据,一般存储在显示器的EEPROM中。
在EDID1.0->EDID1.3版本中,EDID的容量是128Byte,从EDID1.3版本以后,数据容量扩展到256Byte。
一般通过DDC(或I2C)通道读取EDID,从设备地址是0x50。
EDID1.3版本的数据结构见下图:
二、EDID获取
应用程序调用libdrm代码中的drmModeGetConnector()函数,通过ioctl传递宏DRM_IOCTL_MODE_GETCONNECTOR通知Linux内核要获取相关数据(包括EDID)。
在Linux内核中,如果定义了宏CONFIG_DRM_LOAD_EDID_FIRMWARE,内核会先调用drm_load_edid_firmware()函数,从/lib/firmware路径下的对应文件中读取EDID数据;若读取失败或未定义宏CONFIG_DRM_LOAD_EDID_FIRMWARE,内核通过DDC通道和显示器进行通信,获取EDID数据。
1、EDID获取流程
EDID获取流程图
注:上面流程图中提到了DRM Connector的一些函数,后续介绍Connector的初始化过程。
2、DDC通信流程
DDC通信流程图
3、EDID调试
可通过下面两种方法显示EDID数据。
1)、系统dump
## 1、进入单板系统
root@linaro-alip:/sys/class/drm/card0-HDMI-A-1# ls
audioformat device edid mode power subsystem
content_protection dpms enabled modes status uevent
root@linaro-alip:/sys/class/drm/card0-HDMI-A-1# cat edid > edid.bin
## 2、如果单板系统没有hexdump命令,则拷贝到pc
root@ubuntu:/home/run/code# hexdump -C -n 256 edid.bin
00000000 00 ff ff ff ff ff ff 00 41 0c 55 55 01 01 01 01 |........A.UU....|
00000010 0a 19 01 03 80 79 44 78 2a 16 4d 9f 5a 52 9f 26 |.....yDx*.M.ZR.&|
00000020 0e 47 4a a1 08 00 95 00 b3 00 01 01 01 01 01 01 |.GJ.............|
00000030 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c |.......:..q8-@X,|
00000040 45 00 b9 a8 42 00 00 1e 66 21 50 b0 51 00 1b 30 |E...B...f!P.Q..0|
00000050 40 70 36 00 b9 a8 42 00 00 18 00 00 00 fd 00 14 |@p6...B.........|
00000060 4c 1e 53 0f 00 0a 20 20 20 20 20 20 00 00 00 fc |L.S... ....|
00000070 00 50 68 69 6c 69 70 73 20 54 56 0a 20 20 01 2d |.Philips TV. .-|
00000080 02 03 28 f1 4d 1f 90 14 05 13 04 02 03 20 01 12 |..(.M........ ..|
00000090 06 07 29 09 07 07 15 07 50 57 06 00 83 01 00 00 |..).....PW......|
000000a0 67 03 0c 00 10 00 b0 2d 02 3a 80 18 71 38 2d 40 |g......-.:..q8-@|
000000b0 58 2c 25 00 b9 a8 42 00 00 1e 8c 0a a0 14 51 f0 |X,%...B.......Q.|
000000c0 16 00 26 7c 43 00 b9 a8 42 00 00 98 01 1d 80 18 |..&|C...B.......|
000000d0 71 1c 16 20 58 2c 25 00 b9 a8 42 00 00 9e 8c 0a |q.. X,%...B.....|
000000e0 d0 8a 20 e0 2d 10 10 3e 96 00 b9 a8 42 00 00 18 |.. .-..>....B...|
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d |...............=|
00000100
2)、modetest命令
使用modetest命令前,先停止使用/dev/dri/card0节点的应用程序。
在“Linux DRM那些事-libdrm调试准备”中,提到使用killall命令,后续调试时发现比较麻烦(原因:系统会自启动桌面显示)。可以使用systemctl命令,停止桌面显示服务,然后使用modetest命令测试。
## 1.停止桌面显示
root@linaro-alip:~# systemctl stop lightdm.service
[ 682.983722] rockchip-vop ff900000.vop: [drm:vop_crtc_enable] Update mode to 1024x768p60, type: 11
## 2.modetest测试
root@linaro-alip:~# ./modetest
trying to open device 'rockchip'...done
Encoders:
id crtc type possible crtcs possible clones
87 61 TMDS 0x00000001 0x00000000
Connectors:
id encoder status name size (mm) modes encoders
88 87 connected HDMI-A-1 1210x680 26 87
modes:
name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
1920x1080 60 1920 2008 2052 2200 1080 1082 1087 1125 148500 flags: phsync, pvsync; type: driver
...
props:
1 EDID:
flags: immutable blob
blobs:
value:
00ffffffffffff00410c555501010101
0a190103807944782a164d9f5a529f26
0e474aa108009500b300010101010101
010101010101023a801871382d40582c
4500b9a84200001e662150b051001b30
40703600b9a842000018000000fd0014
4c1e530f000a202020202020000000fc
005068696c6970732054560a2020012d
020328f14d1f90140513040203200112
06072909070715075057060083010000
67030c001000b02d023a801871382d40
582c2500b9a84200001e8c0aa01451f0
1600267c4300b9a842000098011d8018
711c1620582c2500b9a84200009e8c0a
d08a20e02d10103e9600b9a842000018
0000000000000000000000000000003d
...
## 3.恢复桌面显示
root@linaro-alip:~# systemctl start lightdm.service
注:本文仅在简书、OSCHINA和今日头条发布过,转载请标注原作者和链接。
,