diff --git a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c index 864cd92d..94cd5d90 100644 --- a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c +++ b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c @@ -271,6 +271,14 @@ static void Dptx_StartVideoStream(XDptx *InstancePtr) /* Set the bits per color. If not set, the default is 6. */ XDptx_CfgMsaSetBpc(InstancePtr, XDPTX_STREAM_ID1, 8); + /* Set synchronous clock mode. */ + XDptx_CfgMsaEnSynchClkMode(InstancePtr, XDPTX_STREAM_ID1, 1); + + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID1); + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID2); + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID3); + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID4); + /* Choose a method for selecting the video mode. There are 3 ways to do this: * 1) Use the preferred timing from the monitor's EDID: * u8 Edid[XDPTX_EDID_SIZE]; diff --git a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_mst_example.c b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_mst_example.c index 22317619..65621340 100644 --- a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_mst_example.c +++ b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_mst_example.c @@ -38,9 +38,8 @@ * (MST) mode. * * @note When topology discovery is enabled, the required stack size will - * be larger than the default that SDK sets of 0x400. Increase the - * stack size if the ALLOCATE_FROM_SINKLIST option is used. Testing - * was done with a stack size of 0x1000. + * be larger than the default that SDK sets. Increase the stack + * size if the ALLOCATE_FROM_SINKLIST option is used. * @note For this example to display output, the user will need to * implement initialization of the system (Dptx_PlatformInit) and, * after training is complete, implement configuration of the video @@ -49,6 +48,8 @@ * @note The functions Dptx_PlatformInit and Dptx_StreamSrc* are declared * extern in xdptx_example_common.h and are left up to the user to * implement. + * @note Some setups require introduction of delays when sending sideband + * messages. * *
* MODIFICATION HISTORY: @@ -94,6 +95,7 @@ /**************************** Function Prototypes *****************************/ u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId); +u32 Dptx_MstExampleRun(XDptx *InstancePtr); /**************************** Function Definitions ****************************/ @@ -141,21 +143,6 @@ int main(void) u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId) { u32 Status; - u32 MaskVal; - u8 StreamIndex; - XDptx_VideoMode VideoMode = USE_VIDEO_MODE; - u8 Bpc = USE_BPC; - - /* Enable multi-stream transport (MST) mode for this example. */ - XDptx_MstCfgModeEnable(InstancePtr); - for (StreamIndex = 0; StreamIndex < NUM_STREAMS; StreamIndex++) { - XDptx_MstCfgStreamEnable(InstancePtr, XDPTX_STREAM_ID1 + - StreamIndex); - } - for (StreamIndex = NUM_STREAMS; StreamIndex < 4; StreamIndex++) { - XDptx_MstCfgStreamDisable(InstancePtr, XDPTX_STREAM_ID1 + - StreamIndex); - } /* Do platform initialization here. This is hardware system specific - * it is up to the user to implement this function. */ @@ -180,20 +167,93 @@ u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId) return XST_FAILURE; } + do { + Status = Dptx_MstExampleRun(InstancePtr); + + if (Status == XST_ERROR_COUNT_MAX) { + xil_printf("ACT trigger lost... Need to re-train.\n"); + } + } while (Status != XST_SUCCESS); + + /* Do not return. */ + xil_printf("MST example DONE.\n"); + while (1); + + return XST_SUCCESS; +} + +/******************************************************************************/ +/** + * This function trains the link and allocates stream payloads. + * + * @param InstancePtr is a pointer to the XDptx instance. + * @param DeviceId is the unique device ID of the DisplayPort TX core + * instance. + * + * @return + * - XST_SUCCESS if MST allocation was successful. + * - XST_ERROR_COUNT_MAX if the ACT trigger was lost. + * - XST_FAILURE otherwise. + * + * @note None. + * +*******************************************************************************/ +u32 Dptx_MstExampleRun(XDptx *InstancePtr) +{ + u32 Status; + u32 MaskVal; + u8 StreamIndex; + XDptx_VideoMode VideoMode = USE_VIDEO_MODE; + u8 Bpc = USE_BPC; + u8 NumStreams = NUM_STREAMS; + XDptx_EnableTrainAdaptive(InstancePtr, TRAIN_ADAPTIVE); - XDptx_SetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER); + XDptx_SetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER); + + InstancePtr->AuxDelayUs = 0; + InstancePtr->SbMsgDelayUs = 0; /* A DisplayPort connection must exist at this point. See the interrupt * and polling examples for waiting for connection events. */ Status = Dptx_StartLink(InstancePtr); if (Status != XST_SUCCESS) { + xil_printf("Link Training failed.\n"); return XST_FAILURE; } - XDptx_CfgMsaSetBpc(InstancePtr, XDPTX_STREAM_ID1, Bpc); - XDptx_CfgMsaSetBpc(InstancePtr, XDPTX_STREAM_ID2, Bpc); - XDptx_CfgMsaSetBpc(InstancePtr, XDPTX_STREAM_ID3, Bpc); - XDptx_CfgMsaSetBpc(InstancePtr, XDPTX_STREAM_ID4, Bpc); + /* If required, add delays in MST mode. */ + InstancePtr->AuxDelayUs = 30000; + InstancePtr->SbMsgDelayUs = 100000; + + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID1); + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID2); + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID3); + XDptx_ClearMsaValues(InstancePtr, XDPTX_STREAM_ID4); + +#ifdef ALLOCATE_FROM_SINKLIST + xil_printf("Find topology >>>\n"); + InstancePtr->Topology.NodeTotal = 0; + InstancePtr->Topology.SinkTotal = 0; + + XDptx_FindAccessibleDpDevices(InstancePtr, 1, NULL); + xil_printf("<<< Find topology DONE; # of sinks found = %d.\n", + InstancePtr->Topology.SinkTotal); + + if (NumStreams > InstancePtr->Topology.SinkTotal) { + NumStreams = InstancePtr->Topology.SinkTotal; + } +#endif + + /* Enable multi-stream transport (MST) mode for this example. */ + XDptx_MstCfgModeEnable(InstancePtr); + for (StreamIndex = 0; StreamIndex < NumStreams; StreamIndex++) { + XDptx_MstCfgStreamEnable(InstancePtr, XDPTX_STREAM_ID1 + + StreamIndex); + } + for (StreamIndex = NumStreams; StreamIndex < 4; StreamIndex++) { + XDptx_MstCfgStreamDisable(InstancePtr, XDPTX_STREAM_ID1 + + StreamIndex); + } #ifndef ALLOCATE_FROM_SINKLIST u8 Lct; @@ -217,26 +277,19 @@ u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId) } #else - xil_printf("Find topology >>>\n"); - InstancePtr->Topology.NodeTotal = 0; - InstancePtr->Topology.SinkTotal = 0; - - XDptx_FindAccessibleDpDevices(InstancePtr, 1, NULL); - xil_printf("<<< Find topology DONE.\n"); - if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID1)) { XDptx_SetStreamSelectFromSinkList(InstancePtr, XDPTX_STREAM_ID1, STREAM1_USE_SINKNUM); } - if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID1)) { + if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID2)) { XDptx_SetStreamSelectFromSinkList(InstancePtr, XDPTX_STREAM_ID2, STREAM2_USE_SINKNUM); } - if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID1)) { + if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID3)) { XDptx_SetStreamSelectFromSinkList(InstancePtr, XDPTX_STREAM_ID3, STREAM3_USE_SINKNUM); } - if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID1)) { + if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID4)) { XDptx_SetStreamSelectFromSinkList(InstancePtr, XDPTX_STREAM_ID4, STREAM4_USE_SINKNUM); } @@ -248,6 +301,11 @@ u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId) for (StreamIndex = 0; StreamIndex < 4; StreamIndex++) { if (XDptx_MstStreamIsEnabled(InstancePtr, XDPTX_STREAM_ID1 + StreamIndex)) { + XDptx_CfgMsaSetBpc(InstancePtr, XDPTX_STREAM_ID1 + + StreamIndex, Bpc); + XDptx_CfgMsaEnSynchClkMode(InstancePtr, + XDPTX_STREAM_ID1 + StreamIndex, 1); + XDptx_CfgMsaUseStandardVideoMode(InstancePtr, XDPTX_STREAM_ID1 + StreamIndex, VideoMode); } @@ -283,24 +341,29 @@ u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId) XDPTX_SOFT_RESET_VIDEO_STREAM_ALL_MASK); XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDPTX_SOFT_RESET, 0x0); + /* Sync the stream source to the DisplayPort TX if needed. */ + Dptx_StreamSrcSync(InstancePtr); + //////////////////////////////////// + /* Mask interrupts while allocating payloads. */ MaskVal = XDptx_ReadReg(InstancePtr->Config.BaseAddr, XDPTX_INTERRUPT_MASK); XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDPTX_INTERRUPT_MASK, 0x3F); - /* Allocate payloads. */ XDptx_MstEnable(InstancePtr); - XDptx_AllocatePayloadStreams(InstancePtr); - /* Reset the transmitter. */ - XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDPTX_SOFT_RESET, - XDPTX_SOFT_RESET_VIDEO_STREAM_ALL_MASK); - XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDPTX_SOFT_RESET, 0x0); + /* Clear the payload ID table first. */ + Status = XDptx_ClearPayloadVcIdTable(InstancePtr); + if (Status != XST_SUCCESS) { + return Status; + } - /* Sync the stream source to the DisplayPort TX if needed. */ - Dptx_StreamSrcSync(InstancePtr); - //////////////////////////////////// + /* Allocate payloads. */ + Status = XDptx_AllocatePayloadStreams(InstancePtr); + if (Status != XST_SUCCESS) { + return Status; + } /* Enable the main link. */ XDptx_EnableMainLink(InstancePtr); @@ -309,8 +372,5 @@ u32 Dptx_MstExample(XDptx *InstancePtr, u16 DeviceId) XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDPTX_INTERRUPT_MASK, MaskVal); - /* Do not return. */ - while (1); - return XST_SUCCESS; } diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h b/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h index 40aaf13b..0b44336e 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h @@ -186,6 +186,9 @@ * investigated for the next SDK release. * - The driver does not handle audio. See the audio example in the driver * examples directory for the required sequence for enabling audio. + * - Limited testing was done with 4-byte GT data width. + * - Most testing was done on a KC705 board. Some testing was done on a ZC706 + * board, mostly with a 2-byte GT data width configuration. * * @note For a 5.4Gbps link rate, a high performance 7 series FPGA is * required with a speed grade of -2 or -3. diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c index f755b29f..c4325573 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c @@ -682,12 +682,6 @@ u32 XDptx_AllocatePayloadStreams(XDptx *InstancePtr) Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); - /* Clear the payload ID table first. */ - Status = XDptx_ClearPayloadVcIdTable(InstancePtr); - if (Status != XST_SUCCESS) { - return Status; - } - /* Allocate the payload table for each stream in both the DisplayPort TX * and RX device. */ for (StreamIndex = 0; StreamIndex < 4; StreamIndex++) { @@ -914,6 +908,8 @@ u32 XDptx_ClearPayloadVcIdTable(XDptx *InstancePtr) } } while ((AuxData[0] & 0x01) != 0x01); + XDptx_WaitUs(InstancePtr, 1000); + Status = XDptx_SendActTrigger(InstancePtr); if (Status != XST_SUCCESS) { return Status; diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c index 51d7950f..0884c12e 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c @@ -53,7 +53,6 @@ /******************************* Include Files ********************************/ -#include "math.h" #include "xdptx.h" #include "xdptx_hw.h" #include "xstatus.h"