v_hdmirx: Improved stability.

Contributions from Marco Groeneveld (mgroenev@xilinx.com).

Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
Acked-by: Srikanth Vemula <svemula@xilinx.com>
This commit is contained in:
Gilbert Magnaye 2015-11-12 23:13:50 -08:00 committed by Nava kishore Manne
parent 13ae615fea
commit 9f2f544754
8 changed files with 306 additions and 119 deletions

0
XilinxProcessorIPLib/drivers/v_hdmirx/src/Makefile Executable file → Normal file
View file

315
XilinxProcessorIPLib/drivers/v_hdmirx/src/xv_hdmirx.c Executable file → Normal file
View file

@ -42,8 +42,7 @@
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------------
* 1.00 10/07/15 Initial release.
* 1.0 gm, mg 11/03/15 Initial release.
* </pre>
*
******************************************************************************/
@ -266,11 +265,7 @@ int XV_HdmiRx_CfgInitialize(XV_HdmiRx *InstancePtr, XV_HdmiRx_Config *CfgPtr, u3
Video Timing detector peripheral
*/
/* Set run flag */
XV_HdmiRx_VtdEnable(InstancePtr);
/* Enable interrupt */
XV_HdmiRx_VtdIntrEnable(InstancePtr);
// The VTD run flag is set in the armed state
/*
DDC peripheral
@ -403,7 +398,8 @@ int XV_HdmiRx_SetStream(XV_HdmiRx *InstancePtr, XVidC_PixelsPerClock Ppc, u32 Cl
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid((Ppc == (XVIDC_PPC_2)) || (Ppc == (XVIDC_PPC_4)));
Xil_AssertNonvoid((Ppc == (XVIDC_PPC_1)) || (Ppc == (XVIDC_PPC_2))
|| (Ppc == (XVIDC_PPC_4)));
Xil_AssertNonvoid(Clock > 0x0);
/* Pixels per clock */
@ -1097,10 +1093,28 @@ void XV_HdmiRx_GetVideoProperties(XV_HdmiRx *InstancePtr)
* @note None.
*
******************************************************************************/
void XV_HdmiRx_GetVideoTiming(XV_HdmiRx *InstancePtr)
int XV_HdmiRx_GetVideoTiming(XV_HdmiRx *InstancePtr)
{
u32 Data;
// Local timing parameters
u16 HActive;
u16 HFrontPorch;
u16 HSyncWidth;
u16 HBackPorch;
u16 HTotal;
u16 HSyncPolarity;
u16 VActive;
u16 F0PVFrontPorch;
u16 F0PVSyncWidth;
u16 F0PVBackPorch;
u16 F0PVTotal;
u16 F1VFrontPorch;
u16 F1VSyncWidth;
u16 F1VBackPorch;
u16 F1VTotal;
u8 Match;
// Lookup the videomode based on the vic
InstancePtr->Stream.Video.VmId = XV_HdmiRx_LookupVmId(InstancePtr->Stream.Vic);
//InstancePtr->Stream.Video.VmId = XVIDC_VM_NOT_SUPPORTED;
@ -1117,124 +1131,241 @@ void XV_HdmiRx_GetVideoTiming(XV_HdmiRx *InstancePtr)
// Interlaced
InstancePtr->Stream.Video.IsInterlaced = XVidC_IsInterlaced(InstancePtr->Stream.Video.VmId);
//xil_printf("vic %0d - vmid %0d\n\r",InstancePtr->Stream.Vic, InstancePtr->Stream.Video.VmId);
return (XST_SUCCESS);
}
// No, then read the timing parameters from the video timing detector
else {
/* Read Total Pixels */
InstancePtr->Stream.Video.Timing.HTotal = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_TOT_PIX_OFFSET));
// For YUV420 the total pixels must be doubled
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420)
InstancePtr->Stream.Video.Timing.HTotal = InstancePtr->Stream.Video.Timing.HTotal * 2;
// First we read the video parameters from the VTD and store them in a local variable
/* Read Total Pixels */
HTotal = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_TOT_PIX_OFFSET));
/* Read Active Pixels */
InstancePtr->Stream.Video.Timing.HActive = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_ACT_PIX_OFFSET));
// For YUV420 the active pixels must be doubled
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420)
InstancePtr->Stream.Video.Timing.HActive = InstancePtr->Stream.Video.Timing.HActive * 2;
HActive = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_ACT_PIX_OFFSET));
/* Read Hsync Width */
InstancePtr->Stream.Video.Timing.HSyncWidth = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_HSW_OFFSET));
// For YUV420 the Hsync width must be doubled
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420)
InstancePtr->Stream.Video.Timing.HSyncWidth = InstancePtr->Stream.Video.Timing.HSyncWidth * 2;
HSyncWidth = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_HSW_OFFSET));
/* Read HFront Porch */
InstancePtr->Stream.Video.Timing.HFrontPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_HFP_OFFSET));
// For YUV420 the Hfront porch must be doubled
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420)
InstancePtr->Stream.Video.Timing.HFrontPorch = InstancePtr->Stream.Video.Timing.HFrontPorch * 2;
HFrontPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_HFP_OFFSET));
/* Read HBack Porch */
InstancePtr->Stream.Video.Timing.HBackPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_HBP_OFFSET));
// For YUV420 the Hfront porch must be doubled
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420)
InstancePtr->Stream.Video.Timing.HBackPorch = InstancePtr->Stream.Video.Timing.HBackPorch * 2;
HBackPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_HBP_OFFSET));
/* Total lines field 1 */
InstancePtr->Stream.Video.Timing.F0PVTotal = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_TOT_LIN_OFFSET)) & (0xFFFF);
F0PVTotal = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_TOT_LIN_OFFSET)) & (0xFFFF);
/* Total lines field 2 */
InstancePtr->Stream.Video.Timing.F1VTotal = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_TOT_LIN_OFFSET))) >> 16);
F1VTotal = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_TOT_LIN_OFFSET))) >> 16);
/* Active lines field 1 */
InstancePtr->Stream.Video.Timing.VActive = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_ACT_LIN_OFFSET)) & (0xFFFF);
VActive = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_ACT_LIN_OFFSET)) & (0xFFFF);
/* Read VSync Width field 1*/
InstancePtr->Stream.Video.Timing.F0PVSyncWidth = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VSW_OFFSET)) & (0xFFFF);
F0PVSyncWidth = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VSW_OFFSET)) & (0xFFFF);
/* Read VSync Width field 2*/
InstancePtr->Stream.Video.Timing.F1VSyncWidth = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VSW_OFFSET))) >> 16);
F1VSyncWidth = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VSW_OFFSET))) >> 16);
/* Read VFront Porch field 1*/
InstancePtr->Stream.Video.Timing.F0PVFrontPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VFP_OFFSET)) & (0xFFFF);
F0PVFrontPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VFP_OFFSET)) & (0xFFFF);
/* Read VFront Porch field 2*/
InstancePtr->Stream.Video.Timing.F1VFrontPorch = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VFP_OFFSET))) >> 16);
Data = (Data >> 16) & (0xFFFF);
F1VFrontPorch = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VFP_OFFSET))) >> 16);
/* Read VBack Porch field 1 */
InstancePtr->Stream.Video.Timing.F0PVBackPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VBP_OFFSET)) & (0xFFFF);
F0PVBackPorch = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VBP_OFFSET)) & (0xFFFF);
/* Read VBack Porch field 2 */
InstancePtr->Stream.Video.Timing.F1VBackPorch = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VBP_OFFSET))) >> 16);
F1VBackPorch = ((XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_VBP_OFFSET))) >> 16);
/* Read Status register */
Data = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_STA_OFFSET));
// Next, we compare these values with the previous stored values
// By default the match is true
Match = TRUE;
/* Check video format */
if ((Data) & (XV_HDMIRX_VTD_STA_FMT_MASK)) {
/* Interlaced */
InstancePtr->Stream.Video.IsInterlaced = 1;
// Htotal
if (HTotal != InstancePtr->Stream.Video.Timing.HTotal) {
Match = FALSE;
}
// HActive
if (HActive != InstancePtr->Stream.Video.Timing.HActive) {
Match = FALSE;
}
// HSyncWidth
if (HSyncWidth != InstancePtr->Stream.Video.Timing.HSyncWidth) {
Match = FALSE;
}
// HFrontPorch
if (HFrontPorch != InstancePtr->Stream.Video.Timing.HFrontPorch) {
Match = FALSE;
}
// HBackPorch
if (HBackPorch != InstancePtr->Stream.Video.Timing.HBackPorch) {
Match = FALSE;
}
// F0PVTotal
if (F0PVTotal != InstancePtr->Stream.Video.Timing.F0PVTotal) {
Match = FALSE;
}
// F1VTotal
if (F1VTotal != InstancePtr->Stream.Video.Timing.F1VTotal) {
Match = FALSE;
}
// VActive
if (VActive != InstancePtr->Stream.Video.Timing.VActive) {
Match = FALSE;
}
// F0PVSyncWidth
if (F0PVSyncWidth != InstancePtr->Stream.Video.Timing.F0PVSyncWidth) {
Match = FALSE;
}
// F1VSyncWidth
if (F1VSyncWidth != InstancePtr->Stream.Video.Timing.F1VSyncWidth) {
Match = FALSE;
}
// F0PVFrontPorch
if (F0PVFrontPorch != InstancePtr->Stream.Video.Timing.F0PVFrontPorch) {
Match = FALSE;
}
// F1VFrontPorch
if (F1VFrontPorch != InstancePtr->Stream.Video.Timing.F1VFrontPorch) {
Match = FALSE;
}
// F0PVBackPorch
if (F0PVBackPorch != InstancePtr->Stream.Video.Timing.F0PVBackPorch) {
Match = FALSE;
}
// F1VBackPorch
if (F1VBackPorch != InstancePtr->Stream.Video.Timing.F1VBackPorch) {
Match = FALSE;
}
// Then we store the timing parameters regardless if there was a match
/* Read Total Pixels */
InstancePtr->Stream.Video.Timing.HTotal = HTotal;
/* Read Active Pixels */
InstancePtr->Stream.Video.Timing.HActive = HActive;
/* Read Hsync Width */
InstancePtr->Stream.Video.Timing.HSyncWidth = HSyncWidth;
/* Read HFront Porch */
InstancePtr->Stream.Video.Timing.HFrontPorch = HFrontPorch;
/* Read HBack Porch */
InstancePtr->Stream.Video.Timing.HBackPorch = HBackPorch;
/* Total lines field 1 */
InstancePtr->Stream.Video.Timing.F0PVTotal = F0PVTotal;
/* Total lines field 2 */
InstancePtr->Stream.Video.Timing.F1VTotal = F1VTotal;
/* Active lines field 1 */
InstancePtr->Stream.Video.Timing.VActive = VActive;
/* Read VSync Width field 1*/
InstancePtr->Stream.Video.Timing.F0PVSyncWidth = F0PVSyncWidth;
/* Read VSync Width field 2*/
InstancePtr->Stream.Video.Timing.F1VSyncWidth = F1VSyncWidth;
/* Read VFront Porch field 1*/
InstancePtr->Stream.Video.Timing.F0PVFrontPorch = F0PVFrontPorch;
/* Read VFront Porch field 2*/
InstancePtr->Stream.Video.Timing.F1VFrontPorch = F1VFrontPorch;
/* Read VBack Porch field 1 */
InstancePtr->Stream.Video.Timing.F0PVBackPorch = F0PVBackPorch;
/* Read VBack Porch field 2 */
InstancePtr->Stream.Video.Timing.F1VBackPorch = F1VBackPorch;
// Do we have a match?
// Yes, then continue processing
if (Match) {
/* Read Status register */
Data = XV_HdmiRx_ReadReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_STA_OFFSET));
/* Check video format */
if ((Data) & (XV_HDMIRX_VTD_STA_FMT_MASK)) {
/* Interlaced */
InstancePtr->Stream.Video.IsInterlaced = 1;
}
else {
/* Progressive */
InstancePtr->Stream.Video.IsInterlaced = 0;
}
/* Check Vsync polarity */
if ((Data) & (XV_HDMIRX_VTD_STA_VS_POL_MASK)) {
/* Positive */
InstancePtr->Stream.Video.Timing.VSyncPolarity = 1;
}
else {
/* Negative */
InstancePtr->Stream.Video.Timing.VSyncPolarity = 0;
}
/* Check Hsync polarity */
if ((Data) & (XV_HDMIRX_VTD_STA_HS_POL_MASK)) {
/* Positive */
InstancePtr->Stream.Video.Timing.HSyncPolarity = 1;
}
else {
/* Negative */
InstancePtr->Stream.Video.Timing.HSyncPolarity = 0;
}
// Calculate and set the frame rate field
InstancePtr->Stream.Video.FrameRate = XV_HdmiRx_Divide(InstancePtr->Stream.PixelClk, (InstancePtr->Stream.Video.Timing.F0PVTotal * InstancePtr->Stream.Video.Timing.HTotal));
// If the colorspace is YUV420, then the horizontal parameters must be doubled (and the frame rate)
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420) {
InstancePtr->Stream.Video.FrameRate = InstancePtr->Stream.Video.FrameRate * 2;
InstancePtr->Stream.Video.Timing.HTotal = InstancePtr->Stream.Video.Timing.HTotal * 2;
InstancePtr->Stream.Video.Timing.HActive = InstancePtr->Stream.Video.Timing.HActive * 2;
InstancePtr->Stream.Video.Timing.HSyncWidth = InstancePtr->Stream.Video.Timing.HSyncWidth * 2;
InstancePtr->Stream.Video.Timing.HFrontPorch = InstancePtr->Stream.Video.Timing.HFrontPorch * 2;
InstancePtr->Stream.Video.Timing.HBackPorch = InstancePtr->Stream.Video.Timing.HBackPorch * 2;
}
// Lookup the video mode id
InstancePtr->Stream.Video.VmId = XVidC_GetVideoModeId(InstancePtr->Stream.Video.Timing.HActive,
InstancePtr->Stream.Video.Timing.VActive,
InstancePtr->Stream.Video.FrameRate,
InstancePtr->Stream.Video.IsInterlaced);
//If video mode not found in the table tag it as custom
if (InstancePtr->Stream.Video.VmId == XVIDC_VM_NOT_SUPPORTED) {
InstancePtr->Stream.Video.VmId = XVIDC_VM_CUSTOM;
}
// Return success
return (XST_SUCCESS);
}
// No match
else {
/* Progressive */
InstancePtr->Stream.Video.IsInterlaced = 0;
}
/* Check Vsync polarity */
if ((Data) & (XV_HDMIRX_VTD_STA_VS_POL_MASK)) {
/* Positive */
InstancePtr->Stream.Video.Timing.VSyncPolarity = 1;
}
else {
/* Negative */
InstancePtr->Stream.Video.Timing.VSyncPolarity = 0;
}
/* Check Hsync polarity */
if ((Data) & (XV_HDMIRX_VTD_STA_HS_POL_MASK)) {
/* Positive */
InstancePtr->Stream.Video.Timing.HSyncPolarity = 1;
}
else {
/* Negative */
InstancePtr->Stream.Video.Timing.HSyncPolarity = 0;
}
// Calculate and set the frame rate field
InstancePtr->Stream.Video.FrameRate = XV_HdmiRx_Divide(InstancePtr->Stream.PixelClk, (InstancePtr->Stream.Video.Timing.F0PVTotal * InstancePtr->Stream.Video.Timing.HTotal));
// If the colorspace is YUV420, then double the frame rate
if (InstancePtr->Stream.Video.ColorFormatId == XVIDC_CSF_YCRCB_420) {
xil_printf("Ik kom hier %d\n\r", InstancePtr->Stream.Video.FrameRate);
InstancePtr->Stream.Video.FrameRate = InstancePtr->Stream.Video.FrameRate * 2;
}
// Lookup the video mode id
InstancePtr->Stream.Video.VmId = XVidC_GetVideoModeId(InstancePtr->Stream.Video.Timing.HActive,
InstancePtr->Stream.Video.Timing.VActive,
InstancePtr->Stream.Video.FrameRate,
InstancePtr->Stream.Video.IsInterlaced);
//If video mode not found in the table tag it as custom
if (InstancePtr->Stream.Video.VmId == XVIDC_VM_NOT_SUPPORTED) {
InstancePtr->Stream.Video.VmId = XVIDC_VM_CUSTOM;
return (XST_FAILURE);
}
}
}

26
XilinxProcessorIPLib/drivers/v_hdmirx/src/xv_hdmirx.h Executable file → Normal file
View file

@ -116,7 +116,7 @@
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------------
* 1.00 10/07/15 Initial release.
* 1.0 gm, mg 10/07/15 Initial release.
* </pre>
*
@ -166,8 +166,10 @@ typedef enum {
XV_HDMIRX_STATE_STREAM_DOWN, /**< Stream down */
XV_HDMIRX_STATE_STREAM_IDLE, /**< Stream idle */
XV_HDMIRX_STATE_STREAM_INIT, /**< Stream init */
XV_HDMIRX_STATE_STREAM_RDY, /**< Stream ready */
XV_HDMIRX_STATE_STREAM_UP /**< Stream up */
XV_HDMIRX_STATE_STREAM_ARM, /**< Stream arm */
XV_HDMIRX_STATE_STREAM_LOCK, /**< Stream lock */
XV_HDMIRX_STATE_STREAM_RDY, /**< Stream ready */
XV_HDMIRX_STATE_STREAM_UP /**< Stream up */
} XV_HdmiRx_State;
/**************************** Type Definitions *******************************/
@ -645,6 +647,22 @@ typedef struct {
#define XV_HdmiRx_VtdIntrDisable(InstancePtr) \
XV_HdmiRx_WriteReg((InstancePtr)->Config.BaseAddress, (XV_HDMIRX_VTD_CTRL_CLR_OFFSET), (XV_HDMIRX_VTD_CTRL_IE_MASK))
/*****************************************************************************/
/**
*
* This macro sets the threshold in the HDMI RX Timing Detector peripheral.
*
* @param InstancePtr is a pointer to the XV_HdmiRx core instance.
*
* @return None.
*
* @note C-style signature:
* void XV_HdmiRx_VtdIntrDisable(XV_HdmiRx *InstancePtr)
*
******************************************************************************/
#define XV_HdmiRx_VtdSetThreshold(InstancePtr, Value) \
XV_HdmiRx_WriteReg((InstancePtr)->Config.BaseAddress, (XV_HDMIRX_VTD_CTRL_OFFSET), (u32)(Value << XV_HDMIRX_VTD_CTRL_THRESHOLD_SHIFT))
/*****************************************************************************/
/**
@ -1065,7 +1083,7 @@ int XV_HdmiRx_GetTmdsClockRatio(XV_HdmiRx *InstancePtr);
u8 XV_HdmiRx_GetAviVic(XV_HdmiRx *InstancePtr);
XVidC_ColorFormat XV_HdmiRx_GetAviColorSpace(XV_HdmiRx *InstancePtr);
XVidC_ColorDepth XV_HdmiRx_GetGcpColorDepth(XV_HdmiRx *InstancePtr);
void XV_HdmiRx_GetVideoTiming(XV_HdmiRx *InstancePtr);
int XV_HdmiRx_GetVideoTiming(XV_HdmiRx *InstancePtr);
u32 XV_HdmiRx_Divide(u32 Dividend, u32 Divisor);
/* Log specific functions */

View file

View file

@ -45,8 +45,7 @@
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------------
* 1.00 10/07/15 Initial release.
* 1.0 gm, mg 11/03/15 Initial release.
* </pre>
*
******************************************************************************/
@ -158,6 +157,8 @@ extern "C" {
#define XV_HDMIRX_VTD_CTRL_RUN_MASK (1<<0) /**< VTD Control Run mask */
#define XV_HDMIRX_VTD_CTRL_IE_MASK (1<<1) /**< VTD Control Interrupt Enable mask */
#define XV_HDMIRX_VTD_CTRL_FIELD_POL_MASK (1<<2) /**< VTD Control field polarity mask */
#define XV_HDMIRX_VTD_CTRL_THRESHOLD_SHIFT 24 /**< VTD Control threshold shift */
#define XV_HDMIRX_VTD_CTRL_THRESHOLD_MASK 0xff /**< VTD Control threshold mask */
// Video timing detector peripheral Status register masks
#define XV_HDMIRX_VTD_STA_IRQ_MASK (1<<0) /**< VTD Status Interrupt mask */
@ -347,4 +348,4 @@ extern "C" {
}
#endif
#endif /* end of protection macro */
#endif /* end of protection macro */

View file

@ -42,7 +42,7 @@
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------------
* 1.00 10/07/15 Initial release.
* 1.0 gm, mg 11/03/15 Initial release.
* </pre>
*
@ -318,16 +318,37 @@ static void HdmiRx_VtdIntrHandler(XV_HdmiRx *InstancePtr)
// Clear event flag
XV_HdmiRx_WriteReg(InstancePtr->Config.BaseAddress, (XV_HDMIRX_VTD_STA_OFFSET), (XV_HDMIRX_VTD_STA_TPR_EVT_MASK));
// Read video timing
XV_HdmiRx_GetVideoTiming(InstancePtr);
// Check if we are in lock state
if (InstancePtr->Stream.State == XV_HDMIRX_STATE_STREAM_LOCK) {
// Set stream status to up
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_UP; // The stream is up
// Read video timing
Status = XV_HdmiRx_GetVideoTiming(InstancePtr);
// Call stream up callback
if (InstancePtr->IsStreamUpCallbackSet) {
InstancePtr->StreamUpCallback(InstancePtr->StreamUpRef);
if (Status == XST_SUCCESS) {
// Set stream status to up
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_UP; // The stream is up
// Call stream up callback
if (InstancePtr->IsStreamUpCallbackSet) {
InstancePtr->StreamUpCallback(InstancePtr->StreamUpRef);
}
}
}
// Check if we are in stream up state
else if (InstancePtr->Stream.State == XV_HDMIRX_STATE_STREAM_UP) {
// Read video timing
Status = XV_HdmiRx_GetVideoTiming(InstancePtr);
if (Status != XST_SUCCESS) {
// Set stream status to up
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_LOCK;
}
}
}
}
@ -438,7 +459,7 @@ static void HdmiRx_PioIntrHandler(XV_HdmiRx *InstancePtr)
// Video ready event has occurred
if ((Event) & (XV_HDMIRX_PIO_IN_VID_RDY_MASK)) {
// Stream up
// Ready
if ((Data) & (XV_HDMIRX_PIO_IN_VID_RDY_MASK)) {
// Check the previous state
@ -449,13 +470,11 @@ static void HdmiRx_PioIntrHandler(XV_HdmiRx *InstancePtr)
// Enable video
XV_HdmiRx_VideoEnable(InstancePtr, (TRUE));
// Set stream status to ready
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_RDY; // The stream is ready
// Set stream status to arm
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_ARM; // The stream is armed
// Call stream up callback
//if (InstancePtr->IsStreamUpCallbackSet) {
// InstancePtr->StreamUpCallback(InstancePtr->StreamUpRef);
//}
// Load timer
XV_HdmiRx_TmrStart(InstancePtr, 20000000); // 200 ms @ 100 MHz (one UHD frame is 40 ms, 5 frames)
}
}
@ -473,6 +492,9 @@ static void HdmiRx_PioIntrHandler(XV_HdmiRx *InstancePtr)
XV_HdmiRx_AuxDisable(InstancePtr);
XV_HdmiRx_AudioDisable(InstancePtr);
/* Disable VTD */
XV_HdmiRx_VtdDisable(InstancePtr);
// Disable link
XV_HdmiRx_LinkEnable(InstancePtr, (FALSE));
@ -547,14 +569,13 @@ static void HdmiRx_TmrIntrHandler(XV_HdmiRx *InstancePtr)
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_INIT; // The stream init
// Load timer
XV_HdmiRx_TmrStart(InstancePtr, 20000000); // 200 ms @ 100 MHz
XV_HdmiRx_TmrStart(InstancePtr, 20000000); // 200 ms @ 100 MHz (one UHD frame is 40 ms, 5 frames)
}
// Init state
else if (InstancePtr->Stream.State == XV_HDMIRX_STATE_STREAM_INIT) {
// Read video properties
//XV_HdmiRx_GetVideoTiming(InstancePtr);
XV_HdmiRx_GetVideoProperties(InstancePtr);
// Call stream init callback
@ -562,6 +583,22 @@ static void HdmiRx_TmrIntrHandler(XV_HdmiRx *InstancePtr)
InstancePtr->StreamInitCallback(InstancePtr->StreamInitRef);
}
}
// Armed state
else if (InstancePtr->Stream.State == XV_HDMIRX_STATE_STREAM_ARM) {
// Set VTD threshold
XV_HdmiRx_VtdSetThreshold(InstancePtr, 8); // 8 frames
/* Enable VTD */
XV_HdmiRx_VtdEnable(InstancePtr);
/* Enable interrupt */
XV_HdmiRx_VtdIntrEnable(InstancePtr);
// Set stream status to lock
InstancePtr->Stream.State = XV_HDMIRX_STATE_STREAM_LOCK;
}
}
}

View file

@ -41,7 +41,7 @@
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------------
* 1.00 10/07/15 Initial release.
* 1.0 gm, mg 10/07/15 Initial release.
* </pre>
*

View file

@ -41,7 +41,7 @@
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------------
* 1.00 10/07/15 Initial release.
* 1.0 gm, mg 10/07/15 Initial release.
* </pre>
*
@ -107,4 +107,4 @@ XV_HdmiRx_Config *XV_HdmiRx_LookupConfig(u16 DeviceId)
}
return (XV_HdmiRx_Config *)CfgPtr;
}
}