This is main code of Xilinx HDMI Receiver Subsystem device driver.
Please see xv_hdmirxss.h for more details of the driver.
MODIFICATION HISTORY:
Ver Who Date Changes
1.00 10/07/15 Initial release.
1.1 yh 15/01/16 Added 3D Video support
1.2 yh 20/01/16 Added remapper support
1.3 yh 01/02/16 Added set_ppc api
1.4 yh 01/02/16 Removed xil_print "Cable (dis)connected"
1.5 yh 01/02/16 Removed xil_printf("Active audio channels...)
1.6 yh 15/02/16 Added default value to XV_HdmiRxSs_ConfigRemapper
1.7 MG 03/02/16 Added HDCP support
1.8 MG 10/02/16 Moved HDCP 2.2 reset from stream up/down callback
to connect callback
1.9 MH 15/03/16 Added HDCP authenticated callback support
1.10 MH 23/04/16 1. HDCP 1.x driver now uses AXI timer 4.1, so updated
to use AXI Timer config structure to determine timer
clock frequency
2. HDCP 1.x driver has fixed the problem where the
reset for the receiver causes the entire DDC peripheral
to get reset. Based on this change the driver has been
updated to use XV_HdmiRxSs_HdcpReset and
XV_HdmiRxSs_HdcpReset functions directly.
3. Updated XV_HdmiRxSs_HdcpEnable and
XV_HdmiRxSs_HdcpEnable functions to ensure that
HDCP 1.4 and 2.2 are mutually exclusive.
This fixes the problem where HDCP 1.4 and 2.2
state machines are running simultaneously.
1.11 MG 13/05/16 Added DDC peripheral HDCP mode selection to XV_HdmiRxSs_HdcpEnable
1.12 MH 23/06/16 Added HDCP repeater support.
1.13 YH 18/07/16 1. Replace xil_print with xdbg_printf.
2. Replace MB_Sleep() with usleep()
1.14 YH 25/07/16 Used UINTPTR instead of u32 for BaseAddress
XV_HdmiRxSs_CfgInitialize
1.15 MH 26/07/16 Updates for automatic protocol switching
1.16 MH 05/08/16 Updates to optimize out HDCP when excluded
1.17 YH 17/08/16 Remove sleep in XV_HdmiRxSs_ResetRemapper
squash unused variable compiler warning
Added Event Log
1.18 MH 08/10/16 Improve HDCP 1.4 authentication
1.19 MG 31/10/16 Fixed issue with reference clock compensation in
XV_HdmiRxSS_SetStream
1.20 YH 14/11/16 Added API to enable/disable YUV420/Pixel Drop Mode
for video bridge
1.21 YH 14/11/16 Remove Remapper APIs
Replace XV_HdmiRxSs_ConfigRemapper API with
XV_HdmiRxSs_ConfigBridgeMode API as remapper feature is
moved to video bridge and controlled by HDMI core
1.22 MMO 03/01/17 Add compiler option(XV_HDMIRXSS_LOG_ENABLE) to enable
Log
Move global variable XV_HdmiRx_VSIF VSIF to local
XV_HdmiRxSs_RetrieveVSInfoframe API
Move HDCP related API's to hdmirxss_hdcp.c
1.23 MMO 10/02/17 Added Sync Loss and HDMI/DVI Interrupt Support
1.4 YH 07/07/17 Add new log type XV_HDMIRXSS_LOG_EVT_SETSTREAM_ERR
Report HDMI/DVI mode in HDMI example design info log
1.41 MMO 21/07/17 CR-979900 (Fix)
Removed the HDCP Push Event API Call when the
Aux Callback event happen
MH 09/08/17 Added function XV_HdmiRxSs_HdcpSetCapability
1.42 YH 06/10/17 Added function XV_HdmiRxSs_GetAudioFormat
EB 10/10/17 Updated function XV_HdmiRxSs_ReportAudio to report
audio format
5.00 YH 16/11/17 Added dedicated reset for each clock domain
16/11/17 Added bridge overflow interrupt
EB 16/01/18 Added parsing of InfoFrames during AuxCallback
Changed XV_HdmiRxSs_RetrieveVSInfoframe's input
parameter type
Added function XV_HdmiRxSs_GetAviInfoframe,
XV_HdmiRxSs_GetGCP, XV_HdmiRxSs_GetAudioInfoframe,
XV_HdmiRxSs_GetVSIF
Updated XV_HdmiRxSs_ConfigBridgeMode so Pixel
Pepetition is based on received AVI InfoFrame
SM 28/02/18 Added definition of XV_HdmiRxSS_SetAppVersion() API
5.10 MMO 06/04/18 Updated XV_HdmiRxSs_ToggleHpd and XV_HdmiRxSs_Stop
for cleaner HPD flow during transition from HDMI2.0
to HDMI1.4
YH 13/04/18 Fixed a bug in XV_HdmiRxSs_BrdgOverflowCallback
******************************************************************************/
/***************************** Include Files *********************************/
125 "/proj/xhdsswstaff/saddepal/rebase_esw/dummy/embeddedsw/XilinxProcessorIPLib/drivers/v_hdmirxss/src/xv_hdmirxss.c" 2
126 "/proj/xhdsswstaff/saddepal/rebase_esw/dummy/embeddedsw/XilinxProcessorIPLib/drivers/v_hdmirxss/src/xv_hdmirxss.c" 2
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/**
This typedef declares the driver instances of all the cores in the subsystem
*/
typedef struct
{
XV_HdmiRx HdmiRx;
} XV_HdmiRxSs_SubCores;
/**************************** Local Global ***********************************/
/** Define Driver instance of all sub-core included in the design */
XV_HdmiRxSs_SubCores XV_HdmiRxSs_SubCoreRepo[XPAR_XV_HDMIRXSS_NUM_INSTANCES];
/************************** Function Prototypes ******************************/
static void XV_HdmiRxSs_GetIncludedSubcores(XV_HdmiRxSs *HdmiRxSsPtr,
u16 DevId);
static void XV_HdmiRxSs_WaitUs(XV_HdmiRxSs *InstancePtr, u32 MicroSeconds);
static void XV_HdmiRxSs_RetrieveVSInfoframe(XV_HdmiRxSs *HdmiRxSs);
static int XV_HdmiRxSs_RegisterSubsysCallbacks(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ConnectCallback(void *CallbackRef);
static void XV_HdmiRxSs_BrdgOverflowCallback(void *CallbackRef);
static void XV_HdmiRxSs_AuxCallback(void *CallbackRef);
static void XV_HdmiRxSs_AudCallback(void *CallbackRef);
static void XV_HdmiRxSs_LnkStaCallback(void *CallbackRef);
static void XV_HdmiRxSs_DdcCallback(void *CallbackRef);
static void XV_HdmiRxSs_StreamDownCallback(void *CallbackRef);
static void XV_HdmiRxSs_StreamInitCallback(void *CallbackRef);
static void XV_HdmiRxSs_StreamUpCallback(void *CallbackRef);
static void XV_HdmiRxSs_SyncLossCallback(void *CallbackRef);
static void XV_HdmiRxSs_ModeCallback(void *CallbackRef);
static void XV_HdmiRxSs_ReportCoreInfo(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ReportTiming(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ReportLinkQuality(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ReportAudio(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ReportInfoFrame(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ReportSubcoreVersion(XV_HdmiRxSs *InstancePtr);
static void XV_HdmiRxSs_ConfigBridgeMode(XV_HdmiRxSs *InstancePtr);
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
This macros selects the bridge YUV420 mode
- Parameters
-
InstancePtr | is a pointer to the HDMI RX Subsystem |
*****************************************************************************/
#define XV_HdmiRxSs_BridgeYuv420(InstancePtr,Enable)
/*****************************************************************************/
/**
This macros selects the bridge pixel repeat mode
- Parameters
-
InstancePtr | is a pointer to the HDMI RX Subsystem |
*****************************************************************************/
#define XV_HdmiRxSs_BridgePixelDrop(InstancePtr,Enable)
/************************** Function Definition ******************************/
void XV_HdmiRxSs_ReportInfo(XV_HdmiRxSs *InstancePtr)
{
xil_printf("------------\r\n");
xil_printf("HDMI RX SubSystem\r\n");
xil_printf("------------\r\n");
XV_HdmiRxSs_ReportCoreInfo(InstancePtr);
XV_HdmiRxSs_ReportSubcoreVersion(InstancePtr);
xil_printf("\r\n");
xil_printf("HDMI RX Mode - ");
if (InstancePtr->HdmiRxPtr->Stream.IsHdmi == (TRUE)) {
xil_printf("HDMI\r\n");
}
else {
xil_printf("DVI\r\n");
}
xil_printf("------------\r\n");
xil_printf("HDMI RX timing\r\n");
xil_printf("------------\r\n");
XV_HdmiRxSs_ReportTiming(InstancePtr);
xil_printf("Link quality\r\n");
xil_printf("---------\r\n");
XV_HdmiRxSs_ReportLinkQuality(InstancePtr);
xil_printf("Audio\r\n");
xil_printf("---------\r\n");
XV_HdmiRxSs_ReportAudio(InstancePtr);
xil_printf("Infoframe\r\n");
xil_printf("---------\r\n");
XV_HdmiRxSs_ReportInfoFrame(InstancePtr);
xil_printf("\r\n");
}
/*****************************************************************************/
/**
This function reports list of cores included in Video Processing Subsystem
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance. |
- Returns
- None
******************************************************************************/
static void XV_HdmiRxSs_ReportCoreInfo(XV_HdmiRxSs *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
xil_printf("\r\n ->HDMI RX Subsystem Cores\r\n");
/* Report all the included cores in the subsystem instance */
if(InstancePtr->HdmiRxPtr)
{
xil_printf(" : HDMI RX \r\n");
}
}
/******************************************************************************/
/**
This function installs a custom delay/sleep function to be used by the
XV_HdmiRxSs driver.
- Parameters
-
InstancePtr | is a pointer to the HdmiSsRx instance.
|
CallbackFunc | is the address to the callback function.
|
CallbackRef | is the user data item (microseconds to delay) that
will be passed to the custom sleep/delay function when it is
invoked. |
- Returns
- None.
- Note
- None.
*******************************************************************************/
void XV_HdmiRxSs_SetUserTimerHandler(
XV_HdmiRxSs InstancePtr,
XVidC_DelayHandler CallbackFunc, void *CallbackRef)
{
/ Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(CallbackFunc != NULL);
Xil_AssertVoid(CallbackRef != NULL);
InstancePtr->UserTimerWaitUs = CallbackFunc;
InstancePtr->UserTimerPtr = CallbackRef;
}
/******************************************************************************/
/**
This function is the delay/sleep function for the XV_HdmiRxSs driver. For the
Zynq family, there exists native sleep functionality. For MicroBlaze however,
there does not exist such functionality. In the MicroBlaze case, the default
method for delaying is to use a predetermined amount of loop iterations. This
method is prone to inaccuracy and dependent on system configuration; for
greater accuracy, the user may supply their own delay/sleep handler, pointed
to by InstancePtr->UserTimerWaitUs, which may have better accuracy if a
hardware timer is used.
- Parameters
-
InstancePtr | is a pointer to the HdmiSsRx instance.
|
MicroSeconds | is the number of microseconds to delay/sleep for. |
- Returns
- None.
- Note
- None.
*******************************************************************************/
static void XV_HdmiRxSs_WaitUs(XV_HdmiRxSs <em>InstancePtr, u32 MicroSeconds)
{
/ Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if (MicroSeconds == 0) {
return;
}
if (InstancePtr->UserTimerWaitUs != NULL) {
/* Use the timer handler specified by the user for better
accuracy. */
InstancePtr->UserTimerWaitUs(InstancePtr, MicroSeconds);
}
else {
usleep(MicroSeconds);
}
}
/*****************************************************************************/
/**
This function calls the interrupt handler for HDMI RX
- Parameters
-
InstancePtr | is a pointer to the HDMI RX Subsystem |
*****************************************************************************/
void XV_HdmiRxSS_HdmiRxIntrHandler(XV_HdmiRxSs *InstancePtr)
{
XV_HdmiRx_IntrHandler(InstancePtr->HdmiRxPtr);
}
/*****************************************************************************/
/**
This function register's all sub-core ISR's with interrupt controller and
any subsystem level call back function with requisite sub-core
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be
worked on. |
*****************************************************************************/
static int XV_HdmiRxSs_RegisterSubsysCallbacks(XV_HdmiRxSs *InstancePtr)
{
XV_HdmiRxSs *HdmiRxSsPtr = InstancePtr;
//Register HDMI callbacks
if(HdmiRxSsPtr->HdmiRxPtr) {
/*
Register call back for Rx Core Interrupts.
*/
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_CONNECT,
(void *)XV_HdmiRxSs_ConnectCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_BRDG_OVERFLOW,
(void *)XV_HdmiRxSs_BrdgOverflowCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_AUX,
(void *)XV_HdmiRxSs_AuxCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_AUD,
(void *)XV_HdmiRxSs_AudCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_LNKSTA,
(void *)XV_HdmiRxSs_LnkStaCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_DDC,
(void *)XV_HdmiRxSs_DdcCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_STREAM_DOWN,
(void *)XV_HdmiRxSs_StreamDownCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_STREAM_INIT,
(void *)XV_HdmiRxSs_StreamInitCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_STREAM_UP,
(void *)XV_HdmiRxSs_StreamUpCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_SYNC_LOSS,
(void *)XV_HdmiRxSs_SyncLossCallback,
(void *)InstancePtr);
XV_HdmiRx_SetCallback(HdmiRxSsPtr->HdmiRxPtr,
XV_HDMIRX_HANDLER_MODE,
(void *)XV_HdmiRxSs_ModeCallback,
(void *)InstancePtr);
}
return(XST_SUCCESS);
}
/*****************************************************************************/
/**
This function queries the subsystem instance configuration to determine
the included sub-cores. For each sub-core that is present in the design
the sub-core driver instance is binded with the subsystem sub-core driver
handle
- Parameters
-
HdmiRxSsPtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
static void XV_HdmiRxSs_GetIncludedSubcores(XV_HdmiRxSs *HdmiRxSsPtr, u16 DevId)
{
HdmiRxSsPtr->HdmiRxPtr =((HdmiRxSsPtr->Config.HdmiRx.IsPresent) ?
(&XV_HdmiRxSs_SubCoreRepo[DevId].HdmiRx) : NULL);
}
/*****************************************************************************/
/**
This function initializes the video subsystem and included sub-cores.
This function must be called prior to using the subsystem. Initialization
includes setting up the instance data for top level as well as all included
sub-core therein, and ensuring the hardware is in a known stable state.
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on.
|
CfgPtr | points to the configuration structure associated with the
subsystem instance.
|
EffectiveAddr | is the base address of the device. If address
translation is being used, then this parameter must reflect the
virtual base address. Otherwise, the physical address should be
used. |
- Returns
- XST_SUCCESS if initialization is successful else XST_FAILURE
******************************************************************************/
int XV_HdmiRxSs_CfgInitialize(
XV_HdmiRxSs *InstancePtr,
XV_HdmiRxSs_Config *CfgPtr,
UINTPTR EffectiveAddr)
{
XV_HdmiRxSs *HdmiRxSsPtr = InstancePtr;
/* Verify arguments */
Xil_AssertNonvoid(HdmiRxSsPtr != NULL);
Xil_AssertNonvoid(CfgPtr != NULL);
Xil_AssertNonvoid(EffectiveAddr != (UINTPTR)NULL);
/* Setup the instance */
memcpy((void *)&(HdmiRxSsPtr->Config), (const void *)CfgPtr,
sizeof(XV_HdmiRxSs_Config));
HdmiRxSsPtr->Config.BaseAddress = EffectiveAddr;
/* Determine sub-cores included in the provided instance of subsystem */
XV_HdmiRxSs_GetIncludedSubcores(HdmiRxSsPtr, CfgPtr->DeviceId);
/* Initialize all included sub_cores */
if(HdmiRxSsPtr->HdmiRxPtr)
{
if(XV_HdmiRxSs_SubcoreInitHdmiRx(HdmiRxSsPtr) != XST_SUCCESS)
{
return(XST_FAILURE);
}
}
/* Register Callbacks */
XV_HdmiRxSs_RegisterSubsysCallbacks(HdmiRxSsPtr);
/* Reset the hardware and set the flag to indicate the
subsystem is ready
*/
XV_HdmiRxSs_Reset(HdmiRxSsPtr);
HdmiRxSsPtr->IsReady = XIL_COMPONENT_IS_READY;
/* Initialize the application version with 0 <default value>="">.
Application need to set the this variable properly to let driver know
what version of application is being used.
*/
HdmiRxSsPtr->AppMajVer = 0;
HdmiRxSsPtr->AppMinVer = 0;
return(XST_SUCCESS);
}
/****************************************************************************/
/**
This function starts the HDMI RX subsystem including all sub-cores that are
included in the processing pipeline for a given use-case. Video pipe is
started from back to front
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
- Note
- Cores are started only if the corresponding start flag in the scratch
pad memory is set. This allows to selectively start only those cores
included in the processing chain
******************************************************************************/
void XV_HdmiRxSs_Start(XV_HdmiRxSs *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
XV_HdmiRxSs_LogWrite(InstancePtr, XV_HDMIRXSS_LOG_EVT_START, 0);
/* Drive HDMI RX HPD High */
XV_HdmiRx_SetHpd(InstancePtr->HdmiRxPtr, TRUE);
/* Disable Audio Peripheral */
XV_HdmiRx_AudioDisable(InstancePtr->HdmiRxPtr);
XV_HdmiRx_AudioIntrDisable(InstancePtr->HdmiRxPtr);
}
/*****************************************************************************/
/**
This function stops the HDMI RX subsystem including all sub-cores
Stop the video pipe starting from front to back
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
void XV_HdmiRxSs_Stop(XV_HdmiRxSs *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
/* Clear SCDC variables */
XV_HdmiRx_DdcScdcClear(InstancePtr->HdmiRxPtr);
/* Disable the scrambler */
XV_HdmiRx_SetScrambler(InstancePtr->HdmiRxPtr, (FALSE));
/* Drive HDMI RX HPD Low */
XV_HdmiRx_SetHpd(InstancePtr->HdmiRxPtr, (FALSE));
XV_HdmiRxSs_LogWrite(InstancePtr, XV_HDMIRXSS_LOG_EVT_STOP, 0);
}
/*****************************************************************************/
/**
This function resets the video subsystem sub-cores. There are 2 reset
networks within the subsystem
- For cores that are on AXIS interface
- For cores that are on AXI-MM interface
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
void XV_HdmiRxSs_Reset(XV_HdmiRxSs *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
XV_HdmiRxSs_LogWrite(InstancePtr, XV_HDMIRXSS_LOG_EVT_RESET, 0);
/* Assert HDMI RX core resets */
XV_HdmiRxSs_RXCore_VRST(InstancePtr, TRUE);
XV_HdmiRxSs_RXCore_LRST(InstancePtr, TRUE);
/* Assert SYSCLK VID_IN bridge reset */
XV_HdmiRxSs_SYSRST(InstancePtr, TRUE);
/* Release HDMI RX core resets */
XV_HdmiRxSs_RXCore_VRST(InstancePtr, FALSE);
XV_HdmiRxSs_RXCore_LRST(InstancePtr, FALSE);
/* Release SYSCLK VID_IN bridge reset */
XV_HdmiRxSs_SYSRST(InstancePtr, FALSE);
}
/*****************************************************************************/
/**
This function asserts or releases the Internal Video reset
of the HDMI subcore within the subsystem
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
void XV_HdmiRxSs_RXCore_VRST(XV_HdmiRxSs *InstancePtr, u8 Reset)
{
Xil_AssertVoid(InstancePtr != NULL);
XV_HdmiRx_INT_VRST(InstancePtr->HdmiRxPtr, Reset);
}
/*****************************************************************************/
/**
This function asserts or releases the Internal Link reset
of the HDMI subcore within the subsystem
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
void XV_HdmiRxSs_RXCore_LRST(XV_HdmiRxSs *InstancePtr, u8 Reset)
{
Xil_AssertVoid(InstancePtr != NULL);
XV_HdmiRx_INT_LRST(InstancePtr->HdmiRxPtr, Reset);
}
/*****************************************************************************/
/**
This function asserts or releases the video reset of other
blocks within the subsystem
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
void XV_HdmiRxSs_VRST(XV_HdmiRxSs *InstancePtr, u8 Reset)
{
Xil_AssertVoid(InstancePtr != NULL);
XV_HdmiRx_EXT_VRST(InstancePtr->HdmiRxPtr, Reset);
}
/*****************************************************************************/
/**
This function asserts or releases the system reset of other
blocks within the subsystem
- Parameters
-
InstancePtr | is a pointer to the Subsystem instance to be worked on. |
- Returns
- None
******************************************************************************/
void XV_HdmiRxSs_SYSRST(XV_HdmiRxSs *InstancePtr, u8 Reset)
{
Xil_AssertVoid(InstancePtr != NULL);
XV_HdmiRx_EXT_SYSRST(InstancePtr->HdmiRxPtr, Reset);
}
/*****************************************************************************/
/**
This function is called when a Bridge overflow event has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_BrdgOverflowCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
// Check if user callback has been registered
if (HdmiRxSsPtr->BrdgOverflowCallback) {
HdmiRxSsPtr->BrdgOverflowCallback(HdmiRxSsPtr->BrdgOverflowRef);
}
}
/*****************************************************************************/
/**
This function is called when a RX connect event has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_ConnectCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
// Is the cable connected?
if (XV_HdmiRx_IsStreamConnected(HdmiRxSsPtr->HdmiRxPtr)) {
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_CONNECT, 0);
// Set RX hot plug detect
XV_HdmiRx_SetHpd(HdmiRxSsPtr->HdmiRxPtr, TRUE);
// Set stream connected flag
HdmiRxSsPtr->IsStreamConnected = (TRUE);
}
// RX cable is disconnected
else {
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_DISCONNECT, 0);
// Clear RX hot plug detect
XV_HdmiRx_SetHpd(HdmiRxSsPtr->HdmiRxPtr, FALSE);
// Set stream connected flag
HdmiRxSsPtr->IsStreamConnected = (FALSE);
XV_HdmiRx_SetScrambler(HdmiRxSsPtr->HdmiRxPtr, (FALSE)); //Disable scrambler
}
// Check if user callback has been registered
if (HdmiRxSsPtr->ConnectCallback) {
HdmiRxSsPtr->ConnectCallback(HdmiRxSsPtr->ConnectRef);
}
}
/*****************************************************************************/
/**
This function is called when a RX AUX IRQ has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_AuxCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
XHdmiC_Aux *AuxPtr;
XHdmiC_AVI_InfoFrame *AviInfoFramePtr;
XHdmiC_GeneralControlPacket *GeneralControlPacketPtr;
XHdmiC_AudioInfoFrame *AudioInfoFramePtr;
AviInfoFramePtr = XV_HdmiRxSs_GetAviInfoframe(HdmiRxSsPtr);
GeneralControlPacketPtr = XV_HdmiRxSs_GetGCP(HdmiRxSsPtr);
AudioInfoFramePtr = XV_HdmiRxSs_GetAudioInfoframe(HdmiRxSsPtr);
AuxPtr = XV_HdmiRxSs_GetAuxiliary(HdmiRxSsPtr);
if(AuxPtr->Header.Byte[0] == AUX_VSIF_TYPE){
// Retrieve Vendor Specific Info Frame
XV_HdmiRxSs_RetrieveVSInfoframe(HdmiRxSsPtr);
} else if(AuxPtr->Header.Byte[0] == AUX_AVI_INFOFRAME_TYPE){
// Reset Avi InfoFrame
(void)memset((void *)AviInfoFramePtr, 0, sizeof(XHdmiC_AVI_InfoFrame));
// Parse Aux to retrieve Avi InfoFrame
XV_HdmiC_ParseAVIInfoFrame(AuxPtr, AviInfoFramePtr);
HdmiRxSsPtr->HdmiRxPtr->Stream.Video.ColorFormatId =
XV_HdmiRx_GetAviColorSpace(HdmiRxSsPtr->HdmiRxPtr);
HdmiRxSsPtr->HdmiRxPtr->Stream.Vic =
XV_HdmiRx_GetAviVic(HdmiRxSsPtr->HdmiRxPtr);
HdmiRxSsPtr->HdmiRxPtr->Stream.Video.AspectRatio =
XV_HdmiC_IFAspectRatio_To_XVidC(HdmiRxSsPtr->AVIInfoframe.PicAspectRatio);
} else if(AuxPtr->Header.Byte[0] == AUX_GENERAL_CONTROL_PACKET_TYPE) {
// Reset General Control Packet
(void)memset((void *)GeneralControlPacketPtr, 0, sizeof(XHdmiC_GeneralControlPacket));
// Parse Aux to retrieve General Control Packet
XV_HdmiC_ParseGCP(AuxPtr, GeneralControlPacketPtr);
// Stream.Video.ColorDepth is updated from the core during AUX INTR
} else if(AuxPtr->Header.Byte[0] == AUX_AUDIO_INFOFRAME_TYPE) {
// Reset Audio InfoFrame
(void)memset((void *)AudioInfoFramePtr, 0, sizeof(XHdmiC_AudioInfoFrame));
// Parse Aux to retrieve Audio InfoFrame
XV_HdmiC_ParseAudioInfoFrame(AuxPtr, AudioInfoFramePtr);
}
// Check if user callback has been registered
if (HdmiRxSsPtr->AuxCallback) {
HdmiRxSsPtr->AuxCallback(HdmiRxSsPtr->AuxRef);
}
}
/*****************************************************************************/
/**
This function is called when a RX Sync Loss IRQ has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_SyncLossCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
if (HdmiRxSsPtr->HdmiRxPtr->Stream.SyncStatus ==
XV_HDMIRX_SYNCSTAT_SYNC_LOSS) {
// Push sync loss event to HDCP event queue
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_SYNCLOSS, 0);
}
// Sync is recovered/establish
else if (HdmiRxSsPtr->HdmiRxPtr->Stream.SyncStatus ==
XV_HDMIRX_SYNCSTAT_SYNC_EST) {
// Push sync loss event to HDCP event queue
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_SYNCEST, 0);
}
}
/*****************************************************************************/
/**
This function is called when the mode has transitioned from DVI to HDMI or
vice versa.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_ModeCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
// HDMI mode
if (XV_HdmiRxSs_GetVideoStreamType(HdmiRxSsPtr )) {
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_HDMIMODE, 0);
}
// DVI mode
else {
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_DVIMODE, 0);
}
}
/*****************************************************************************/
/**
This function retrieves the Vendor Specific Info Frame.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_RetrieveVSInfoframe(XV_HdmiRxSs *HdmiRxSs)
{
/** Vendor-Specific InfoFrame structure */
XHdmiC_VSIF *VSIFPtr;
VSIFPtr = XV_HdmiRxSs_GetVSIF(HdmiRxSs);
if (HdmiRxSs->HdmiRxPtr->Aux.Header.Byte[0] == AUX_VSIF_TYPE) {
// Reset Vendor Specific InfoFrame
(void)memset((void *)VSIFPtr, 0, sizeof(XHdmiC_VSIF));
XV_HdmiC_VSIF_ParsePacket(&HdmiRxSs->HdmiRxPtr->Aux, VSIFPtr);
// Defaults
HdmiRxSs->HdmiRxPtr->Stream.Video.Is3D = FALSE;
HdmiRxSs->HdmiRxPtr->Stream.Video.Info_3D.Format = XVIDC_3D_UNKNOWN;
if (VSIFPtr->Format == XHDMIC_VSIF_VF_3D) {
HdmiRxSs->HdmiRxPtr->Stream.Video.Is3D = TRUE;
HdmiRxSs->HdmiRxPtr->Stream.Video.Info_3D = VSIFPtr->Info_3D.Stream;
} else if (VSIFPtr->Format == XHDMIC_VSIF_VF_EXTRES) {
switch(VSIFPtr->HDMI_VIC) {
case 1 :
HdmiRxSs->HdmiRxPtr->Stream.Vic = 95;
break;
case 2 :
HdmiRxSs->HdmiRxPtr->Stream.Vic = 94;
break;
case 3 :
HdmiRxSs->HdmiRxPtr->Stream.Vic = 93;
break;
case 4 :
HdmiRxSs->HdmiRxPtr->Stream.Vic = 98;
break;
default :
break;
}
}
}
}
/*****************************************************************************/
/**
This function is called when a RX Audio IRQ has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_AudCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
u8 Channels;
if (XV_HdmiRx_IsAudioActive(HdmiRxSsPtr->HdmiRxPtr)) {
// Get audio channels
Channels = XV_HdmiRx_GetAudioChannels(HdmiRxSsPtr->HdmiRxPtr);
HdmiRxSsPtr->AudioChannels = Channels;
}
// Check if user callback has been registered
if (HdmiRxSsPtr->AudCallback) {
HdmiRxSsPtr->AudCallback(HdmiRxSsPtr->AudRef);
}
}
/*****************************************************************************/
/**
This function is called when a RX Link Status IRQ has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_LnkStaCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
HdmiRxSsPtr->IsLinkStatusErrMax =
XV_HdmiRx_IsLinkStatusErrMax(HdmiRxSsPtr->HdmiRxPtr);
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_LINKSTATUS, 0);
// Check if user callback has been registered
if (HdmiRxSsPtr->LnkStaCallback) {
HdmiRxSsPtr->LnkStaCallback(HdmiRxSsPtr->LnkStaRef);
}
}
/*****************************************************************************/
/**
This function is called when a RX DDC IRQ has occurred.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_DdcCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
// Check if user callback has been registered
if (HdmiRxSsPtr->DdcCallback) {
HdmiRxSsPtr->DdcCallback(HdmiRxSsPtr->DdcRef);
}
}
/*****************************************************************************/
/**
This function is called when the RX stream is down.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_StreamDownCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
/* Assert HDMI RX core resets */
XV_HdmiRxSs_RXCore_VRST(HdmiRxSsPtr, TRUE);
XV_HdmiRxSs_RXCore_LRST(HdmiRxSsPtr, TRUE);
/* Assert SYSCLK VID_IN bridge reset */
XV_HdmiRxSs_SYSRST(HdmiRxSsPtr, TRUE);
/* Set stream up flag */
HdmiRxSsPtr->IsStreamUp = (FALSE);
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_STREAMDOWN, 0);
// Check if user callback has been registered
if (HdmiRxSsPtr->StreamDownCallback) {
HdmiRxSsPtr->StreamDownCallback(HdmiRxSsPtr->StreamDownRef);
}
}
/*****************************************************************************/
/**
This function is called when the RX stream init .
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_StreamInitCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_STREAMINIT, 0);
// Check if user callback has been registered
if (HdmiRxSsPtr->StreamInitCallback) {
HdmiRxSsPtr->StreamInitCallback(HdmiRxSsPtr->StreamInitRef);
}
}
/*****************************************************************************/
/**
This function is called when the RX stream is up.
- Parameters
-
- Returns
- None.
- Note
- None.
******************************************************************************/
static void XV_HdmiRxSs_StreamUpCallback(void *CallbackRef)
{
XV_HdmiRxSs *HdmiRxSsPtr = (
XV_HdmiRxSs *)CallbackRef;
/* Clear link Status error counters */
XV_HdmiRx_ClearLinkStatus(HdmiRxSsPtr->HdmiRxPtr);
/* Set stream up flag */
HdmiRxSsPtr->IsStreamUp = (TRUE);
XV_HdmiRxSs_LogWrite(HdmiRxSsPtr, XV_HDMIRXSS_LOG_EVT_STREAMUP, 0);
/* Configure Remapper according to HW setting and video format */
XV_HdmiRxSs_ConfigBridgeMode(HdmiRxSsPtr);
// Check if user callback has been registered
if (HdmiRxSsPtr->StreamUpCallback) {
HdmiRxSsPtr->StreamUpCallback(HdmiRxSsPtr->StreamUpRef);
}
}
/*****************************************************************************/
/**
This function installs an asynchronous callback function for the given
HandlerType:
HandlerType Callback Function Type
----------------------- --------------------------------------------------
(XV_HDMIRXSS_HANDLER_CONNECT) HpdCallback
(XV_HDMIRXSS_HANDLER_VS) VsCallback
(XV_HDMIRXSS_HANDLER_STREAM_DOWN) StreamDownCallback
(XV_HDMIRXSS_HANDLER_STREAM_UP) StreamUpCallback
(XV_HDMIRXSS_HANDLER_HDCP_AUTHENTICATED)
(XV_HDMIRXSS_HANDLER_HDCP_UNAUTHENTICATED)
(XV_HDMIRXSS_HANDLER_HDCP_AUTHENTICATION_REQUEST)
(XV_HDMIRXSS_HANDLER_HDCP_STREAM_MANAGE_REQUEST)
(XV_HDMIRXSS_HANDLER_HDCP_TOPOLOGY_UPDATE)
- Parameters
-
InstancePtr | is a pointer to the HDMI RX Subsystem instance.
|
HandlerType | specifies the type of handler.
|
CallbackFunc | is the address of the callback function.
|
CallbackRef | is a user data item that will be passed to the
callback function when it is invoked. |
- Returns
- XST_SUCCESS if callback function installed successfully.
- XST_INVALID_PARAM when HandlerType is invalid.
- Note
- Invoking this function for a handler that already has been
installed replaces it with the new handler.