dptx: Added functions that reorder the sink numbering of the topology.
Added functionality that reorders the sink list such that topologies containing tiled display(s) will have the contained sinks reordered in a consistent manner. The need for such functionality exists because not all tiled displays will have the same internal topologies. It was observed that two 4k2k MST based monitors (tiled display, 2 sinks) from different manufacturers would have the left and right images swapped using identical stream-to-sink mappings. Thus, the need to obtain the tiled display topology information of all sinks and their relative tile location is required to send the correct stream to the desired sink. Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
This commit is contained in:
parent
69fe13cc3e
commit
fe2c47e815
2 changed files with 117 additions and 1 deletions
|
@ -827,10 +827,12 @@ void XDptx_SetStreamSinkRad(XDptx *InstancePtr, u8 Stream, u8 LinkCountTotal,
|
|||
u8 *RelativeAddress);
|
||||
|
||||
/* xdptx_mst.c: Multi-stream transport (MST) functions related to MST topology
|
||||
* discovery. */
|
||||
* discovery and management. */
|
||||
u32 XDptx_DiscoverTopology(XDptx *InstancePtr);
|
||||
u32 XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
|
||||
u8 *RelativeAddress);
|
||||
void XDptx_TopologySwapSinks(XDptx *InstancePtr, u8 Index0, u8 Index1);
|
||||
u32 XDptx_TopologySortSinksByTiling(XDptx *InstancePtr);
|
||||
|
||||
/* xdptx_mst.c: Multi-stream transport (MST) functions for communicating
|
||||
* with downstream DisplayPort devices. */
|
||||
|
|
|
@ -162,6 +162,7 @@ static u32 XDptx_Transaction2MsgFormat(u8 *Transaction, XDptx_SidebandMsg *Msg);
|
|||
static u8 XDptx_Crc4CalculateHeader(XDptx_SidebandMsgHeader *Header);
|
||||
static u8 XDptx_Crc8CalculateBody(XDptx_SidebandMsgBody *Body);
|
||||
static u8 XDptx_CrcCalculate(const u8 *Data, u32 NumberOfBits, u8 Polynomial);
|
||||
static u32 XDptx_IsSameTileDisplay(u8 *DispIdSecTile0, u8 *DispIdSecTile1);
|
||||
|
||||
/**************************** Variable Definitions ****************************/
|
||||
|
||||
|
@ -706,6 +707,93 @@ u32 XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
|
|||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
void XDptx_TopologySwapSinks(XDptx *InstancePtr, u8 Index0, u8 Index1)
|
||||
{
|
||||
XDptx_TopologyNode *TmpSink = InstancePtr->Topology.SinkList[Index0];
|
||||
|
||||
InstancePtr->Topology.SinkList[Index0] =
|
||||
InstancePtr->Topology.SinkList[Index1];
|
||||
|
||||
InstancePtr->Topology.SinkList[Index1] = TmpSink;
|
||||
}
|
||||
|
||||
u32 XDptx_TopologySortSinksByTiling(XDptx *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
XDptx_TopologyNode *CurrSink, *CmpSink;
|
||||
u8 CurrIndex, CmpIndex, NewIndex;
|
||||
u8 CurrEdidExt[128], CmpEdidExt[128];
|
||||
u8 *CurrTdt, *CmpTdt;
|
||||
u8 CurrTileOrder, CmpTileOrder;
|
||||
u8 SameTileDispCount, SameTileDispNum;
|
||||
|
||||
for (CurrIndex = 0; CurrIndex <
|
||||
(InstancePtr->Topology.SinkTotal - 1); CurrIndex++) {
|
||||
CurrSink = InstancePtr->Topology.SinkList[CurrIndex];
|
||||
|
||||
Status = XDptx_GetRemoteTiledDisplayDb(InstancePtr, CurrEdidExt,
|
||||
CurrSink->LinkCountTotal,
|
||||
CurrSink->RelativeAddress, &CurrTdt);
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* No tiled display topology data block exists. */
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Start by using the tiling parameters of the current sink
|
||||
* index. */
|
||||
CurrTileOrder = XDptx_GetDispIdTdtTileOrder(CurrTdt);
|
||||
NewIndex = CurrIndex;
|
||||
SameTileDispCount = 1;
|
||||
SameTileDispNum = XDptx_GetDispIdTdtNumTiles(CurrTdt);
|
||||
|
||||
/* Try to find a sink that is part of the same tiled display,
|
||||
* but has a smaller tile location - the sink with a smaller
|
||||
* tile location should be ordered first in the topology's sink
|
||||
* list. */
|
||||
for (CmpIndex = (CurrIndex + 1);
|
||||
(CmpIndex < InstancePtr->Topology.SinkTotal)
|
||||
&& (SameTileDispCount < SameTileDispNum);
|
||||
CmpIndex++) {
|
||||
CmpSink = InstancePtr->Topology.SinkList[CmpIndex];
|
||||
|
||||
Status = XDptx_GetRemoteTiledDisplayDb(
|
||||
InstancePtr, CmpEdidExt,
|
||||
CmpSink->LinkCountTotal,
|
||||
CmpSink->RelativeAddress, &CmpTdt);
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* No tiled display topology data block. */
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
if (!XDptx_IsSameTileDisplay(CurrTdt, CmpTdt)) {
|
||||
/* The sink under comparison does not belong to
|
||||
* the same tiled display. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Keep track of the sink with a tile location that
|
||||
* should be ordered first out of the remaining sinks
|
||||
* that are part of the same tiled display. */
|
||||
CmpTileOrder = XDptx_GetDispIdTdtTileOrder(CmpTdt);
|
||||
if (CurrTileOrder > CmpTileOrder) {
|
||||
CurrTileOrder = CmpTileOrder;
|
||||
NewIndex = CmpIndex;
|
||||
SameTileDispCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If required, swap the current sink with the sink that is a
|
||||
* part of the same tiled display, but has a smaller tile
|
||||
* location. */
|
||||
if (CurrIndex != NewIndex) {
|
||||
XDptx_TopologySwapSinks(InstancePtr, CurrIndex,
|
||||
NewIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This function performs a remote DisplayPort Configuration Data (DPCD) read
|
||||
|
@ -2801,3 +2889,29 @@ static u8 XDptx_CrcCalculate(const u8 *Data, u32 NumberOfBits, u8 Polynomial)
|
|||
|
||||
return Remainder & 0xFF;
|
||||
}
|
||||
|
||||
static u32 XDptx_IsSameTileDisplay(u8 *TileDisp0, u8 *TileDisp1)
|
||||
{
|
||||
if ((TileDisp0[XDPTX_DISPID_TDT_VENID0] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_VENID0]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_VENID1] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_VENID1]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_VENID2] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_VENID2]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_PCODE0] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_PCODE0]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_PCODE1] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_PCODE1]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_SN0] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_SN0]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_SN1] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_SN1]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_SN2] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_SN2]) ||
|
||||
(TileDisp0[XDPTX_DISPID_TDT_SN3] !=
|
||||
TileDisp1[XDPTX_DISPID_TDT_SN3]) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue