
This patch adds examples for driver DisplayPort Receiver Subsystem Signed-off-by: Shadul Shaikh <shaduls@xilinx.com> Acked-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
787 lines
24 KiB
C
787 lines
24 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* Use of the Software is limited solely to applications:
|
|
* (a) running on a Xilinx device, or
|
|
* (b) that interact with a Xilinx device through a bus or interconnect.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the Xilinx shall not be used
|
|
* in advertising or otherwise to promote the sale, use or other dealings in
|
|
* this Software without prior written authorization from Xilinx.
|
|
*
|
|
******************************************************************************/
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* @file xdprxss_mst_example.c
|
|
*
|
|
* This file contains a design example using the XDpRxSs driver in single stream
|
|
* (SST) transport or multi-stream transport (MST) mode.
|
|
*
|
|
* @note For this example to display output, the user need to implement
|
|
* initialization of the system (DpRxSs_PlatformInit), Video Phy
|
|
* (DpRxSs_VideoPhyInit), start DisplayPort RX subsystem
|
|
* (XDpRxSs_Start) and DisplayPort TX Subsystem setup
|
|
* (DpTxSs_Setup).
|
|
* The input to the Subsystem is from RX (GT).
|
|
* This example requires an interrupt controller in the system.
|
|
* The functions DpRxSs_PlatformInit, DpRxSs_VideoPhyInit and
|
|
* DpTxSs_Setup are declared and are left up to the user to
|
|
* implement.
|
|
*
|
|
* <pre>
|
|
* MODIFICATION HISTORY:
|
|
*
|
|
* Ver Who Date Changes
|
|
* ---- --- -------- --------------------------------------------------
|
|
* 1.00 sha 07/29/15 Initial release.
|
|
* </pre>
|
|
*
|
|
******************************************************************************/
|
|
|
|
/***************************** Include Files *********************************/
|
|
|
|
#include "xdprxss.h"
|
|
#include "xil_printf.h"
|
|
#include "xil_types.h"
|
|
#include "xparameters.h"
|
|
#include "xstatus.h"
|
|
#include "xtmrctr.h"
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
/* For MicroBlaze systems. */
|
|
#include "xintc.h"
|
|
#else
|
|
/* For ARM/Zynq SoC systems. */
|
|
#include "xscugic.h"
|
|
#endif /* XPAR_INTC_0_DEVICE_ID */
|
|
|
|
/************************** Constant Definitions *****************************/
|
|
|
|
/*
|
|
* The following constants map to the names of the hardware instances.
|
|
* They are only defined here such that a user can easily change all the
|
|
* needed device IDs in one place.
|
|
* There is only one interrupt controlled to be selected from SCUGIC and GPIO
|
|
* INTC. INTC selection is based on INTC parameters defined xparameters.h file.
|
|
*/
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
#define XINTC_DPRXSS_DP_INTERRUPT_ID XPAR_INTC_0_DPRXSS_0_DPRXSS_DP_IRQ_VEC_ID
|
|
#define XINTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
|
|
#define XINTC XIntc
|
|
#define XINTC_HANDLER XIntc_InterruptHandler
|
|
#else /* Else part */
|
|
#define XINTC_DPRXSS_DP_INTERRUPT_ID XPAR_INTC_0_DPRXSS_0_DPRXSS_DP_IRQ_VEC_ID
|
|
#define XINTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
|
#define XINTC XScuGic
|
|
#define XINTC_HANDLER XScuGic_InterruptHandler
|
|
#endif /* XPAR_INTC_0_DEVICE_ID */
|
|
|
|
/* The unique device ID of the Timer controller instance to be used */
|
|
#define XTMR_CTRL_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
|
|
|
|
/* The unique device ID of the DisplayPort Receiver Subsystem HIP instance
|
|
* to be used
|
|
*/
|
|
#define XDPRXSS_DEVICE_ID XPAR_DPRXSS_0_DEVICE_ID
|
|
|
|
/* Example will run either in MST or SST mode based upon config parameters.
|
|
* In MST mode, this example exposes maximum number of input and output ports
|
|
* of DP RX that will be included while replying to sideband messages from TX.
|
|
*/
|
|
#define DPRXSS_LINK_RATE XDPRXSS_LINK_BW_SET_540GBPS
|
|
#define DPRXSS_LANE_COUNT XDPRXSS_LANE_COUNT_SET_4
|
|
|
|
/***************** Macros (Inline Functions) Definitions *********************/
|
|
|
|
|
|
/**************************** Type Definitions *******************************/
|
|
|
|
|
|
/************************** Function Prototypes ******************************/
|
|
|
|
u32 DpRxSs_MstExample(u16 DeviceId);
|
|
u32 DpRxSs_PlatformInit(void);
|
|
u32 DpRxSs_VideoPhyInit(void);
|
|
u32 DpTxSs_Setup(void);
|
|
|
|
/* Interrupt helper functions */
|
|
u32 DpRxSs_SetupIntrSystem(void);
|
|
void DpRxSs_VideoModeHandler(void *InstancePtr);
|
|
void DpRxSs_NoVideoHandler(void *InstancePtr);
|
|
void DpRxSs_VerticalBlankHandler(void *InstancePtr);
|
|
void DpRxSs_TrainingLostHandler(void *InstancePtr);
|
|
void DpRxSs_TrainingDoneHandler(void *InstancePtr);
|
|
void DpRxSs_DownReqestHandler(void *InstancePtr);
|
|
void DpRxSs_DownReplyHandler(void *InstancePtr);
|
|
void DpRxSs_UnplugHandler(void *InstancePtr);
|
|
void DpRxSs_LinkBandwidthHandler(void *InstancePtr);
|
|
void DpRxSs_PllResetHandler(void *InstancePtr);
|
|
u32 DpRxSs_SetupTimerHandler(void);
|
|
void DpRxSs_CustomWaitUs(void *InstancePtr, u32 MicroSeconds);
|
|
void DpRxSs_DetectResolution(XDpRxSs *InstancePtr);
|
|
|
|
/************************** Variable Definitions *****************************/
|
|
|
|
XDpRxSs DpRxSsInst; /* The DPRX Subsystem instance.*/
|
|
XINTC IntcInst; /* The interrupt controller instance. */
|
|
XTmrCtr TmrCtrInst; /* The timer counter instance. */
|
|
|
|
/************************** Function Definitions *****************************/
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This is the main function for XDpRxSs SST/MST example.
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if the MST/SST example passed.
|
|
* - XST_FAILURE if the MST/SST example was unsuccessful.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int main()
|
|
{
|
|
u32 Status;
|
|
|
|
xil_printf("------------------------------------------\n\r");
|
|
xil_printf("DisplayPort RX Subsystem SST/MST example\n\r");
|
|
xil_printf("(c) 2015 by Xilinx\n\r");
|
|
xil_printf("-------------------------------------------\n\r\n\r");
|
|
|
|
Status = DpRxSs_MstExample(XDPRXSS_DEVICE_ID);
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("DisplayPort RX Subsystem SST/MST example failed."
|
|
"\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
xil_printf("DisplayPort RX Subsystem SST/MST example passed\n\r");
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the main entry point for the MST/SST example using the
|
|
* XDpRxSs driver.
|
|
*
|
|
* @param DeviceId is the unique device ID of the DisplayPort RX
|
|
* Subsystem core.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if DisplayPort RX Subsystem configured in SST/MST
|
|
* successfully.
|
|
* - XST_FAILURE, if DisplayPort RX Subsystem failed to configure
|
|
* in SST/MST.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 DpRxSs_MstExample(u16 DeviceId)
|
|
{
|
|
u32 Status;
|
|
XDpRxSs_Config *ConfigPtr;
|
|
|
|
/* Do platform initialization in this function. This is hardware
|
|
* system specific. It is up to the user to implement this function.
|
|
*/
|
|
xil_printf("PlatformInit\n\r");
|
|
Status = DpRxSs_PlatformInit();
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("Platform init failed!\n\r");
|
|
}
|
|
xil_printf("Platform initialization done.\n\r");
|
|
|
|
/* Obtain the device configuration for the DisplayPort RX Subsystem */
|
|
ConfigPtr = XDpRxSs_LookupConfig(DeviceId);
|
|
if (!ConfigPtr) {
|
|
return XST_FAILURE;
|
|
}
|
|
/* Copy the device configuration into the DpRxSsInst's Config
|
|
* structure. */
|
|
Status = XDpRxSs_CfgInitialize(&DpRxSsInst, ConfigPtr,
|
|
ConfigPtr->BaseAddress);
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("DPRXSS config initialization failed.\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Check for SST/MST support */
|
|
if (DpRxSsInst.UsrOpt.MstSupport) {
|
|
xil_printf("\n\rINFO:DPRXSS is MST enabled. DPRXSS can be "
|
|
"switched to SST/MST\n\r\n\r");
|
|
}
|
|
else {
|
|
xil_printf("\n\rINFO:DPRXSS is SST enabled. DPRXSS works "
|
|
"only in SST mode.\n\r\n\r");
|
|
}
|
|
|
|
/* Set up a timer. */
|
|
DpRxSs_SetupTimerHandler();
|
|
|
|
Status = DpRxSs_SetupIntrSystem();
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("ERR: Interrupt system setup failed.\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Set Link rate and lane count to maximum */
|
|
XDpRxSs_SetLinkRate(&DpRxSsInst, DPRXSS_LINK_RATE);
|
|
XDpRxSs_SetLaneCount(&DpRxSsInst, DPRXSS_LANE_COUNT);
|
|
|
|
/* Start DPRXSS */
|
|
Status = XDpRxSs_Start(&DpRxSsInst);
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("ERR:DPRX SS start failed\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Setup Video Phy, left to the user for implementation */
|
|
DpRxSs_VideoPhyInit();
|
|
|
|
/* Setup DPTX SS, left to the user for implementation */
|
|
DpTxSs_Setup();
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function initialize required platform specific peripherals.
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if required peripherals are initialized and
|
|
* configured successfully.
|
|
* - XST_FAILURE, otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 DpRxSs_PlatformInit(void)
|
|
{
|
|
/* User is responsible to setup platform specific initialization */
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function configures Video Phy.
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if Video Phy configured successfully.
|
|
* - XST_FAILURE, otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 DpRxSs_VideoPhyInit(void)
|
|
{
|
|
/* User is responsible to setup Video Phy */
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function configures DisplayPort TX Subsystem.
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if DPTX Subsystem configured successfully.
|
|
* - XST_FAILURE, otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 DpTxSs_Setup(void)
|
|
{
|
|
/* User is responsible to setup Video Phy */
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function sets up a custom timer which the driver will use for MicroBlaze
|
|
* systems.
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if a timer controller exists for use.
|
|
* - XST_FAILURE otherwise.
|
|
*
|
|
* @note A timer controller must be present in the system.
|
|
*
|
|
******************************************************************************/
|
|
u32 DpRxSs_SetupTimerHandler(void)
|
|
{
|
|
u32 Status;
|
|
|
|
Status = XTmrCtr_Initialize(&TmrCtrInst, XTMR_CTRL_DEVICE_ID);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Set a custom timer handler for improved delay accuracy on MicroBlaze
|
|
* systems since the driver does not assume/have a dependency on the
|
|
* system having a timer in the FPGA.
|
|
* Note: This only has an affect for MicroBlaze systems since the Zynq
|
|
* ARM SoC contains a timer, which is used when the driver calls the
|
|
* delay function. */
|
|
XDpRxSs_SetUserTimerHandler(&DpRxSsInst, &DpRxSs_CustomWaitUs,
|
|
&TmrCtrInst);
|
|
|
|
XTmrCtr_SetResetValue(DpRxSsInst.DpPtr->UserTimerPtr, 0, 0);
|
|
XTmrCtr_Reset(DpRxSsInst.DpPtr->UserTimerPtr, 0);
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is used to override the driver's default sleep functionality.
|
|
* For MicroBlaze systems, the XDpRxSs_WaitUs driver function's default behavior
|
|
* is to use the MB_Sleep function from microblaze_sleep.h, which is implemented
|
|
* in software and only has millisecond accuracy. For this reason, using a
|
|
* hardware timer is preferable. For ARM/Zynq SoC systems, the SoC's timer is
|
|
* used - XDpRxSs_WaitUs will ignore this custom timer handler.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs core instance.
|
|
* @param MicroSeconds is the number of microseconds to delay/sleep for.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note Use the XDpRxSs_SetUserTimerHandler driver function to set this
|
|
* function as the handler for when the XDpRxSs_WaitUs driver
|
|
* function is called.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_CustomWaitUs(void *InstancePtr, u32 MicroSeconds)
|
|
{
|
|
XDpRxSs *DpRxSsPtr = (XDpRxSs *)InstancePtr;
|
|
u32 TimerVal;
|
|
|
|
XTmrCtr_Start(DpRxSsPtr->DpPtr->UserTimerPtr, 0);
|
|
|
|
/* Wait specified number of useconds. */
|
|
do {
|
|
TimerVal = XTmrCtr_GetValue(DpRxSsPtr->DpPtr->UserTimerPtr, 0);
|
|
} while (TimerVal < (MicroSeconds *
|
|
(DpRxSsPtr->DpPtr->Config.SAxiClkHz / 1000000)));
|
|
|
|
XTmrCtr_Stop(DpRxSsPtr->DpPtr->UserTimerPtr, 0);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function sets up the interrupt system so interrupts can occur for the
|
|
* DisplayPort RX Subsystem core. The function is application-specific since
|
|
* the actual system may or may not have an interrupt controller. The DPRX
|
|
* Subsystem core could be directly connected to a processor without an
|
|
* interrupt controller. The user should modify this function to fit the
|
|
* application.
|
|
*
|
|
* @param None
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if interrupt setup was successful.
|
|
* - A specific error code defined in "xstatus.h" if an error
|
|
* occurs.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 DpRxSs_SetupIntrSystem(void)
|
|
{
|
|
u32 Status;
|
|
XINTC *IntcInstPtr = &IntcInst;
|
|
|
|
/* Set callbacks for the required interrupts */
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VM_CHG_EVENT,
|
|
DpRxSs_VideoModeHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_NO_VID_EVENT,
|
|
DpRxSs_NoVideoHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VBLANK_EVENT,
|
|
DpRxSs_VerticalBlankHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_TLOST_EVENT,
|
|
DpRxSs_TrainingLostHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_TDONE_EVENT,
|
|
DpRxSs_TrainingDoneHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_DWN_REQ_EVENT,
|
|
DpRxSs_DownReqestHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_DWN_REP_EVENT,
|
|
DpRxSs_DownReplyHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_UNPLUG_EVENT,
|
|
DpRxSs_UnplugHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_LINKBW_EVENT,
|
|
DpRxSs_LinkBandwidthHandler, &DpRxSsInst);
|
|
XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_PLL_RESET_EVENT,
|
|
DpRxSs_PllResetHandler, &DpRxSsInst);
|
|
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
/* Initialize the interrupt controller driver so that it's ready to
|
|
* use, specify the device ID that was generated in xparameters.h
|
|
*/
|
|
Status = XIntc_Initialize(IntcInstPtr, XINTC_DEVICE_ID);
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("Intc initialization failed!\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Hook up interrupt service routine */
|
|
Status = XIntc_Connect(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID,
|
|
(XInterruptHandler)XDpRxSs_DpIntrHandler,
|
|
&DpRxSsInst);
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("ERR: DP RX SS DP interrupt connect failed!\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Enable the interrupt vector at the interrupt controller */
|
|
XIntc_Enable(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID);
|
|
|
|
/* Start the interrupt controller such that interrupts are recognized
|
|
* and handled by the processor
|
|
*/
|
|
Status = XIntc_Start(IntcInstPtr, XIN_REAL_MODE);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
#else
|
|
/* The configuration parameters of the interrupt controller */
|
|
XScuGic_Config *IntcConfig;
|
|
|
|
/* Initialize the interrupt controller driver so that it is ready to
|
|
* use.
|
|
*/
|
|
IntcConfig = XScuGic_LookupConfig(XINTC_DEVICE_ID);
|
|
if (NULL == IntcConfig) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
Status = XScuGic_CfgInitialize(IntcInstPtr, IntcConfig,
|
|
IntcConfig->CpuBaseAddress);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Connect the device driver handler that will be called when an
|
|
* interrupt for the device occurs, the handler defined above performs
|
|
* the specific interrupt processing for the device
|
|
*/
|
|
Status = XScuGic_Connect(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID,
|
|
(Xil_InterruptHandler)XDpRxSs_DpIntrHandler,
|
|
&DpRxSsInst);
|
|
if (Status != XST_SUCCESS) {
|
|
xil_printf("ERR: DP RX SS DP interrupt connect failed!\n\r");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/* Enable the interrupt for the Pixel Splitter device */
|
|
XScuGic_Enable(IntcInstance, XINTC_DPRXSS_DP_INTERRUPT_ID);
|
|
#endif
|
|
/* Initialize the exception table. */
|
|
Xil_ExceptionInit();
|
|
|
|
/* Register the interrupt controller handler with the exception
|
|
* table.
|
|
*/
|
|
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
|
(Xil_ExceptionHandler)XINTC_HANDLER, IntcInstPtr);
|
|
|
|
/* Enable exceptions. */
|
|
Xil_ExceptionEnable();
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when a video mode change interrupt
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_VideoModeHandler(void *InstancePtr)
|
|
{
|
|
XDpRxSs *DpRxSsPtr = (XDpRxSs *)InstancePtr;
|
|
|
|
xil_printf("Interrupt: video mode change.\n\r");
|
|
|
|
if (DpRxSsPtr->VBlankCount >= 20) {
|
|
DpRxSs_DetectResolution(DpRxSsPtr);
|
|
|
|
/* User is responsible for resetting the video pipe */
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function will present the resolution of the incoming video stream.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note The resolution will be rounded up to the nearest resolution
|
|
* present in the XVidC_VideoTimingModes table.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_DetectResolution(XDpRxSs *InstancePtr)
|
|
{
|
|
u32 DpHres, DpVres;
|
|
u32 GetResCount = 0;
|
|
|
|
do {
|
|
DpHres = XDpRxSs_ReadReg(InstancePtr->DpPtr->Config.BaseAddr,
|
|
XDPRXSS_MSA_HRES);
|
|
DpVres = XDpRxSs_ReadReg(InstancePtr->DpPtr->Config.BaseAddr,
|
|
XDPRXSS_MSA_VRES);
|
|
GetResCount++;
|
|
XDpRxSs_WaitUs(InstancePtr, 1000);
|
|
} while (((DpHres == 0) || (DpVres == 0)) && (GetResCount < 2000));
|
|
|
|
xil_printf("\n*** Detected resolution: %u x %u ***\n", DpHres, DpVres);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when a no video interrupt occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_NoVideoHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: no-video flags in the VBID field after active "
|
|
"video has been received.\n\r");
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when the training done interrupt
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_TrainingDoneHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: training done.\n\r");
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when a down request interrupt
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_DownReqestHandler(void *InstancePtr)
|
|
{
|
|
XDpRxSs *DpRxSsPtr = (XDpRxSs *)InstancePtr;
|
|
|
|
xil_printf("Interrupt: down request.\n\r");
|
|
|
|
XDpRxSs_HandleDownReq(DpRxSsPtr);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when a down reply interrupt
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_DownReplyHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: down reply.\n\r");
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when a vertical blank interrupt
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_VerticalBlankHandler(void *InstancePtr)
|
|
{
|
|
XDpRxSs *DpRxSsPtr = (XDpRxSs *)InstancePtr;
|
|
u32 Status;
|
|
|
|
if (DpRxSsPtr->VBlankEnable) {
|
|
DpRxSsPtr->VBlankCount++;
|
|
xil_printf("Interrupt: vertical blanking (frame %d).\n",
|
|
DpRxSsPtr->VBlankCount);
|
|
|
|
/* Wait until 20 frames have been received before forwarding or
|
|
* outputting any video stream. */
|
|
if (DpRxSsPtr->VBlankCount >= 20) {
|
|
DpRxSsPtr->VBlankEnable = 0;
|
|
DpRxSsPtr->VBlankCount = 0;
|
|
XDp_RxInterruptDisable(DpRxSsPtr->DpPtr,
|
|
XDP_RX_INTERRUPT_MASK_VBLANK_MASK);
|
|
|
|
Status = XDpRxSs_CheckLinkStatus(InstancePtr);
|
|
if (Status == XST_SUCCESS) {
|
|
/* User is responsible for resetting the video
|
|
* pipe.
|
|
*/
|
|
|
|
/* Detect resolution */
|
|
DpRxSs_DetectResolution(InstancePtr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when a training lost interrupt
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_TrainingLostHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: training done.\n\r");
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when the unplug event occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_UnplugHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: unplug event.\n\r");
|
|
|
|
/* User is responsible to take corrective actions */
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for when the link bandwidth change
|
|
* occurs.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_LinkBandwidthHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: link bandwidth change request.\n\r");
|
|
|
|
/* User is responsible to re-initialize Video Phy if link rate
|
|
* is mismatching.
|
|
*/
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function is the callback function for PLL reset request.
|
|
*
|
|
* @param InstancePtr is a pointer to the XDpRxSs instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void DpRxSs_PllResetHandler(void *InstancePtr)
|
|
{
|
|
xil_printf("Interrupt: PLL reset request.\n\r");
|
|
|
|
/* User is responsible to reset Video Phy */
|
|
}
|