您的位置:首页 > 其它

Windows显示驱动中读取EDID

2015-07-04 11:45 155 查看
去年刚进实验室的时候,实验室有有人在从事Windows双屏显示驱动的开发。项目难度很大,因为相关Windows的东西基本都是闭源的,资料少之又少,因此项目进展也很慢。我也被配安排帮助开发驱动程序,当时给我的任务是写一个Windows驱动下读取显示器的EDID的程序。

EDID

首先有必要了解一下EDID是什么?

EDID(Extended Display Identification Data :扩展显示标识数据,一种VESA标准数据格式(显卡有四种总线类型:IAS、VESA、PCI、APG,我们现有程序就是VESA总线)):包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、厂商预设值、分辨率、频率范围的限制、显示器名和序列号的字符串等信息。基本EDID有128个字节,保存在display节中,这些信息可通过DDC与系统进行通信,是在显示器和GPU之间进行的。EDID数据读取到之后,可将相关参数传递给PC的显卡驱动,从而做出调整,使显示内容(数据)与显示屏相匹配。

基本的EDID拥有128个字节信息,其信息如下:

0-7: 头信息,由00 FF FF FF FF FF FF 00 这8个字节组成

8-9: 厂商ID

10-11: 产品ID

12-15: 32-bit序列号

16-17 : 制造日期

18-19 : EDID 版本

20-24 : 显示器的基本信息(视频输入定义,最大横向图像尺寸,最大纵向图像尺寸,显示传输特性,特征支持)

25-34 : 显示器的颜色特征

35-37 : Established Timings

38-53 : Standard Timings Identification

54-125:Detailed Timing Description

126: 扩展标志位

127: 求和验证值

EDID目前已经存在五种版本(数据格式),EDID1.0、EDID1.1、EDID1.2、EDID1.3、EDID2.0。另外还一种Enhanced EDID,它时基于EDID 1.3的结构,可以存储更多的数据,数据长度是128+N*128。

EDID能够为显示器的初始化配置提供环境参数,是显示驱动不可缺少的输入数据,因此读取EDID是我本次任务的最终目标。

HDMI:高清晰度多媒体接口

在我手里有参考价值的资料是Windows显卡驱动的中通过HDMI读取EDID的程序。虽然我的目标是通过VGA读取EDID,但是在没有任何驱动开发经验的情况下,有必要先了解一下显卡驱动中HDMI部分的代码,以作为VGA程序开发的借鉴和参考。在看代码的同时,我也调研了HDMI数据传输的机制。下面对此做简要介绍。

HDMI特点

支持EDID和DDC2B标准,设备之间可智能选择最佳匹配连接方式

强大的版权保护机制:HDCP

支持24bit色深处理,(RGB,YCbCr4-4-4,TCbCr4-2-2)

完全兼容DVI接口标准

支持热拔插

采用TMDS(最小传输差分传输技术),利用两个引脚间电压差来传送信号的技术

每个标准的HDMI连接,都包含3个用于传输数据的TMDS传输通道,1个独立的TMDS时钟通道(保证传输时所需的统一时序)。每个TMDS通道都能传输10bits的数据流(有多种编码格式)

HDMI把视频信号分为:R、G、B、H、V五种信号,用TMDS技术编码



数据通道

TMDS:三个通道传输R、G、B三原色,HV编码在B信号通道里传输,R、G的多余位置用来传输音频信号。

DDC:显示数据通道,用来向视频接收装置发送配置信息和数据格式信息;接收装置读取这些E-EDID(增强扩展显示识别数据)

CEC:消费电子控制通道,通过这条通道可以控制视听设备的工作

HDMI输入的源编码格式

视频像素数据(8位)

控制数据(2位)

数据包(4位):包含:音频数据、辅助信息数据

数据传输过程

视频数据传输期

HDMI数据线上传送视频像素信号(数据)

视频信号经过编码,生成3路(3个TMDS数据传输通道,每路8位),共24位视频数据流,输入HDMI发射器中

TMDS通道传输24位视频像素信号,将每通道的8位编码成10位,在每个10位像素时钟周期传送一个最小化的信号序列,视频信号被调制为TMDS数据信号传输出去,被***接收

岛屿数据传输期

TMDS通道上将出现音频数据、辅助信息数据,这些数据每4位一组(即上述的4位数据包)

