From c4154510b8ab26ac8dcbbaad16b942aae9f997f5 Mon Sep 17 00:00:00 2001 From: Andrei-Liviu Simion Date: Mon, 4 Aug 2014 21:40:03 -0700 Subject: [PATCH] dptx: Initial commit for multi-stream transport (MST) functionality. - Now supporting up to 4 streams. - Separate set of main stream attributes (MSA) for each stream. - New MST calculations for payload bandwidth number (PBN) and time slot allocation. Signed-off-by: Andrei-Liviu Simion --- .../dptx/examples/xdptx_example_common.c | 36 +- .../dptx/examples/xdptx_example_common.h | 2 +- XilinxProcessorIPLib/drivers/dptx/src/xdptx.h | 148 +++--- .../drivers/dptx/src/xdptx_hw.h | 2 +- .../drivers/dptx/src/xdptx_spm.c | 500 +++++++++++------- .../drivers/dptx/src/xdptx_vidmodetable.c | 2 +- 6 files changed, 409 insertions(+), 281 deletions(-) diff --git a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c index 04788aea..f3d716a0 100644 --- a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c +++ b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.c @@ -270,37 +270,37 @@ static void Dptx_StartVideoStream(XDptx *InstancePtr) u8 AuxData[1]; /* Set the bits per color. If not set, the default is 6. */ - XDptx_CfgMsaSetBpc(InstancePtr, 8); + XDptx_CfgMsaSetBpc(InstancePtr, 1, 8); /* 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: * XDptx_GetEdid(InstancePtr); - * XDptx_CfgMsaUseEdidPreferredTiming(InstancePtr); + * XDptx_CfgMsaUseEdidPreferredTiming(InstancePtr, 1); * * 2) Use a standard video timing mode (see mode_table.h): - * XDptx_CfgMsaUseStandardVideoMode(InstancePtr, XDPTX_VM_640x480_60_P); + * XDptx_CfgMsaUseStandardVideoMode(InstancePtr, 1, XDPTX_VM_640x480_60_P); * * 3) Use a custom configuration for the main stream attributes (MSA): * XDptx_MainStreamAttributes MsaConfigCustom; - * MsaConfigCustom.MVid = 108000; - * MsaConfigCustom.HSyncPolarity = 0; - * MsaConfigCustom.VSyncPolarity = 0; - * MsaConfigCustom.HSyncPulseWidth = 112; - * MsaConfigCustom.VSyncPulseWidth = 3; - * MsaConfigCustom.HResolution = 1280; - * MsaConfigCustom.VResolution = 1024; - * MsaConfigCustom.VBackPorch = 38; - * MsaConfigCustom.VFrontPorch = 1; - * MsaConfigCustom.HBackPorch = 248; - * MsaConfigCustom.HFrontPorch = 48; - * XDptx_CfgMsaUseCustom(InstancePtr, &MsaConfigCustom, 1); + * MsaConfigCustom.Dmt.HResolution = 1280; + * MsaConfigCustom.Dmt.VResolution = 1024; + * MsaConfigCustom.Dmt.PixelClkKhz = 108000; + * MsaConfigCustom.Dmt.HSyncPolarity = 0; + * MsaConfigCustom.Dmt.VSyncPolarity = 0; + * MsaConfigCustom.Dmt.HFrontPorch = 48; + * MsaConfigCustom.Dmt.HSyncPulseWidth = 112; + * MsaConfigCustom.Dmt.HBackPorch = 248; + * MsaConfigCustom.Dmt.VFrontPorch = 1; + * MsaConfigCustom.Dmt.VSyncPulseWidth = 3; + * MsaConfigCustom.Dmt.VBackPorch = 38; + * XDptx_CfgMsaUseCustom(InstancePtr, 1, &MsaConfigCustom, 1); */ Status = XDptx_GetEdid(InstancePtr); if (Status == XST_SUCCESS) { - XDptx_CfgMsaUseEdidPreferredTiming(InstancePtr); + XDptx_CfgMsaUseEdidPreferredTiming(InstancePtr, 1); } else { - XDptx_CfgMsaUseStandardVideoMode(InstancePtr, + XDptx_CfgMsaUseStandardVideoMode(InstancePtr, 1, XDPTX_VM_640x480_60_P); } @@ -320,7 +320,7 @@ static void Dptx_StartVideoStream(XDptx *InstancePtr) /* Configure video stream source or generator here. This function needs * to be implemented in order for video to be displayed and is hardware * system specific. It is up to the user to implement this function. */ - Dptx_ConfigureStreamSrc(InstancePtr); + Dptx_ConfigureStreamSrc(InstancePtr, 1); /*********************************/ XDptx_EnableMainLink(InstancePtr); diff --git a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.h b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.h index 839b78f6..bbd7c3c8 100644 --- a/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.h +++ b/XilinxProcessorIPLib/drivers/dptx/examples/xdptx_example_common.h @@ -121,7 +121,7 @@ /**************************** Function Prototypes *****************************/ extern u32 Dptx_PlatformInit(void); -extern u32 Dptx_ConfigureStreamSrc(XDptx *InstancePtr); +extern u32 Dptx_ConfigureStreamSrc(XDptx *InstancePtr, u8 Stream); u32 Dptx_SetupExample(XDptx *InstancePtr, u16 DeviceId); u32 Dptx_Run(XDptx *InstancePtr); diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h b/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h index a0500224..21c14b47 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h @@ -303,33 +303,6 @@ typedef enum { XDPTX_VM_LAST = XDPTX_VM_USE_EDID_PREFERRED } XDptx_VideoMode; -/** - * This typedef contains the display monitor timing attributes for a video mode. - */ -typedef struct { - XDptx_VideoMode VideoMode; /**< Enumerated key. */ - u8 DmtId; /**< Standard Display Monitor Timing - (DMT) ID number. */ - u16 HResolution; /**< Horizontal resolution. */ - u16 VResolution; /**< Vertical resolution. */ - u32 PixelClkKhz; /**< Pixel frequency (in KHz). */ - u8 Scan; /**< Interlaced/non-interlaced. */ - u8 HSyncPolarity; /**< Horizontal synchronization - polarity. */ - u8 VSyncPolarity; /**< Vertical synchronization - polarity. */ - u32 HFrontPorch; /**< Horizontal front porch. */ - u32 HSyncPulseWidth; /**< Horizontal synchronization pulse - width. */ - u32 HBackPorch; /**< Horizontal back porch. */ - u32 VFrontPorch; /**< Vertical front porch. */ - u32 VSyncPulseWidth; /**< Vertical synchronization pulse - width.*/ - u32 VBackPorch; /**< Vertical back porch. */ -} XDptx_DmtMode; - -extern XDptx_DmtMode XDptx_DmtModes[]; - /** * This typedef contains configuration information for the DisplayPort TX core. */ @@ -404,58 +377,65 @@ typedef struct { each lane. */ u8 PeLevel; /**< The current pre-emphasis/cursor level for each lane. */ - u8 ComponentFormat; /**< The component format currently in - use over the main link. */ - u8 DynamicRange; /**< The dynamic range currently in use - over the main link. */ - u8 YCbCrColorimetry; /**< The YCbCr colorimetry currently in - use over the main link. */ - u8 SynchronousClockMode; /**< Synchronous clock mode is currently - in use over the main link. */ u8 Pattern; /**< The current pattern currently in use over the main link. */ } XDptx_LinkConfig; +/** + * This typedef contains the display monitor timing attributes for a video mode. + */ +typedef struct { + XDptx_VideoMode VideoMode; /**< Enumerated key. */ + u8 DmtId; /**< Standard Display Monitor Timing + (DMT) ID number. */ + u16 HResolution; /**< Horizontal resolution (in + pixels). */ + u16 VResolution; /**< Vertical resolution (in lines). */ + u32 PixelClkKhz; /**< Pixel frequency (in KHz). This is + also the M value for the video + stream (MVid). */ + u8 Interlaced; /**< Input stream interlaced scan + (0=non-interlaced/ + 1=interlaced). */ + u8 HSyncPolarity; /**< Horizontal synchronization polarity + (0=positive/1=negative). */ + u8 VSyncPolarity; /**< Vertical synchronization polarity + (0=positive/1=negative). */ + u32 HFrontPorch; /**< Horizontal front porch (in + pixels). */ + u32 HSyncPulseWidth; /**< Horizontal synchronization time + (pulse width in pixels). */ + u32 HBackPorch; /**< Horizontal back porch (in + pixels). */ + u32 VFrontPorch; /**< Vertical front porch (in lines). */ + u32 VSyncPulseWidth; /**< Vertical synchronization time + (pulse width in lines). */ + u32 VBackPorch; /**< Vertical back porch (in lines). */ +} XDptx_DmtMode; + /** * This typedef contains the main stream attributes which determine how the * video will be displayed. */ typedef struct { + XDptx_DmtMode Dmt; /**< Holds the set of Display Mode + Timing (DMT) attributes that + correspond to the information + stored in the XDptx_DmtModes + table. */ u32 HClkTotal; /**< Horizontal total time (in pixels). */ u32 VClkTotal; /**< Vertical total time (in pixels). */ - u32 HSyncPulseWidth; /**< Horizontal synchronization time (in - pixels). */ - u32 VSyncPulseWidth; /**< Vertical synchronization time (in - lines */ - u32 HResolution; /**< Horizontal resolution (in - pixels). */ - u32 VResolution; /**< Vertical resolution (in lines). */ - u32 HSyncPolarity; /**< Horizontal synchronization polarity - (0=positive/1=negative). */ - u32 VSyncPolarity; /**< Vertical synchronization polarity - (0=positive/1=negative). */ u32 HStart; /**< Horizontal blank start (in pixels). */ u32 VStart; /**< Vertical blank start (in lines). */ - u32 VBackPorch; /**< Vertical back porch (in lines). */ - u32 VFrontPorch; /**< Vertical front porch (in lines). */ - u32 HBackPorch; /**< Horizontal back porch (in - pixels). */ - u32 HFrontPorch; /**< Horizontal front porch (in - pixels). */ u32 Misc0; /**< Miscellaneous stream attributes 0 as specified by the DisplayPort 1.2 specification. */ u32 Misc1; /**< Miscellaneous stream attributes 1 as specified by the DisplayPort 1.2 specification. */ - u32 MVid; /**< M value for the video stream. This - value is equal to the pixel - clock in KHz. */ u32 NVid; /**< N value for the video stream. */ - u32 TransferUnitSize; /**< Size of the transfer unit in the - framing logic. */ u32 UserPixelWidth; /**< The width of the user data input port. */ u32 DataPerLane; /**< Used to translate the number of @@ -464,12 +444,30 @@ typedef struct { u32 AvgBytesPerTU; /**< Average number of bytes per transfer unit, scaled up by a factor of 1000. */ + u32 TransferUnitSize; /**< Size of the transfer unit in the + framing logic. In MST mode, this + is also the number of time slots + that are alloted in the payload + ID table. */ u32 InitWait; /**< Number of initial wait cycles at the start of a new line by the framing logic. */ - u32 Interlaced; /**< Input stream is interlaced. */ u32 BitsPerColor; /**< Number of bits per color component. */ + u8 ComponentFormat; /**< The component format currently in + use by the video stream. */ + u8 DynamicRange; /**< The dynamic range currently in use + by the video stream. */ + u8 YCbCrColorimetry; /**< The YCbCr colorimetry currently in + use by the video stream. */ + u8 SynchronousClockMode; /**< Synchronous clock mode is currently + in use by the video stream. */ + u16 MstPbn; /**< Payload bandwidth number used to + allocate bandwidth in MST + mode. */ + u8 MstStreamEnable; /**< In MST mode, enables the + corresponding stream for this + MSA configuration. */ } XDptx_MainStreamAttributes; /******************************************************************************/ @@ -520,6 +518,12 @@ typedef void (*XDptx_HpdPulseHandler)(void *InstancePtr); * this type is then passed to the driver API functions. */ typedef struct { + u32 MstEnable; /**< Multi-stream transport + (MST) mode. Enables + functionality, allowing + multiple streams to be + sent over the main + link. */ u32 IsReady; /**< Device is initialized and ready. */ u8 TrainAdaptive; /**< Downshift lane count and @@ -535,9 +539,13 @@ typedef struct { the RX device. */ XDptx_LinkConfig LinkConfig; /**< Configuration structure for the main link. */ - XDptx_MainStreamAttributes MsaConfig; /**< Configuration structure for - the main stream - attributes. */ + XDptx_MainStreamAttributes MsaConfig[4]; /**< Configuration structure + for the main stream + attributes (MSA). Each + stream has its own set + of attributes. When MST + mode is disabled, only + MsaConfig[0] is used. */ XDptx_TimerHandler UserTimerWaitUs; /**< Custom user function for delay/sleep. */ void *UserTimerPtr; /**< Pointer to a timer instance @@ -557,6 +565,10 @@ typedef struct { callback function.*/ } XDptx; +/*************************** Variable Declarations ****************************/ + +extern XDptx_DmtMode XDptx_DmtModes[]; + /**************************** Function Prototypes *****************************/ /* xdptx.c: Setup and initialization functions. */ @@ -597,14 +609,16 @@ void XDptx_SetUserTimerHandler(XDptx *InstancePtr, XDptx_TimerHandler CallbackFunc, void *CallbackRef); /* xdptx_spm.c: Stream policy maker functions. */ -void XDptx_CfgMsaRecalculate(XDptx *InstancePtr); -void XDptx_CfgMsaUseStandardVideoMode(XDptx *InstancePtr, +void XDptx_CfgMsaRecalculate(XDptx *InstancePtr, u8 Stream); +void XDptx_CfgMsaUseStandardVideoMode(XDptx *InstancePtr, u8 Stream, XDptx_VideoMode VideoMode); -void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr); -void XDptx_CfgMsaUseCustom(XDptx *InstancePtr, +void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr, u8 Stream); +void XDptx_CfgMsaUseCustom(XDptx *InstancePtr, u8 Stream, XDptx_MainStreamAttributes *MsaConfigCustom, u8 Recalculate); -void XDptx_CfgMsaSetBpc(XDptx *InstancePtr, u8 BitsPerColor); -void XDptx_SetVideoMode(XDptx *InstancePtr); +void XDptx_CfgMsaSetBpc(XDptx *InstancePtr, u8 Stream, u8 BitsPerColor); +void XDptx_SetVideoMode(XDptx *InstancePtr, u8 Stream); +void XDptx_ClearMsaValues(XDptx *InstancePtr, u8 Stream); +void XDptx_SetMsaValues(XDptx *InstancePtr, u8 Stream); /* xdptx_intr.c: Interrupt handling functions. */ void XDptx_SetHpdEventHandler(XDptx *InstancePtr, diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_hw.h b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_hw.h index 43c3a84f..e51b3612 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_hw.h +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_hw.h @@ -300,7 +300,7 @@ * @{ */ #define XDPTX_STREAM2_MSA_START 0x0500 /**< Start of the MSA registers -for stream 2. */ + for stream 2. */ #define XDPTX_STREAM2_MSA_START_OFFSET (XDPTX_STREAM2_MSA_START - \ XDPTX_STREAM1_MSA_START) /**< The MSA registers for stream 2 are at an diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c index 64e2e7e5..c417288c 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_spm.c @@ -46,21 +46,21 @@ * Ver Who Date Changes * ----- ---- -------- ----------------------------------------------- * 1.00a als 05/17/14 Initial release. + * als 08/03/14 Initial MST addition. * * *******************************************************************************/ /******************************* Include Files ********************************/ +#include "math.h" #include "xdptx.h" #include "xdptx_hw.h" #include "xstatus.h" /**************************** Function Prototypes *****************************/ -static void XDptx_ClearMsaValues(XDptx *InstancePtr); -static void XDptx_SetMsaValues(XDptx *InstancePtr, - XDptx_MainStreamAttributes *MsaConfig); +static void XDptx_CalculateTs(XDptx *InstancePtr, u8 Stream, u8 BitsPerPixel); /**************************** Function Definitions ****************************/ @@ -69,7 +69,6 @@ static void XDptx_SetMsaValues(XDptx *InstancePtr, * This function calculates the following Main Stream Attributes (MSA): * - Transfer unit size * - User pixel width - * - NVid * - Horizontal start * - Vertical start * - Horizontal total clock @@ -81,17 +80,17 @@ static void XDptx_SetMsaValues(XDptx *InstancePtr, * - Number of initial wait cycles * These values are derived from: * - Bits per color - * - MVid - * - Horizontal sync polarity - * - Vertical sync polarity - * - Horizontal sync pulse width - * - Vertical sync pulse width * - Horizontal resolution * - Vertical resolution - * - Vertical back porch - * - Vertical front porch - * - Horizontal back porch + * - Pixel clock (in KHz) + * - Horizontal sync polarity + * - Vertical sync polarity * - Horizontal front porch + * - Horizontal sync pulse width + * - Horizontal back porch + * - Vertical front porch + * - Vertical sync pulse width + * - Vertical back porch * * @param InstancePtr is a pointer to the XDptx instance. * @@ -102,11 +101,12 @@ static void XDptx_SetMsaValues(XDptx *InstancePtr, * calculated values are untouched in the MsaConfig structure. * *******************************************************************************/ -void XDptx_CfgMsaRecalculate(XDptx *InstancePtr) +void XDptx_CfgMsaRecalculate(XDptx *InstancePtr, u8 Stream) { u32 VideoBw; - u32 BitsPerPixel; - XDptx_MainStreamAttributes *MsaConfig = &InstancePtr->MsaConfig; + u8 BitsPerPixel; + XDptx_MainStreamAttributes *MsaConfig = + &InstancePtr->MsaConfig[Stream - 1]; XDptx_LinkConfig *LinkConfig = &InstancePtr->LinkConfig; /* Verify arguments. */ @@ -117,28 +117,25 @@ void XDptx_CfgMsaRecalculate(XDptx *InstancePtr) Xil_AssertVoid((LinkConfig->LaneCount == XDPTX_LANE_COUNT_SET_1) || (LinkConfig->LaneCount == XDPTX_LANE_COUNT_SET_2) || (LinkConfig->LaneCount == XDPTX_LANE_COUNT_SET_4)); - Xil_AssertVoid((LinkConfig->SynchronousClockMode == 0) || - (LinkConfig->SynchronousClockMode == 1)); - Xil_AssertVoid((LinkConfig->DynamicRange == 0) || - (LinkConfig->DynamicRange == 1)); - Xil_AssertVoid((LinkConfig->YCbCrColorimetry == 0) || - (LinkConfig->YCbCrColorimetry == 1)); + Xil_AssertVoid((MsaConfig->SynchronousClockMode == 0) || + (MsaConfig->SynchronousClockMode == 1)); + Xil_AssertVoid((MsaConfig->DynamicRange == 0) || + (MsaConfig->DynamicRange == 1)); + Xil_AssertVoid((MsaConfig->YCbCrColorimetry == 0) || + (MsaConfig->YCbCrColorimetry == 1)); Xil_AssertVoid((MsaConfig->BitsPerColor == 6) || (MsaConfig->BitsPerColor == 8) || (MsaConfig->BitsPerColor == 10) || (MsaConfig->BitsPerColor == 12) || (MsaConfig->BitsPerColor == 16)); - /* Fixed transfer unit size. */ - MsaConfig->TransferUnitSize = 64; - /* Set the user pixel width to handle clocks that exceed the * capabilities of the DisplayPort TX core. */ - if ((MsaConfig->MVid > 300000) && + if ((MsaConfig->Dmt.PixelClkKhz > 300000) && (LinkConfig->LaneCount == XDPTX_LANE_COUNT_SET_4)) { MsaConfig->UserPixelWidth = 4; } - else if ((MsaConfig->MVid > 75000) && + else if ((MsaConfig->Dmt.PixelClkKhz > 75000) && (LinkConfig->LaneCount != XDPTX_LANE_COUNT_SET_1)) { MsaConfig->UserPixelWidth = 2; } @@ -148,14 +145,18 @@ void XDptx_CfgMsaRecalculate(XDptx *InstancePtr) /* Compute the rest of the MSA values. */ MsaConfig->NVid = 27 * 1000 * LinkConfig->LinkRate; - MsaConfig->HStart = MsaConfig->HSyncPulseWidth + MsaConfig->HBackPorch; - MsaConfig->VStart = MsaConfig->VSyncPulseWidth + MsaConfig->VBackPorch; - MsaConfig->HClkTotal = (MsaConfig->HSyncPulseWidth + - MsaConfig->HBackPorch + MsaConfig->HFrontPorch + - MsaConfig->HResolution); - MsaConfig->VClkTotal = (MsaConfig->VSyncPulseWidth + - MsaConfig->VBackPorch + MsaConfig->VFrontPorch + - MsaConfig->VResolution); + MsaConfig->HStart = MsaConfig->Dmt.HSyncPulseWidth + + MsaConfig->Dmt.HBackPorch; + MsaConfig->VStart = MsaConfig->Dmt.VSyncPulseWidth + + MsaConfig->Dmt.VBackPorch; + MsaConfig->HClkTotal = (MsaConfig->Dmt.HSyncPulseWidth + + MsaConfig->Dmt.HBackPorch + + MsaConfig->Dmt.HFrontPorch + + MsaConfig->Dmt.HResolution); + MsaConfig->VClkTotal = (MsaConfig->Dmt.VSyncPulseWidth + + MsaConfig->Dmt.VBackPorch + + MsaConfig->Dmt.VFrontPorch + + MsaConfig->Dmt.VResolution); /* Miscellaneous attributes. */ if (MsaConfig->BitsPerColor == 6) { @@ -175,21 +176,21 @@ void XDptx_CfgMsaRecalculate(XDptx *InstancePtr) } MsaConfig->Misc0 = (MsaConfig->Misc0 << XDPTX_MAIN_STREAMX_MISC0_BDC_SHIFT) | - (LinkConfig->YCbCrColorimetry << + (MsaConfig->YCbCrColorimetry << XDPTX_MAIN_STREAMX_MISC0_YCBCR_COLORIMETRY_SHIFT) | - (LinkConfig->DynamicRange << + (MsaConfig->DynamicRange << XDPTX_MAIN_STREAMX_MISC0_DYNAMIC_RANGE_SHIFT) | - (LinkConfig->ComponentFormat << + (MsaConfig->ComponentFormat << XDPTX_MAIN_STREAMX_MISC0_COMPONENT_FORMAT_SHIFT) | - (LinkConfig->SynchronousClockMode); + (MsaConfig->SynchronousClockMode); MsaConfig->Misc1 = 0; - MsaConfig->DataPerLane = (MsaConfig->HResolution * - MsaConfig->BitsPerColor * 3 / 16) - LinkConfig->LaneCount; + MsaConfig->DataPerLane = (MsaConfig->Dmt.HResolution * + MsaConfig->BitsPerColor * 3 / 16) - LinkConfig->LaneCount; /* Determine the number of bits per pixel for the specified color * component format. */ - if (LinkConfig->ComponentFormat == + if (MsaConfig->ComponentFormat == XDPTX_MAIN_STREAMX_MISC0_COMPONENT_FORMAT_YCBCR422) { /* YCbCr422 color component format. */ BitsPerPixel = MsaConfig->BitsPerColor * 2; @@ -199,27 +200,47 @@ void XDptx_CfgMsaRecalculate(XDptx *InstancePtr) BitsPerPixel = MsaConfig->BitsPerColor * 3; } - /* Calculate the transfer unit size. */ - VideoBw = (MsaConfig->MVid * BitsPerPixel) / 8; - MsaConfig->AvgBytesPerTU = (VideoBw * MsaConfig->TransferUnitSize) / - (LinkConfig->LaneCount * (MsaConfig->NVid / 1000)); - /* The number of initial wait cycles at the start of a new line by the - * framing logic. This allows enough data to be buffered in the input - * FIFO before video is sent. */ - MsaConfig->InitWait = (MsaConfig->TransferUnitSize - - (MsaConfig->AvgBytesPerTU / 1000)); - if ((MsaConfig->AvgBytesPerTU / 1000) > MsaConfig->TransferUnitSize) { + if (InstancePtr->MstEnable == 1) { + /* Do time slot (and payload bandwidth number) calculations for + * MST. */ + XDptx_CalculateTs(InstancePtr, Stream, BitsPerPixel); + MsaConfig->InitWait = 0; } - else if (MsaConfig->InitWait > 10) { - MsaConfig->InitWait -= 10; - } else { - MsaConfig->InitWait = 0; + /* Allocate a fixed size for single-stream transport (SST) + * operation. */ + MsaConfig->TransferUnitSize = 64; + + /* Calculate the average number of bytes per transfer unit. + * Note: Both the integer and the fractional part is stored in + * AvgBytesPerTU. */ + VideoBw = (MsaConfig->Dmt.PixelClkKhz * BitsPerPixel) / 8; + MsaConfig->AvgBytesPerTU = (VideoBw * + MsaConfig->TransferUnitSize) / + (LinkConfig->LaneCount * + (MsaConfig->NVid / 1000)); + + /* The number of initial wait cycles at the start of a new line + * by the framing logic. This allows enough data to be buffered + * in the input FIFO before video is sent. */ + MsaConfig->InitWait = (MsaConfig->TransferUnitSize - + (MsaConfig->AvgBytesPerTU / 1000)); + if ((MsaConfig->AvgBytesPerTU / 1000) > + MsaConfig->TransferUnitSize) { + MsaConfig->InitWait = 0; + } + else if (MsaConfig->InitWait > 10) { + MsaConfig->InitWait -= 10; + } + else { + MsaConfig->InitWait = 0; + } } } + /******************************************************************************/ /** * This function sets the Main Stream Attribute (MSA) values in the @@ -237,10 +258,11 @@ void XDptx_CfgMsaRecalculate(XDptx *InstancePtr) * MSA values associated to the specified video mode. * *******************************************************************************/ -void XDptx_CfgMsaUseStandardVideoMode(XDptx *InstancePtr, +void XDptx_CfgMsaUseStandardVideoMode(XDptx *InstancePtr, u8 Stream, XDptx_VideoMode VideoMode) { - XDptx_MainStreamAttributes *MsaConfig = &InstancePtr->MsaConfig; + XDptx_MainStreamAttributes *MsaConfig = + &InstancePtr->MsaConfig[Stream - 1]; /* Verify arguments. */ Xil_AssertVoid(InstancePtr != NULL); @@ -248,20 +270,22 @@ void XDptx_CfgMsaUseStandardVideoMode(XDptx *InstancePtr, Xil_AssertVoid(VideoMode <= XDPTX_VM_LAST); /* Configure the MSA values from the display monitor DMT table. */ - MsaConfig->MVid = XDptx_DmtModes[VideoMode].PixelClkKhz; - MsaConfig->HSyncPolarity = XDptx_DmtModes[VideoMode].HSyncPolarity; - MsaConfig->VSyncPolarity = XDptx_DmtModes[VideoMode].VSyncPolarity; - MsaConfig->HSyncPulseWidth = XDptx_DmtModes[VideoMode].HSyncPulseWidth; - MsaConfig->VSyncPulseWidth = XDptx_DmtModes[VideoMode].VSyncPulseWidth; - MsaConfig->HResolution = XDptx_DmtModes[VideoMode].HResolution; - MsaConfig->VResolution = XDptx_DmtModes[VideoMode].VResolution; - MsaConfig->VBackPorch = XDptx_DmtModes[VideoMode].VBackPorch; - MsaConfig->VFrontPorch = XDptx_DmtModes[VideoMode].VFrontPorch; - MsaConfig->HBackPorch = XDptx_DmtModes[VideoMode].HBackPorch; - MsaConfig->HFrontPorch = XDptx_DmtModes[VideoMode].HFrontPorch; + MsaConfig->Dmt.HResolution = XDptx_DmtModes[VideoMode].HResolution; + MsaConfig->Dmt.VResolution = XDptx_DmtModes[VideoMode].VResolution; + MsaConfig->Dmt.PixelClkKhz = XDptx_DmtModes[VideoMode].PixelClkKhz; + MsaConfig->Dmt.HSyncPolarity = XDptx_DmtModes[VideoMode].HSyncPolarity; + MsaConfig->Dmt.VSyncPolarity = XDptx_DmtModes[VideoMode].VSyncPolarity; + MsaConfig->Dmt.HFrontPorch = XDptx_DmtModes[VideoMode].HFrontPorch; + MsaConfig->Dmt.HSyncPulseWidth = + XDptx_DmtModes[VideoMode].HSyncPulseWidth; + MsaConfig->Dmt.HBackPorch = XDptx_DmtModes[VideoMode].HBackPorch; + MsaConfig->Dmt.VFrontPorch = XDptx_DmtModes[VideoMode].VFrontPorch; + MsaConfig->Dmt.VSyncPulseWidth = + XDptx_DmtModes[VideoMode].VSyncPulseWidth; + MsaConfig->Dmt.VBackPorch = XDptx_DmtModes[VideoMode].VBackPorch; /* Calculate the rest of the MSA values. */ - XDptx_CfgMsaRecalculate(InstancePtr); + XDptx_CfgMsaRecalculate(InstancePtr, Stream); } /******************************************************************************/ @@ -280,9 +304,10 @@ void XDptx_CfgMsaUseStandardVideoMode(XDptx *InstancePtr, * of the sink monitor. * *******************************************************************************/ -void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr) +void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr, u8 Stream) { - XDptx_MainStreamAttributes *MsaConfig = &InstancePtr->MsaConfig; + XDptx_MainStreamAttributes *MsaConfig = + &InstancePtr->MsaConfig[Stream - 1]; u8 *Ptm = &InstancePtr->RxConfig.Edid[XDPTX_EDID_PTM]; /* Verify arguments. */ @@ -303,60 +328,52 @@ void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr) XDPTX_EDID_DTD_XRES_XBLANK_U4_XBLANK_MASK) << 8) | Ptm[XDPTX_EDID_DTD_VBLANK_LSB]; - MsaConfig->MVid = ((Ptm[XDPTX_EDID_DTD_PIXEL_CLK_KHZ_MSB] << 8) | - Ptm[XDPTX_EDID_DTD_PIXEL_CLK_KHZ_LSB]) * 10; - - MsaConfig->HSyncPulseWidth = - (((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & - XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HSPW_MASK) >> - XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HSPW_SHIFT) << 8) | - Ptm[XDPTX_EDID_DTD_HSPW_LSB]; - - MsaConfig->VSyncPulseWidth = - ((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & - XDPTX_EDID_DTD_XFPORCH_XSPW_U2_VSPW_MASK) << 8) | - (Ptm[XDPTX_EDID_DTD_VFPORCH_VSPW_L4] & - XDPTX_EDID_DTD_VFPORCH_VSPW_L4_VSPW_MASK); - - MsaConfig->HResolution = + MsaConfig->Dmt.HResolution = (((Ptm[XDPTX_EDID_DTD_HRES_HBLANK_U4] & XDPTX_EDID_DTD_XRES_XBLANK_U4_XRES_MASK) >> XDPTX_EDID_DTD_XRES_XBLANK_U4_XRES_SHIFT) << 8) | Ptm[XDPTX_EDID_DTD_HRES_LSB]; - MsaConfig->VResolution = (((Ptm[XDPTX_EDID_DTD_VRES_VBLANK_U4] & + MsaConfig->Dmt.VResolution = (((Ptm[XDPTX_EDID_DTD_VRES_VBLANK_U4] & XDPTX_EDID_DTD_XRES_XBLANK_U4_XRES_MASK) >> XDPTX_EDID_DTD_XRES_XBLANK_U4_XRES_SHIFT) << 8) | Ptm[XDPTX_EDID_DTD_VRES_LSB]; - MsaConfig->VFrontPorch = (((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & + MsaConfig->Dmt.PixelClkKhz = ((Ptm[XDPTX_EDID_DTD_PIXEL_CLK_KHZ_MSB] << + 8) | Ptm[XDPTX_EDID_DTD_PIXEL_CLK_KHZ_LSB]) * 10; + + MsaConfig->Dmt.HFrontPorch = (((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & + XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HFPORCH_MASK) >> + XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HFPORCH_SHIFT) << 8) | + Ptm[XDPTX_EDID_DTD_HFPORCH_LSB]; + + MsaConfig->Dmt.HSyncPulseWidth = + (((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & + XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HSPW_MASK) >> + XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HSPW_SHIFT) << 8) | + Ptm[XDPTX_EDID_DTD_HSPW_LSB]; + + MsaConfig->Dmt.VFrontPorch = (((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & XDPTX_EDID_DTD_XFPORCH_XSPW_U2_VFPORCH_MASK) >> XDPTX_EDID_DTD_XFPORCH_XSPW_U2_VFPORCH_SHIFT) << 8) | ((Ptm[XDPTX_EDID_DTD_VFPORCH_VSPW_L4] & XDPTX_EDID_DTD_VFPORCH_VSPW_L4_VFPORCH_MASK) >> XDPTX_EDID_DTD_VFPORCH_VSPW_L4_VFPORCH_SHIFT); - MsaConfig->HFrontPorch = (((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & - XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HFPORCH_MASK) >> - XDPTX_EDID_DTD_XFPORCH_XSPW_U2_HFPORCH_SHIFT) << 8) | - Ptm[XDPTX_EDID_DTD_HFPORCH_LSB]; + MsaConfig->Dmt.VSyncPulseWidth = + ((Ptm[XDPTX_EDID_DTD_XFPORCH_XSPW_U2] & + XDPTX_EDID_DTD_XFPORCH_XSPW_U2_VSPW_MASK) << 8) | + (Ptm[XDPTX_EDID_DTD_VFPORCH_VSPW_L4] & + XDPTX_EDID_DTD_VFPORCH_VSPW_L4_VSPW_MASK); - MsaConfig->HSyncPolarity = (Ptm[XDPTX_EDID_DTD_SIGNAL] & - XDPTX_EDID_DTD_SIGNAL_HPOLARITY_MASK) >> - XDPTX_EDID_DTD_SIGNAL_HPOLARITY_SHIFT; + MsaConfig->Dmt.HBackPorch = HBlank - (MsaConfig->Dmt.HFrontPorch + + MsaConfig->Dmt.HSyncPulseWidth); - MsaConfig->VSyncPolarity = Ptm[XDPTX_EDID_DTD_SIGNAL] & - XDPTX_EDID_DTD_SIGNAL_VPOLARITY_MASK >> - XDPTX_EDID_DTD_SIGNAL_VPOLARITY_SHIFT; - - MsaConfig->VBackPorch = VBlank - - (MsaConfig->VFrontPorch + MsaConfig->VSyncPulseWidth); - - MsaConfig->HBackPorch = HBlank - - (MsaConfig->HFrontPorch + MsaConfig->HSyncPulseWidth); + MsaConfig->Dmt.VBackPorch = VBlank - (MsaConfig->Dmt.VFrontPorch + + MsaConfig->Dmt.VSyncPulseWidth); /* Calculate the rest of the MSA values. */ - XDptx_CfgMsaRecalculate(InstancePtr); + XDptx_CfgMsaRecalculate(InstancePtr, Stream); } /******************************************************************************/ @@ -366,7 +383,7 @@ void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr) * attributes, the rest of the attributes may be derived. The minimal required * main stream attributes that must be contained in the MsaConfigCustom * structure are: - * - MVid + * - Pixel clock (in KHz) * - Horizontal sync polarity * - Vertical sync polarity * - Horizontal sync pulse width @@ -386,14 +403,15 @@ void XDptx_CfgMsaUseEdidPreferredTiming(XDptx *InstancePtr) * * @return None. * - * @note The InstancePtr-> MsaConfig structure is modified with the new + * @note The InstancePtr->MsaConfig structure is modified with the new * values. * *******************************************************************************/ -void XDptx_CfgMsaUseCustom(XDptx *InstancePtr, +void XDptx_CfgMsaUseCustom(XDptx *InstancePtr, u8 Stream, XDptx_MainStreamAttributes *MsaConfigCustom, u8 Recalculate) { - XDptx_MainStreamAttributes *MsaConfig = &InstancePtr->MsaConfig; + XDptx_MainStreamAttributes *MsaConfig = + &InstancePtr->MsaConfig[Stream - 1]; /* Verify arguments. */ Xil_AssertVoid(InstancePtr != NULL); @@ -401,22 +419,21 @@ void XDptx_CfgMsaUseCustom(XDptx *InstancePtr, Xil_AssertVoid(MsaConfigCustom != NULL); /* Copy the MSA values from the user configuration structure. */ - MsaConfig->MVid = MsaConfigCustom->MVid; - MsaConfig->HSyncPolarity = MsaConfigCustom->HSyncPolarity; - MsaConfig->VSyncPolarity = MsaConfigCustom->VSyncPolarity; - MsaConfig->HSyncPulseWidth = MsaConfigCustom->HSyncPulseWidth; - MsaConfig->VSyncPulseWidth = MsaConfigCustom->VSyncPulseWidth; - MsaConfig->HResolution = MsaConfigCustom->HResolution; - MsaConfig->VResolution = MsaConfigCustom->VResolution; - - MsaConfig->VBackPorch = MsaConfigCustom->VBackPorch; - MsaConfig->VFrontPorch = MsaConfigCustom->VFrontPorch; - MsaConfig->HBackPorch = MsaConfigCustom->HBackPorch; - MsaConfig->HFrontPorch = MsaConfigCustom->HFrontPorch; + MsaConfig->Dmt.HResolution = MsaConfigCustom->Dmt.HResolution; + MsaConfig->Dmt.VResolution = MsaConfigCustom->Dmt.VResolution; + MsaConfig->Dmt.PixelClkKhz = MsaConfigCustom->Dmt.PixelClkKhz; + MsaConfig->Dmt.HSyncPolarity = MsaConfigCustom->Dmt.HSyncPolarity; + MsaConfig->Dmt.VSyncPolarity = MsaConfigCustom->Dmt.VSyncPolarity; + MsaConfig->Dmt.HFrontPorch = MsaConfigCustom->Dmt.HFrontPorch; + MsaConfig->Dmt.HSyncPulseWidth = MsaConfigCustom->Dmt.HSyncPulseWidth; + MsaConfig->Dmt.HBackPorch = MsaConfigCustom->Dmt.HBackPorch; + MsaConfig->Dmt.VFrontPorch = MsaConfigCustom->Dmt.VFrontPorch; + MsaConfig->Dmt.VSyncPulseWidth = MsaConfigCustom->Dmt.VSyncPulseWidth; + MsaConfig->Dmt.VBackPorch = MsaConfigCustom->Dmt.VBackPorch; if (Recalculate) { /* Calculate the rest of the MSA values. */ - XDptx_CfgMsaRecalculate(InstancePtr); + XDptx_CfgMsaRecalculate(InstancePtr, Stream); } else { /* Use the custom values for the rest. */ @@ -449,7 +466,7 @@ void XDptx_CfgMsaUseCustom(XDptx *InstancePtr, * value. * *******************************************************************************/ -void XDptx_CfgMsaSetBpc(XDptx *InstancePtr, u8 BitsPerColor) +void XDptx_CfgMsaSetBpc(XDptx *InstancePtr, u8 Stream, u8 BitsPerColor) { /* Verify arguments. */ Xil_AssertVoid(InstancePtr != NULL); @@ -457,10 +474,10 @@ void XDptx_CfgMsaSetBpc(XDptx *InstancePtr, u8 BitsPerColor) (BitsPerColor == 10) || (BitsPerColor == 12) || (BitsPerColor == 16)); - InstancePtr->MsaConfig.BitsPerColor = BitsPerColor; + InstancePtr->MsaConfig[Stream - 1].BitsPerColor = BitsPerColor; /* Calculate the rest of the MSA values. */ - XDptx_CfgMsaRecalculate(InstancePtr); + XDptx_CfgMsaRecalculate(InstancePtr, Stream); } /******************************************************************************/ @@ -476,15 +493,15 @@ void XDptx_CfgMsaSetBpc(XDptx *InstancePtr, u8 BitsPerColor) * @note None. * *******************************************************************************/ -void XDptx_SetVideoMode(XDptx *InstancePtr) +void XDptx_SetVideoMode(XDptx *InstancePtr, u8 Stream) { /* Verify arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); - Xil_AssertVoid(&InstancePtr->MsaConfig != NULL); + Xil_AssertVoid(&InstancePtr->MsaConfig[Stream - 1] != NULL); - XDptx_ClearMsaValues(InstancePtr); - XDptx_SetMsaValues(InstancePtr, &InstancePtr->MsaConfig); + XDptx_ClearMsaValues(InstancePtr, Stream); + XDptx_SetMsaValues(InstancePtr, Stream); } /******************************************************************************/ @@ -499,29 +516,53 @@ void XDptx_SetVideoMode(XDptx *InstancePtr) * @note None. * *******************************************************************************/ -static void XDptx_ClearMsaValues(XDptx *InstancePtr) +void XDptx_ClearMsaValues(XDptx *InstancePtr, u8 Stream) { XDptx_Config *Config = &InstancePtr->Config; + u32 StreamOffset[4] = {0, XDPTX_STREAM2_MSA_START_OFFSET, + XDPTX_STREAM3_MSA_START_OFFSET, XDPTX_STREAM4_MSA_START_OFFSET}; - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HTOTAL, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VTOTAL, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_POLARITY, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSWIDTH, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSWIDTH, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HRES, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VRES, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSTART, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSTART, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC0, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC1, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_TU_SIZE, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_PIXEL_WIDTH, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_DATA_COUNT_PER_LANE, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_M_VID, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_N_VID, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MIN_BYTES_PER_TU, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_FRAC_BYTES_PER_TU, 0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_INIT_WAIT, 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HTOTAL + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VTOTAL + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_POLARITY + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSWIDTH + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSWIDTH + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HRES + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VRES + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSTART + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSTART + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC0 + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC1 + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_PIXEL_WIDTH + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_DATA_COUNT_PER_LANE + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_M_VID + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_N_VID + + StreamOffset[Stream - 1], 0); + + + XDptx_WriteReg(Config->BaseAddr, XDPTX_STREAM0 + (Stream - 1) * 4, 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_TU_SIZE + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MIN_BYTES_PER_TU + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_FRAC_BYTES_PER_TU + + StreamOffset[Stream - 1], 0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_INIT_WAIT + + StreamOffset[Stream - 1], 0); } /******************************************************************************/ @@ -531,61 +572,134 @@ static void XDptx_ClearMsaValues(XDptx *InstancePtr) * structure. * * @param InstancePtr is a pointer to the XDptx instance. - * @param MsaConfig is a pointer to the main stream attributes - * configuration structure. * * @return None. * * @note None. * *******************************************************************************/ -static void XDptx_SetMsaValues(XDptx *InstancePtr, - XDptx_MainStreamAttributes *MsaConfig) +void XDptx_SetMsaValues(XDptx *InstancePtr, u8 Stream) { XDptx_Config *Config = &InstancePtr->Config; + XDptx_MainStreamAttributes *MsaConfig = + &InstancePtr->MsaConfig[Stream - 1]; + u32 StreamOffset[4] = {0, XDPTX_STREAM2_MSA_START_OFFSET, + XDPTX_STREAM3_MSA_START_OFFSET, XDPTX_STREAM4_MSA_START_OFFSET}; /* Set the main stream attributes to the associated DisplayPort TX core * registers. */ - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HTOTAL, - MsaConfig->HClkTotal); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VTOTAL, - MsaConfig->VClkTotal); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_POLARITY, - MsaConfig->HSyncPolarity | (MsaConfig->VSyncPolarity << + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HTOTAL + + StreamOffset[Stream - 1], MsaConfig->HClkTotal); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VTOTAL + + StreamOffset[Stream - 1], MsaConfig->VClkTotal); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_POLARITY + + StreamOffset[Stream - 1], MsaConfig->Dmt.HSyncPolarity | + (MsaConfig->Dmt.VSyncPolarity << XDPTX_MAIN_STREAMX_POLARITY_VSYNC_POL_SHIFT)); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSWIDTH, - MsaConfig->HSyncPulseWidth); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSWIDTH, - MsaConfig->VSyncPulseWidth); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HRES, - MsaConfig->HResolution); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VRES, - MsaConfig->VResolution); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSTART, - MsaConfig->HStart); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSTART, - MsaConfig->VStart); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC0, - MsaConfig->Misc0); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC1, - MsaConfig->Misc1); - XDptx_WriteReg(Config->BaseAddr, XDPTX_M_VID, - MsaConfig->MVid); - XDptx_WriteReg(Config->BaseAddr, XDPTX_N_VID, - MsaConfig->NVid); - XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_PIXEL_WIDTH, - MsaConfig->UserPixelWidth); - XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_DATA_COUNT_PER_LANE, - MsaConfig->DataPerLane); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSWIDTH + + StreamOffset[Stream - 1], MsaConfig->Dmt.HSyncPulseWidth); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSWIDTH + + StreamOffset[Stream - 1], MsaConfig->Dmt.VSyncPulseWidth); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HRES + + StreamOffset[Stream - 1], MsaConfig->Dmt.HResolution); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VRES + + StreamOffset[Stream - 1], MsaConfig->Dmt.VResolution); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_HSTART + + StreamOffset[Stream - 1], MsaConfig->HStart); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_VSTART + + StreamOffset[Stream - 1], MsaConfig->VStart); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC0 + + StreamOffset[Stream - 1], MsaConfig->Misc0); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MAIN_STREAM_MISC1 + + StreamOffset[Stream - 1], MsaConfig->Misc1); + XDptx_WriteReg(Config->BaseAddr, XDPTX_M_VID + + StreamOffset[Stream - 1], MsaConfig->Dmt.PixelClkKhz); + XDptx_WriteReg(Config->BaseAddr, XDPTX_N_VID + + StreamOffset[Stream - 1], MsaConfig->NVid); + XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_PIXEL_WIDTH + + StreamOffset[Stream - 1], MsaConfig->UserPixelWidth); + XDptx_WriteReg(Config->BaseAddr, XDPTX_USER_DATA_COUNT_PER_LANE + + StreamOffset[Stream - 1], MsaConfig->DataPerLane); /* Set the transfer unit values to the associated DisplayPort TX core - * registers. */ - XDptx_WriteReg(Config->BaseAddr, XDPTX_TU_SIZE, - MsaConfig->TransferUnitSize); - XDptx_WriteReg(Config->BaseAddr, XDPTX_MIN_BYTES_PER_TU, - MsaConfig->AvgBytesPerTU / 1000); - XDptx_WriteReg(Config->BaseAddr, XDPTX_FRAC_BYTES_PER_TU, - MsaConfig->AvgBytesPerTU % 1000); - XDptx_WriteReg(Config->BaseAddr, XDPTX_INIT_WAIT, - MsaConfig->InitWait); + * registers. */ + if (InstancePtr->MstEnable == 1) { + XDptx_WriteReg(Config->BaseAddr, + XDPTX_STREAM0 + (Stream - 1) * 4, + ((MsaConfig->AvgBytesPerTU / 1000) << 16) | + (MsaConfig->AvgBytesPerTU % 1000)); + } + XDptx_WriteReg(Config->BaseAddr, XDPTX_TU_SIZE + + StreamOffset[Stream - 1], MsaConfig->TransferUnitSize); + XDptx_WriteReg(Config->BaseAddr, XDPTX_MIN_BYTES_PER_TU + + StreamOffset[Stream - 1], MsaConfig->AvgBytesPerTU / 1000); + XDptx_WriteReg(Config->BaseAddr, XDPTX_FRAC_BYTES_PER_TU + + StreamOffset[Stream - 1], MsaConfig->AvgBytesPerTU % 1000); + XDptx_WriteReg(Config->BaseAddr, XDPTX_INIT_WAIT + + StreamOffset[Stream - 1], MsaConfig->InitWait); +} + +static void XDptx_CalculateTs(XDptx *InstancePtr, u8 Stream, u8 BitsPerPixel) +{ + XDptx_MainStreamAttributes *MsaConfig = + &InstancePtr->MsaConfig[Stream - 1]; + XDptx_LinkConfig *LinkConfig = &InstancePtr->LinkConfig; + double PeakPixelBw; + u32 LinkBw; + double Average_StreamSymbolTimeSlotsPerMTP; + double Target_Average_StreamSymbolTimeSlotsPerMTP; + double MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP; + u32 TsInt; + u32 TsFrac; + + PeakPixelBw = ((double)MsaConfig->Dmt.PixelClkKhz / 1000) * + ((double)BitsPerPixel / 8); + LinkBw = (LinkConfig->LaneCount * LinkConfig->LinkRate * 27); + + /* Calculate the payload bandiwdth number (PBN). */ + MsaConfig->MstPbn = ceil(1.006 * PeakPixelBw * ((double)64 / 54)); + + /* Calculate the average stream symbol time slots per MTP. */ + Average_StreamSymbolTimeSlotsPerMTP = (64.0 * PeakPixelBw / LinkBw); + MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP = (54.0 * + ((double)MsaConfig->MstPbn / LinkBw)); + + /* The target value to be found needs to follow the condition: + * Average_StreamSymbolTimeSlotsPerMTP <= + * Target_Average_StreamSymbolTimeSlotsPerMTP + * >= MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP + * Obtain the greatest target value that satisfies the above condition + * and still a multiple of 1/TsFrac_Denominator. + * Note: TsFrac_Denominator = 8. */ + /* Round down. */ + Target_Average_StreamSymbolTimeSlotsPerMTP = + (u32)Average_StreamSymbolTimeSlotsPerMTP; + /* Find the greatest multiple that is less than the maximum. */ + Target_Average_StreamSymbolTimeSlotsPerMTP += ((1.0 / 8.0) * (u32)(8.0 * + (MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP - + Target_Average_StreamSymbolTimeSlotsPerMTP))); + + /* Determine the integer and the fractional part of the number of time + * slots that will be allocated for the stream. */ + TsInt = Target_Average_StreamSymbolTimeSlotsPerMTP; + TsFrac = (((double)Target_Average_StreamSymbolTimeSlotsPerMTP * 1000) - + (TsInt * 1000)); + + /* Store TsInt and TsFrac in AvgBytesPerTU. */ + MsaConfig->AvgBytesPerTU = TsInt * 1000 + TsFrac; + + /* Set the number of time slots to allocate for this stream. */ + MsaConfig->TransferUnitSize = TsInt; + if (TsFrac != 0) { + /* Round up. */ + MsaConfig->TransferUnitSize++; + } + if ((MsaConfig->TransferUnitSize % 2) != 0) { + /* Set to an even boundary. */ + MsaConfig->TransferUnitSize++; + } + + /* Determine the PBN for the stream. */ + MsaConfig->MstPbn = MsaConfig->TransferUnitSize * + (LinkConfig->LaneCount * LinkConfig->LinkRate / 2); } diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_vidmodetable.c b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_vidmodetable.c index 5a1b8033..406815b8 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_vidmodetable.c +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_vidmodetable.c @@ -63,7 +63,7 @@ * 3) Horizontal resolution (pixels) * 4) Vertical resolution (lines) * 5) Pixel clock (KHz) - * 6) Scan (0=non-interlaced|1=interlaced) + * 6) Interlaced (0=non-interlaced|1=interlaced) * 7) Horizontal sync polarity (0=positive|1=negative) * 8) Vertical sync polarity (0=positive|1=negative) * 9) Horizontal front porch (pixels)