dptx: Improved stack size usage for topology discovery.

Reduced the stack size required by the topology discovery algorithm
significantly.

Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
This commit is contained in:
Andrei-Liviu Simion 2014-09-22 18:39:08 -07:00 committed by Suneel Garapati
parent 9547cbc0a8
commit 414d35c52e
3 changed files with 98 additions and 47 deletions

View file

@ -37,9 +37,6 @@
* Contains a design example using the XDptx driver in multi-stream transport
* (MST) mode.
*
* @note When topology discovery is enabled, the required stack size will
* 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
@ -245,7 +242,13 @@ u32 Dptx_MstExampleRun(XDptx *InstancePtr)
InstancePtr->Topology.NodeTotal = 0;
InstancePtr->Topology.SinkTotal = 0;
XDptx_FindAccessibleDpDevices(InstancePtr, 1, NULL);
Status = XDptx_DiscoverTopology(InstancePtr);
if (Status != XST_SUCCESS) {
xil_printf("!!! A LINK_ADDRESS response from a branch device "
"in the MST topology was not successfully received.\n");
return XST_FAILURE;
}
xil_printf("<<< Find topology DONE; # of sinks found = %d.\n",
InstancePtr->Topology.SinkTotal);

View file

@ -851,7 +851,8 @@ void XDptx_SetStreamSinkRad(XDptx *InstancePtr, u8 Stream, u8 LinkCountTotal,
/* xdptx_mst.c: Multi-stream transport (MST) functions related to MST topology
* discovery. */
void XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
u32 XDptx_DiscoverTopology(XDptx *InstancePtr);
u32 XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
u8 *RelativeAddress);
/* xdptx_mst.c: Multi-stream transport (MST) functions related to MST stream

View file

@ -555,6 +555,36 @@ void XDptx_SetStreamSinkRad(XDptx *InstancePtr, u8 Stream, u8 LinkCountTotal,
* add it to the topology's sink list.
*
* @param InstancePtr is a pointer to the XDptx instance.
*
* @return
* - XST_SUCCESS if the topology discovery is successful.
* - XST_FAILURE otherwise - if sending a LINK_ADDRESS sideband
* message to one of the branch devices in the topology failed.
*
* @note The contents of the InstancePtr->Topology structure will be
* modified.
*
*******************************************************************************/
u32 XDptx_DiscoverTopology(XDptx *InstancePtr)
{
XDptx_SbMsgLinkAddressReplyDeviceInfo DeviceInfo;
u8 RelativeAddress[16];
return XDptx_FindAccessibleDpDevices(InstancePtr, 1, RelativeAddress);
}
/******************************************************************************/
/**
* This function will explore the DisplayPort topology of downstream devices
* starting from the branch device specified by the LinkCountTotal and
* RelativeAddress parameters. It will recursively go through each branch
* device, obtain its information by sending a LINK_ADDRESS sideband message,
* and add this information to the the topology's node table. For each sink
* device connected to a branch's downstream port, this function will obtain
* the details of the sink, add it to the topology's node table, as well as
* add it to the topology's sink list.
*
* @param InstancePtr is a pointer to the XDptx instance.
* @param LinkCountTotal is the total DisplayPort links connecting the
* DisplayPort TX to the current downstream device in the
* recursion.
@ -562,22 +592,25 @@ void XDptx_SetStreamSinkRad(XDptx *InstancePtr, u8 Stream, u8 LinkCountTotal,
* source to the current target DisplayPort device in the
* recursion.
*
* @return None - the recursion will exit from nodes that have an error
* when replying to the LINK_ADDRESS sideband message.
* @return
* - XST_SUCCESS if the topology discovery is successful.
* - XST_FAILURE otherwise - if sending a LINK_ADDRESS sideband
* message to one of the branch devices in the topology failed.
*
* @note The contents of the InstancePtr->Topology structure will be
* modified.
*
*******************************************************************************/
void XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
u32 XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
u8 *RelativeAddress)
{
u32 Status;
u8 Index;
u8 RadIndex;
XDptx_SbMsgLinkAddressReplyDeviceInfo DeviceInfo;
XDptx_SbMsgLinkAddressReplyPortDetail *PortDetails;
u8 NumDownBranches = 0;
u8 OverallFailures = 0;
XDptx_Topology *Topology;
XDptx_SbMsgLinkAddressReplyPortDetail *PortDetails;
static XDptx_SbMsgLinkAddressReplyDeviceInfo DeviceInfo;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
@ -592,9 +625,9 @@ void XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
Status = XDptx_SendSbMsgLinkAddress(InstancePtr, LinkCountTotal,
RelativeAddress, &DeviceInfo);
if (Status != XST_SUCCESS) {
/* The LINK_ADDRESS was sent to a device that cannot reply;
* exit from this recursion path. */
return;
/* The LINK_ADDRESS was sent to a device that cannot reply; exit
* from this recursion path. */
return XST_FAILURE;
}
/* Write GUID to the branch device if it doesn't already have one. */
@ -609,47 +642,61 @@ void XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal,
* this branch device. */
LinkCountTotal++;
/* Any downstream device downstream device will have the RAD of the
* current branch device appended with the port number. */
u8 DownstreamRelativeAddress[LinkCountTotal - 1];
/* Copy the branch device's RAD. */
for (RadIndex = 0; RadIndex < (LinkCountTotal - 2); RadIndex++) {
DownstreamRelativeAddress[RadIndex] = RelativeAddress[RadIndex];
}
u8 DownBranchesDownPorts[DeviceInfo.NumPorts];
for (Index = 0; Index < DeviceInfo.NumPorts; Index++) {
PortDetails = &DeviceInfo.PortDetails[Index];
/* Any downstream device downstream device will have the RAD of the
* current branch device appended with the port number. */
RelativeAddress[LinkCountTotal - 2] = PortDetails->PortNum;
if (PortDetails->InputPort == 0) {
/* Append the port number to the RAD of the branch
* device. */
DownstreamRelativeAddress[RadIndex] =
PortDetails->PortNum;
if ((PortDetails->InputPort == 0) &&
(PortDetails->PeerDeviceType != 0x2) &&
(PortDetails->DpDevPlugStatus == 1)) {
if (PortDetails->PeerDeviceType == 0x2) {
/* Found a branch device; recurse the algorithm
* to see what DisplayPort devices are connected
* to it with the appended RAD. */
XDptx_FindAccessibleDpDevices(InstancePtr,
LinkCountTotal,
DownstreamRelativeAddress);
}
else if (PortDetails->DpDevPlugStatus == 1) {
if ((PortDetails->MsgCapStatus == 1) &&
if ((PortDetails->MsgCapStatus == 1) &&
(PortDetails->DpcdRev >= 0x12)) {
/* Write GUID to the branch device if it
* doesn't already have one. */
XDptx_IssueGuid(InstancePtr,
LinkCountTotal, RelativeAddress,
Topology, PortDetails->Guid);
}
XDptx_AddSinkToList(InstancePtr, PortDetails,
LinkCountTotal,
DownstreamRelativeAddress);
/* Write GUID to the branch device if it
* doesn't already have one. */
XDptx_IssueGuid(InstancePtr,
LinkCountTotal, RelativeAddress,
Topology, PortDetails->Guid);
}
XDptx_AddSinkToList(InstancePtr, PortDetails,
LinkCountTotal,
RelativeAddress);
}
if (PortDetails->PeerDeviceType == 0x2) {
DownBranchesDownPorts[NumDownBranches] =
PortDetails->PortNum;
NumDownBranches++;
}
}
for (Index = 0; Index < NumDownBranches; Index++) {
/* Any downstream device downstream device will have the RAD of
* the current branch device appended with the port number. */
RelativeAddress[LinkCountTotal - 2] =
DownBranchesDownPorts[Index];
/* Found a branch device; recurse the algorithm to see what
* DisplayPort devices are connected to it with the appended
* RAD. */
Status = XDptx_FindAccessibleDpDevices(InstancePtr,
LinkCountTotal, RelativeAddress);
if (Status != XST_SUCCESS) {
/* Keep trying to discover the topology, but the top
* level function call should indicate that a failure
* was detected. */
OverallFailures++;
}
}
if (OverallFailures != 0) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/