dptx: Optimized burst AUX writes.

Use burst writes when possible.
- Detached writing the voltage swing and preemphasis settings to the core from
writing to the sink using AUX writes. Now, a pointer to an array is taken as an
argument and the array is modified with the data to write over AUX. This allows
preparation of a burst write when the voltage swing and preemphasis settings can
be written at the same time as another adjacent DPCD access.

The scrambler is now enabled/disabled while writing the training patterns.

Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
This commit is contained in:
Andrei-Liviu Simion 2015-01-07 12:47:26 -08:00 committed by Nava kishore Manne
parent 431de2ef88
commit 29af856045

View file

@ -122,7 +122,7 @@ static XDptx_TrainingState XDptx_TrainingStateAdjustLaneCount(
static u32 XDptx_GetLaneStatusAdjReqs(XDptx *InstancePtr); static u32 XDptx_GetLaneStatusAdjReqs(XDptx *InstancePtr);
static u32 XDptx_CheckClockRecovery(XDptx *InstancePtr, u8 LaneCount); static u32 XDptx_CheckClockRecovery(XDptx *InstancePtr, u8 LaneCount);
static u32 XDptx_CheckChannelEqualization(XDptx *InstancePtr, u8 LaneCount); static u32 XDptx_CheckChannelEqualization(XDptx *InstancePtr, u8 LaneCount);
static u32 XDptx_SetVswingPreemp(XDptx *InstancePtr); static void XDptx_SetVswingPreemp(XDptx *InstancePtr, u8 *AuxData);
static u32 XDptx_AdjVswingPreemp(XDptx *InstancePtr); static u32 XDptx_AdjVswingPreemp(XDptx *InstancePtr);
static u32 XDptx_SetTrainingPattern(XDptx *InstancePtr, u32 Pattern); static u32 XDptx_SetTrainingPattern(XDptx *InstancePtr, u32 Pattern);
static u32 XDptx_GetTrainingDelay(XDptx *InstancePtr, static u32 XDptx_GetTrainingDelay(XDptx *InstancePtr,
@ -1407,12 +1407,6 @@ static u32 XDptx_RunTraining(XDptx *InstancePtr)
u32 Status; u32 Status;
XDptx_TrainingState TrainingState = XDPTX_TS_CLOCK_RECOVERY; XDptx_TrainingState TrainingState = XDPTX_TS_CLOCK_RECOVERY;
/* Disable scrambler. */
Status = XDptx_SetScrambler(InstancePtr, 0);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
while (1) { while (1) {
switch (TrainingState) { switch (TrainingState) {
case XDPTX_TS_CLOCK_RECOVERY: case XDPTX_TS_CLOCK_RECOVERY:
@ -1449,19 +1443,13 @@ static u32 XDptx_RunTraining(XDptx *InstancePtr)
} }
} }
/* Turn off the training pattern. */ /* Turn off the training pattern and enable scrambler. */
Status = XDptx_SetTrainingPattern(InstancePtr, Status = XDptx_SetTrainingPattern(InstancePtr,
XDPTX_TRAINING_PATTERN_SET_OFF); XDPTX_TRAINING_PATTERN_SET_OFF);
if (Status != XST_SUCCESS) { if (Status != XST_SUCCESS) {
return XST_FAILURE; return XST_FAILURE;
} }
/* Enable scrambler. */
Status = XDptx_SetScrambler(InstancePtr, 1);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Final status check. */ /* Final status check. */
Status = XDptx_CheckLinkStatus(InstancePtr, Status = XDptx_CheckLinkStatus(InstancePtr,
InstancePtr->LinkConfig.LaneCount); InstancePtr->LinkConfig.LaneCount);
@ -1522,20 +1510,16 @@ static XDptx_TrainingState XDptx_TrainingStateClockRecovery(XDptx *InstancePtr)
/* Start CRLock. */ /* Start CRLock. */
/* Transmit training pattern 1. */ /* Transmit training pattern 1. */
/* Disable the scrambler. */
/* Start from minimal voltage swing and pre-emphasis levels. */
InstancePtr->LinkConfig.VsLevel = 0;
InstancePtr->LinkConfig.PeLevel = 0;
Status = XDptx_SetTrainingPattern(InstancePtr, Status = XDptx_SetTrainingPattern(InstancePtr,
XDPTX_TRAINING_PATTERN_SET_TP1); XDPTX_TRAINING_PATTERN_SET_TP1);
if (Status != XST_SUCCESS) { if (Status != XST_SUCCESS) {
return XDPTX_TS_FAILURE; return XDPTX_TS_FAILURE;
} }
/* Start from minimal voltage swing and pre-emphasis levels. */
LinkConfig->VsLevel = 0;
LinkConfig->PeLevel = 0;
Status = XDptx_SetVswingPreemp(InstancePtr);
if (Status != XST_SUCCESS) {
return XDPTX_TS_FAILURE;
}
while (1) { while (1) {
/* Wait delay specified in TRAINING_AUX_RD_INTERVAL. */ /* Wait delay specified in TRAINING_AUX_RD_INTERVAL. */
XDptx_WaitUs(InstancePtr, DelayUs); XDptx_WaitUs(InstancePtr, DelayUs);
@ -1635,12 +1619,7 @@ static XDptx_TrainingState XDptx_TrainingStateChannelEqualization(
/* Start channel equalization. */ /* Start channel equalization. */
/* Write the current drive settings to the RX device. */ /* Write the current drive settings. */
Status = XDptx_SetVswingPreemp(InstancePtr);
if (Status != XST_SUCCESS) {
return XDPTX_TS_FAILURE;
}
/* Transmit training pattern 2/3. */ /* Transmit training pattern 2/3. */
if (InstancePtr->RxConfig.DpcdRxCapsField[XDPTX_DPCD_MAX_LANE_COUNT] & if (InstancePtr->RxConfig.DpcdRxCapsField[XDPTX_DPCD_MAX_LANE_COUNT] &
XDPTX_DPCD_TPS3_SUPPORT_MASK) { XDPTX_DPCD_TPS3_SUPPORT_MASK) {
@ -2022,11 +2001,10 @@ static u32 XDptx_CheckChannelEqualization(XDptx *InstancePtr, u8 LaneCount)
* represent the DisplayPort pre-emphasis levels. * represent the DisplayPort pre-emphasis levels.
* *
*******************************************************************************/ *******************************************************************************/
static u32 XDptx_SetVswingPreemp(XDptx *InstancePtr) static void XDptx_SetVswingPreemp(XDptx *InstancePtr, u8 *AuxData)
{ {
u32 Status; u32 Status;
u8 Data; u8 Data;
u8 AuxData[4];
u8 Index; u8 Index;
u8 VsLevelRx = InstancePtr->LinkConfig.VsLevel; u8 VsLevelRx = InstancePtr->LinkConfig.VsLevel;
u8 PeLevelRx = InstancePtr->LinkConfig.PeLevel; u8 PeLevelRx = InstancePtr->LinkConfig.PeLevel;
@ -2065,7 +2043,7 @@ static u32 XDptx_SetVswingPreemp(XDptx *InstancePtr)
if (PeLevelRx == XDPTX_MAXIMUM_PE_LEVEL) { if (PeLevelRx == XDPTX_MAXIMUM_PE_LEVEL) {
Data |= XDPTX_DPCD_TRAINING_LANEX_SET_MAX_PE_MASK; Data |= XDPTX_DPCD_TRAINING_LANEX_SET_MAX_PE_MASK;
} }
memset(AuxData, Data, InstancePtr->LinkConfig.LaneCount); memset(AuxData, Data, 4);
for (Index = 0; Index < InstancePtr->LinkConfig.LaneCount; Index++) { for (Index = 0; Index < InstancePtr->LinkConfig.LaneCount; Index++) {
/* Disable pre-cursor levels. */ /* Disable pre-cursor levels. */
@ -2080,16 +2058,6 @@ static u32 XDptx_SetVswingPreemp(XDptx *InstancePtr)
XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDptx_WriteReg(InstancePtr->Config.BaseAddr,
XDPTX_PHY_POSTCURSOR_LANE_0 + 4 * Index, PeLevel); XDPTX_PHY_POSTCURSOR_LANE_0 + 4 * Index, PeLevel);
} }
/* Write the voltage swing and pre-emphasis levels for each lane to the
* RX device. */
Status = XDptx_AuxWrite(InstancePtr, XDPTX_DPCD_TRAINING_LANE0_SET,
InstancePtr->LinkConfig.LaneCount, AuxData);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
} }
/******************************************************************************/ /******************************************************************************/
@ -2112,6 +2080,7 @@ static u32 XDptx_AdjVswingPreemp(XDptx *InstancePtr)
u8 Index; u8 Index;
u8 VsLevelAdjReq[4]; u8 VsLevelAdjReq[4];
u8 PeLevelAdjReq[4]; u8 PeLevelAdjReq[4];
u8 AuxData[4];
u8 *AdjReqs = &InstancePtr->RxConfig.LaneStatusAdjReqs[4]; u8 *AdjReqs = &InstancePtr->RxConfig.LaneStatusAdjReqs[4];
/* Analyze the adjustment requests for changes in voltage swing and /* Analyze the adjustment requests for changes in voltage swing and
@ -2163,7 +2132,11 @@ static u32 XDptx_AdjVswingPreemp(XDptx *InstancePtr)
/* Make the adjustments to both the DisplayPort TX core and the RX /* Make the adjustments to both the DisplayPort TX core and the RX
* device. */ * device. */
Status = XDptx_SetVswingPreemp(InstancePtr); XDptx_SetVswingPreemp(InstancePtr, AuxData);
/* Write the voltage swing and pre-emphasis levels for each lane to the
* RX device. */
Status = XDptx_AuxWrite(InstancePtr, XDPTX_DPCD_TRAINING_LANE0_SET,
4, AuxData);
if (Status != XST_SUCCESS) { if (Status != XST_SUCCESS) {
return XST_FAILURE; return XST_FAILURE;
} }
@ -2193,22 +2166,40 @@ static u32 XDptx_AdjVswingPreemp(XDptx *InstancePtr)
static u32 XDptx_SetTrainingPattern(XDptx *InstancePtr, u32 Pattern) static u32 XDptx_SetTrainingPattern(XDptx *InstancePtr, u32 Pattern)
{ {
u32 Status; u32 Status;
u8 RegVal; u8 AuxData[5];
/* Write to the DisplayPort TX core. */ /* Write to the DisplayPort TX core. */
XDptx_WriteReg(InstancePtr->Config.BaseAddr, XDptx_WriteReg(InstancePtr->Config.BaseAddr,
XDPTX_TRAINING_PATTERN_SET, Pattern); XDPTX_TRAINING_PATTERN_SET, Pattern);
/* Preserve the current RX device settings. */ AuxData[0] = Pattern;
Status = XDptx_AuxRead(InstancePtr, XDPTX_DPCD_TP_SET, 1, &RegVal);
RegVal &= ~XDPTX_DPCD_TP_SEL_MASK; /* Write scrambler disable to the DisplayPort TX core. */
RegVal |= (Pattern & XDPTX_DPCD_TP_SEL_MASK); switch (Pattern) {
if (Status != XST_SUCCESS) { case XDPTX_TRAINING_PATTERN_SET_OFF:
return XST_FAILURE; XDptx_WriteReg(InstancePtr->Config.BaseAddr,
XDPTX_SCRAMBLING_DISABLE, 0);
InstancePtr->LinkConfig.ScramblerEn = 1;
break;
case XDPTX_TRAINING_PATTERN_SET_TP1:
case XDPTX_TRAINING_PATTERN_SET_TP2:
case XDPTX_TRAINING_PATTERN_SET_TP3:
AuxData[0] |= XDPTX_DPCD_TP_SET_SCRAMB_DIS_MASK;
XDptx_WriteReg(InstancePtr->Config.BaseAddr,
XDPTX_SCRAMBLING_DISABLE, 1);
InstancePtr->LinkConfig.ScramblerEn = 0;
break;
default:
break;
} }
/* Write to the RX device. */ /* Make the adjustments to both the DisplayPort TX core and the RX
Status = XDptx_AuxWrite(InstancePtr, XDPTX_DPCD_TP_SET, 1, &RegVal); * device. */
XDptx_SetVswingPreemp(InstancePtr, &AuxData[1]);
/* Write the voltage swing and pre-emphasis levels for each lane to the
* RX device. */
Status = XDptx_AuxWrite(InstancePtr, XDPTX_DPCD_TP_SET,
5, AuxData);
if (Status != XST_SUCCESS) { if (Status != XST_SUCCESS) {
return XST_FAILURE; return XST_FAILURE;
} }