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:
parent
9547cbc0a8
commit
414d35c52e
3 changed files with 98 additions and 47 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Add table
Reference in a new issue