数据包也被调制成10位一组的TMDS信号,然后发出

视频数据传输期和岛屿数据传输期均开始于一个Guard Band保护频带,Guard Band由2个特殊的字符组成,为了明确限定控制数据传输期之后的跳转是视频数据传输期

控制数据传输期

在前面任意两个数据传输周期之间,每个TMDS包含2位的控制数据

3通道一共6位控制数据,分别为:HSYNC(行同步)、VSYNC(列同步)、CTL0、CTL1、CTL2、CTL3

每个TMDS通道包含2位控制数据,采用从2位到10位的编码方法,在每个控制周期的最后阶段

CTL0、CTL1、CTL2、CTL3组成的头文件,说明下一个周期是:视频数据传输周期or岛屿数据传输周期?

岛屿数据和控制数据是在视频数据传输的隐消期,不会占据带宽。因此一根HDMI数据线就能同时传输视频、音频信号。

上述是HDMI的工作原理,然而显卡驱动代码中并没有类似HDMI数据传输过程的具体实现,只是通过命令直接获取数据,因此可以推测HDMI是通过一个控制器来获取数据的。果然,在HD40的主板原理图上发现了HDMI控制器anx7150。

关于anx7150,我也简要的阅读了其数据手册,主要了解了该控制器的读取EDID的流程图、状态转移图等,并与显卡驱动中进行了核对。

VGA

本次的任务是通过VGA读取EDID,那么有必要了解一下VGA。

VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。如下图所示,VGA接口的接口一共有15个通道,主要的数据通道时: 1、2、3通道,分别传输R、G、B三原色信号,以及13、14通道传输行、场同步信号。



在数据传输类型方面,VGA和HDMI有一定的区别:HDMI完全是数字信号的传输,而VGA则是由数字信号转换为模拟信号,进行传输,因此VGA的接口芯片CS7123或GM7123其实就是一个DAC的转换器。



由上面这两点就产生了一个疑问:

显卡驱动接上显示屏,要想正常工作。首先就必须读取EDID,然后解析EDID,从而完成对不同的显示屏的不同配置。但是根据数据传输通道和信号传输类型,EDID不太可能是通过这五个数据通道传输过来的,也不太可能是将数据转换为模拟信号传输过来的。并且EDID是存储在EEPROM中的一段序列,通常读取时通过I2C来读取的。所以,思考后觉得应该VGA接口上有通道可以构成一个读取EDID的DDC通道。经深入调研,发现VGA上的11、12、15、4引脚是有着其他功能的。根据资料显示:

Pin11:ID0/RES formerly Monitor ID bit 0, reserved since E-DDC

Pin12:ID1/SDA formerly Monitor ID bit 1, I2C data since DDC2

Pin15:ID3/SCL formerly Monitor ID bit 3, I2C clock since DDC2

Pin4 :ID2/RES formerly Monitor ID bit 2, reserved since E-DDC

从中推测实际中Pin12、Pin15很有可能被用来读取EDID,果然在HD40的板子上,有两个GPIO直接连接到了VGA的这两个管脚。另外,从管脚的作用来开,可以通过I2C协议来进行数据读取。在HD40中集成了I2C模块,看看是否能够直接使用处理器中的这个模块。但是处理器的I2C模块的对外管脚却没有连接到VGA管脚上,那么只能通过GPIO来模拟I2C进行VGA的读取。

GPIO

由于要进行软件模拟GPIO,就需要知道如何对GPIO进行操作。根据文档显示:GPIO中共有9个寄存器,其中一个为只读寄存器,2个为只写寄存器,另外6个为可读写寄存器。GPIO的基地址为0xee500000,下表为涉及到GPIO操作所需的寄存器的基本信息。



方案确定后,直接编写代码。尽管代码中I2C的实现很容易,但是关于程序的初始化设置很复杂,涉及到虚拟内存到物理内存的映射,相关配置,这涉及到一系列的参数设置等等。

在读取EDID过程中,遇到了一个花了两天才解决的问题,即使用的显示器的EEPROM无法进行读取(之前据说该显示器就有些问题)。当时显示器能使用,但是却无法读取EDID,这让我不断的尝试修改代码,最后通过换了一个显示器,成功读取了EDID。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: