Reference:https://china.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/v_hdmi_rx_ss/v3_2/pg236-v-hdmi-rx-ss.pdf
对于HDMI 1.4/2.0 Receiver Subsystem IP在不细究具体实现的情况,可以简单的把其当成就是HDMI 1.4/2.0 Transmitter Subsystem IP的各种信号方向由输入变成输出,由输出变成输入。HDMI 1.4/2.0 Receiver Subsystem IP支持的功能和不支持的功能和HDMI 1.4/2.0 Transmitter Subsystem IP相同。因为是接受端,HDMI1.4/2.0 Receiver Subsystem IP可以支持整型或者非整型帧率的视频。因此,HDMI1.4/2.0 Receiver Subsystem IP的细节可以直接参考HDMI 1.4/2.0 Transmitter Subsystem IP。
与HDMI TX Subsystem相似的,HDMI RX Subsystem通常也会响应两种事件,一种是来自Source device的5V HDMI Cable Detect(我的理解,实质就是HPD,但是Flow来看,Cable Detect有自己独立的中断回调处理,用来使能PHY中RX的IO Buffer),另一种是来自Source device的HDMI Video Stream发生了变化。
图 1
HDMI 1.4/2.0 RX Subsystem的软件flow如图1所示,细节图请参考pg236-v-hdmi-rx-ss.pdf
和HDMI 1.4/2.0 TX Subsystem类似的,当硬件系统中集成了Subsystem IP后,需要在软件中对其进行配置。在软件中引入HDMI 1.4/2.0 RX Subsystem的方式流程如下。
(1) 包含xv_hdmirxss.h头文件
(2) 定义rx subsystem对象: XV_HdmiRxSs HdmiRxSs
(3) 定义配置rx subsystem的配置数据结构体指针: XV_HdmiRxSs_Config *XV_HdmiRxSs_ConfigPtr
(4) 给HDMI 1.4/2.0 RX Subsystem设置256 bytes的E-EDID数据
void XV_HdmiRxSs_SetEdidParam(XV_HdmiRxSs *InstancePtr,u8 *EdidDataPtr,u16 Length);
(5) 初始化HDMI 1.4/2.0 RX Subsystem
XV_HdmiRxSs_Config* XV_HdmiRxSs_LookupConfig(u32 DeviceId);
int XV_HdmiRxSs_CfgInitialize(XV_HdmiRxSs *InstancePtr,XV_HdmiRxSs_Config *CfgPtr,u32 EffectiveAddr);
(6) 连接中断控制器,使能中断
int XIntc_Connect(XIntc *InstancePtr,u8 Id, XInterruptHandler Handler,void *CallBackRef);
void XIntc_Enable(XIntc *InstancePtr,u8 Id);
这里要注意的是,EDID/E-EDID是以8 bit的一维数组定义在软件程序中,EDID/E-EDID在HDMI 1.4/2.0 RX Subsystem初始化的时候,由驱动直接将其加载到Subsystem中。
在软件中集成Video PHY Controller的操作流程与HDMI 1.4/2.0 TX Subsystem相同。
(1) 包含xvphy.h的头文件
(2) 定义Video PHY Controller的对象: XVphy Vphy
(3) 定义Video PHY Controller对应配置数据结构的指针:XVphy_Config *XVphyCfgPtr
(4) 软件初始化Video PHY Controller
XVphy_Config *XVphy_LookupConfig(u16 DeviceId);
u32 XVphy_HdmiInitialize(XVphy *IntancePtr,u8 QuadId,XVphy_Config *CfgPtr,u32 SystemFrequency);
这里注意,建议在HDMI 1.4/2.0 RX Subsystem初始化完后再对Video PHY controller进行初始化。
关于HDMI 1.4/2.0 RX Subsystem的中断类型如下所示.
(1) HPD - 热插拔,每次当HDMI线缆的插拔时产生该中断
a. Rising edge -- HDMI线缆连接上
b. Falling edge -- HDMI线缆未连接上
(2) Link Ready -- 和HDMI TX相似,在HDMI RX sub-core中的一个寄存器有1 bit(link status bit)用来记录link_clk的状态。当link_clk稳定时,该位被置为1;当link_clk不稳定时,该位被清为0。当这个link status bit发生变化时将会产生Link Ready中断。
a. Rising edge -- Link clock变为稳定
b.Falling edge -- Link clock变为不稳定
(3) Video Ready -- 该类型中断在HDMI RX sub-core检测到接受到的视频数据流(分辨率,帧率)发生变化时产生。
a. Rising edge -- 数据流变得稳定(StreamUp)
b.Falling edge -- 数据流变得不稳定(StreamDown)
(4) HDMI Receiver Auxiliary Infoframe Interrupt --当Auxiliary Infoframe被接受到时,产生该中断
(5) HDMI Receiver Audio Infoframe Interrupt -- 当Audio Infoframe被接受到时,产生该中断
(6) HDCP 1.4 Interrupt (需使能HDCP 1.4)
(7) HDCP 1.4 Timer Interrupt(需使能HDCP 1.4)
图 2
与HDMI 1.4/2.0 TX Subsystem相似,需要为HDMI 1.4/2.0 RX Subsystem设置各种对应的中断的中断处理回调函数,调用下面的API函数。
int XV_HdmiRxSs_SetCallback(XV_HdmiRxSs *InstancePtr,u32 HandlerType,void *CallbackFuncPtr,void *CallbackRef);
在xv_hdmirxss.h中定义好的能使用的中断句柄(handlers)如下:XV_HDMIRXSS_HANDLER_CONNECT, XV_HDMIRXSS_HANDLER_AUX, XV_HDMIRXSS_AUD, XV_HDMIRXSS_HANDLER_STREAM_UP, XV_HDMIRXSS_HANDLER_STREAM_DOWN, XV_HDMIRXSS_STREAM_INIT
(1) XV_HDMIRXSS_HANDLER_CONNECT
每当HDMI RX检测到HPD信号时,会产生该中断。
a. 当HDMI cable连接上时,使能Video PHY Controller中差分输入时钟buffer;没有连接时,无效Video PHY Controller中差分输入时钟Buffer.
void XVphy_IBufDsEnable(XVphy *InstancePtr,u8 QuadId,XVphy_DirectionType Dir,u8 Enable);
b. 当HDMI cable没有连接上时,清除Video PHY RX TMDS Clock ratio.
Vphy.HdmiRxTmdsClockRatio = 0;
(2) XV_HDMIRXSS_HANDLER_AUX
每当HDMI RX接受到Auxiliary InfoFrame时,该中断产生,回调函数可以使用该InfoFrame的数据对应用程序进行操作更新。
(3) XV_HDMIRXSS_HANDLER_AUD
每当有效的音频数据流被检测到或者有效的音频通道发生变化时,该中断产生。
(4) XV_HDMIRXSS_HANDLER_STREAM_UP
当HDMI视频流被锁定时,该中断产生。
(5) XV_HDMIRXSS_HANDLER_STREAM_DOWN
当HDMI视频流由锁定变成没有被锁定时,该中断产生。这里注意,如果HDMI 1.4/2.0 RX Subsystem在确定的时间延迟中,video stream remains unlocked,则应用程序可以将系统设置进入待机模式,同时启动一个定时器来唤醒。
(6) XV_HDMIRXSS_HANDLER_STREAM_INIT
每当Video PHY Controller给HDMI 1.4/2.0 RX Subsystem的时钟稳定,且HDMI 1.4/2.0 RX Subsystem开始锁定数据流时,该中断产生。
a. 检测HDMI cable是否连接(1 - Connected; 0 - Disconnected)
XV_HdmiRxSs *HdmiRxSsPtr = (XV_HdmiRxSs *)CallbackRef;
HdmiRxSsPtr->IsStreamConnected
b. 从HDMI RX中获得视频流信息
XVidC_VideoStream *XV_HdmiRxSs_GetVideoStream(XV_HdmiRxSs *InstancePtr);
c. 基于HDMI RX收到的视频流信息,计算HDMI MMCM的参数
u32 XVphy_HdmiCfgCalcMmcmParam(XVphy *InstancePtr,u8 QuadId,XVphy_ChannelId ChId,XVphy_DirectionType Dir,XVidC_PixelsPerClock Ppc,XVidC_ColorDepth Bpc);
d. 使能Video PHY Controller中的MMCM
void XVphy_MmcmStart(XVphy *InstancePtr,u8 QuadId,XVphy_DirectionType Dir);
这里要注意,QuadId并没有使用需要设置为0.
XVphy_MmcmStart(&Vphy,0,XVPHY_DIR_RX);
(7) XV_HDMIRXSS_HANDLER_HDCP_AUTHENTICATE
当HDMI RX Subsystem使能了HDCP 1.4或者HDCP 2.3后,在HDCP通过了认证后产生。
-> XVPHY_HDMI_HANDLER_RXINT
-> XVPHY_HDMI_HANDLER_RXREADY
使用如下API进行挂起(hooked up)中断
void XVphy_SetHdmiCallback(XVphy *InstancePtr,XVphy_HdmiHandlerType HandlerType,void *CallbackFunc,void *CallbackRef);
(1) XVPHY_HDMI_HANDLER_RXINIT
每当Video Controller检测到HDMI RX的参考时钟发生变化时产生。
a. 为HDMI 1.4/2.0 RX Subsystem初始化一个参考时钟变化处理.
void XV_HdmiRxSs_RefClockChangeInit(XV_HdmiRxSs *InstancePtr);
b. 将HDMI RX Subsystem获得的参考TMDS clock设置给Video PHY Controller
VphyPtr->HdmiRxTmdsClockRatio = HdmiRxSs.TMDSClockRatio;
(2) VPHY_HDMI_HANDLER_RXREADY
每次Video PHY Controller对于RX的reset完成时,该中断产生。
a. 检查Video PHY Controller中PLL的类型
XVphy_PllType XVphy_GetPllType(XVphy *InstancePtr,u8 QuadId,XVphy_DirectionType Dir,XVphy_ChannelId ChId);
b. 根据获得的PLL类型来设置HDMI 1.4/2.0 RX Subsystem的视频流信息。
XV_HdmiRxSs_SetStream(XV_HdmiRxSs *InstancePtr,u32 Clock, u32 LineRate)
这里的Clock和LineRate的值都来自于Video PHY Controller.
(1) Cable Plug in
当HDMI线缆连接时,HPD中断产生。调用的中断回调函数的中断类型为XV_HDMIRXSS_HANDLER_CONNECT
(2) Cable Plug out
用HDMI TX不同,HDMI RX收到Cable Plug out中断源时,首先调用的中断回调函数的中断类型是XV_HDMIRXSS_HANDLER_STREAM_DOW,此时是处理RX Stream Down中断;接着调用XV_HDMIRXSS_HANDLER_CONNECT中断回调函数处理HPD中断。
(3) Received Video Stream
a. Video PHY Controller的HDMI RX Init中断被接受到 -- XVPHY_HDMI_HANDLER_RXINIT
b. Video PHY Controller的HDMI RX Ready中断被接受到 -- XVPHY_HDMI_HANDLER_RXREADY
c. RX Audio中断被接受到 -- XV_HDMIRXSS_HANDLER_AUD
d. RX Stream Initialization中断被接受到 -- XV_HDMIRXSS_HANDLER_HDCP_AUTHENTICATE
e. 当视频流数据被锁定住后,RX Stream up中断被接受到 -- XV_HDMIRXSS_HANDLER_STREAM_UP
此时,就可以从HDMI RX Subsystem获得视频流信息了。
XVidC_VidoStream *XV_HdmiRxSs_GetVideoStream(XV_HdmiRxSs *InstancePtr);
(4) Video Stream Change
a. RX Stream Down中断被接受到 -- XV_HDMIRXSS_HANDLER_STREAM_DOWN
b. Video PHY Controller的HDMI RX Init中断被接受到 -- XVPHY_HDMI_HANDLER_RXINIT
c. Video PHY Controller的HDMI RX Ready中断被接受到 -- XVPHY_HDMI_HANDLER_RXREADY
d. RX Audio中断被接受到 -- XV_HDMIRXSS_HANDLER_AUD
e. RX Stream Initialization中断被接受到 -- XV_HDMIRXSS_HANDLER_STREAM_INIT
f. 当视频流数据被锁定住后,RX Stream up中断被接受到 -- XV_HDMIRXSS_HANDLER_STREAM_UP
此时,就可以从HDMI RX Subsystem获得视频流信息了。
XVidC_VideoStream *XV_HdmiRxSs_GetVideoStream(XV_HdmiRxSs *InstancePtr);
(5) Receive Infoframe
HDMI RX接受到了Auxiliary InfoFrame时产生中断 -- XV_HDMIRXSS_HANDLER_AUX