From 0cd5afb0fdd40110f8c37acf28bceca80620317e Mon Sep 17 00:00:00 2001 From: Andrei-Liviu Simion Date: Thu, 30 Oct 2014 12:52:59 -0700 Subject: [PATCH] dptx: Improved remote DPCD reads/writes to automatically work on 16-byte chunks. Some monitors don't support sideband messages with AUX reads greater than 16 bytes. This improvement breaks up the higher-level read/write request into multiple reads/writes that work with up to 16 bytes in size. These higher-level remote DPCD read/write functions also serve as a wrapper for an AUX read/write in case that the link count total is equal to 1 (a read/write request to the RX device directly connected to the TX (not "remote")). Signed-off-by: Andrei-Liviu Simion --- XilinxProcessorIPLib/drivers/dptx/src/xdptx.h | 7 ++ .../drivers/dptx/src/xdptx_mst.c | 78 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h b/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h index eb263196..a0adb1e8 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx.h @@ -833,6 +833,13 @@ u32 XDptx_DiscoverTopology(XDptx *InstancePtr); u32 XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal, u8 *RelativeAddress); +/* xdptx_mst.c: Multi-stream transport (MST) functions for communicating + * with downstream DisplayPort devices. */ +u32 XDptx_RemoteDpcdRead(XDptx *InstancePtr, u8 LinkCountTotal, + u8 *RelativeAddress, u32 DpcdAddress, u32 BytesToRead, u8 *ReadData); +u32 XDptx_RemoteDpcdWrite(XDptx *InstancePtr, u8 LinkCountTotal, + u8 *RelativeAddress, u32 DpcdAddress, u32 BytesToWrite, u8 *WriteData); + /* xdptx_mst.c: Multi-stream transport (MST) functions related to MST stream * allocation. */ u32 XDptx_AllocatePayloadStreams(XDptx *InstancePtr); diff --git a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c index 3a522737..32dd8acb 100644 --- a/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c +++ b/XilinxProcessorIPLib/drivers/dptx/src/xdptx_mst.c @@ -706,6 +706,84 @@ u32 XDptx_FindAccessibleDpDevices(XDptx *InstancePtr, u8 LinkCountTotal, return XST_SUCCESS; } +u32 XDptx_RemoteDpcdRead(XDptx *InstancePtr, u8 LinkCountTotal, + u8 *RelativeAddress, u32 DpcdAddress, u32 BytesToRead, u8 *ReadData) +{ + u32 Status; + + if (LinkCountTotal == 1) { + Status = XDptx_AuxRead(InstancePtr, DpcdAddress, BytesToRead, + ReadData); + } + else { + u32 BytesLeft = BytesToRead; + while (BytesLeft > 0) { + if (BytesLeft > 16) { + Status = XDptx_SendSbMsgRemoteDpcdRead( + InstancePtr, LinkCountTotal, + RelativeAddress, DpcdAddress, 16, + ReadData); + BytesLeft -= 16; + DpcdAddress += 16; + ReadData += 16; + } + else { + Status = XDptx_SendSbMsgRemoteDpcdRead( + InstancePtr, LinkCountTotal, + RelativeAddress, DpcdAddress, BytesLeft, + ReadData); + BytesLeft = 0; + } + + if (Status != XST_SUCCESS) { + /* The AUX read transaction failed. */ + return Status; + } + } + } + + return Status; +} + +u32 XDptx_RemoteDpcdWrite(XDptx *InstancePtr, u8 LinkCountTotal, + u8 *RelativeAddress, u32 DpcdAddress, u32 BytesToWrite, u8 *WriteData) +{ + u32 Status; + + if (LinkCountTotal == 1) { + Status = XDptx_AuxWrite(InstancePtr, DpcdAddress, BytesToWrite, + WriteData); + } + else { + u32 BytesLeft = BytesToWrite; + while (BytesLeft > 0) { + if (BytesLeft > 16) { + Status = XDptx_SendSbMsgRemoteDpcdWrite( + InstancePtr, LinkCountTotal, + RelativeAddress, DpcdAddress, 16, + WriteData); + BytesLeft -= 16; + DpcdAddress += 16; + WriteData += 16; + } + else { + Status = XDptx_SendSbMsgRemoteDpcdWrite( + InstancePtr, LinkCountTotal, + RelativeAddress, DpcdAddress, BytesLeft, + WriteData); + BytesLeft = 0; + } + + if (Status != XST_SUCCESS) { + /* The AUX read transaction failed. */ + return Status; + } + } + } + + return Status; +} + /******************************************************************************/ /** * This function will allocate bandwidth for all enabled stream.