dptx: Improved remote IIC reads/writes to automatically work on 16-byte chunks.
Some monitors don't support sideband messages with IIC 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 IIC read/write functions also serve as a wrapper for an IIC 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 <andrei.simion@xilinx.com>
This commit is contained in:
parent
bc8b86b940
commit
ce0e1fd561
3 changed files with 124 additions and 9 deletions
|
@ -838,7 +838,7 @@ u32 XDptx_IicRead(XDptx *InstancePtr, u8 IicAddress, u16 Offset,
|
|||
|
||||
/* Reposition based on a segment length of 256 bytes. */
|
||||
SegPtr = 0;
|
||||
if (Offset >= 255) {
|
||||
if (Offset > 255) {
|
||||
SegPtr += Offset / 256;
|
||||
Offset %= 256;
|
||||
}
|
||||
|
|
|
@ -839,6 +839,11 @@ 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);
|
||||
u32 XDptx_RemoteIicRead(XDptx *InstancePtr, u8 LinkCountTotal,
|
||||
u8 *RelativeAddress, u8 IicAddress, u16 Offset, u16 BytesToRead,
|
||||
u8 *ReadData);
|
||||
u32 XDptx_RemoteIicWrite(XDptx *InstancePtr, u8 LinkCountTotal,
|
||||
u8 *RelativeAddress, u8 IicAddress, u8 BytesToWrite, u8 *WriteData);
|
||||
|
||||
/* xdptx_mst.c: Multi-stream transport (MST) functions related to MST stream
|
||||
* allocation. */
|
||||
|
|
|
@ -784,6 +784,122 @@ u32 XDptx_RemoteDpcdWrite(XDptx *InstancePtr, u8 LinkCountTotal,
|
|||
return Status;
|
||||
}
|
||||
|
||||
u32 XDptx_RemoteIicRead(XDptx *InstancePtr, u8 LinkCountTotal,
|
||||
u8 *RelativeAddress, u8 IicAddress, u16 Offset, u16 BytesToRead,
|
||||
u8 *ReadData)
|
||||
{
|
||||
u32 Status;
|
||||
|
||||
if (LinkCountTotal == 1) {
|
||||
Status = XDptx_IicRead(InstancePtr, IicAddress, Offset,
|
||||
BytesToRead, ReadData);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
u8 SegPtr;
|
||||
u16 NumBytesLeftInSeg;
|
||||
u16 BytesLeft = BytesToRead;
|
||||
u8 CurrBytesToRead;
|
||||
|
||||
/* Reposition based on a segment length of 256 bytes. */
|
||||
SegPtr = 0;
|
||||
if (Offset > 255) {
|
||||
SegPtr += Offset / 256;
|
||||
Offset %= 256;
|
||||
}
|
||||
NumBytesLeftInSeg = 256 - Offset;
|
||||
|
||||
/* Set the segment pointer to 0. */
|
||||
Status = XDptx_RemoteIicWrite(InstancePtr, LinkCountTotal,
|
||||
RelativeAddress, 0x30, 1, &SegPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* The I2C write to set the segment pointer failed. */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Send I2C read message in 16 byte chunks. */
|
||||
while (BytesLeft > 0) {
|
||||
/* Reposition based on segment boundaries. */
|
||||
if (NumBytesLeftInSeg >= 16) {
|
||||
CurrBytesToRead = 16;
|
||||
}
|
||||
else if (NumBytesLeftInSeg >= BytesLeft) {
|
||||
CurrBytesToRead = BytesLeft;
|
||||
}
|
||||
else {
|
||||
CurrBytesToRead = NumBytesLeftInSeg;
|
||||
}
|
||||
|
||||
/* Send remote I2C read sideband message. */
|
||||
Status = XDptx_SendSbMsgRemoteIicRead(InstancePtr,
|
||||
LinkCountTotal, RelativeAddress, IicAddress, Offset,
|
||||
BytesLeft, ReadData);
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* The sideband message transaction failed. */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* I2C read of 16 bytes. */
|
||||
if (BytesLeft > CurrBytesToRead) {
|
||||
BytesLeft -= CurrBytesToRead;
|
||||
Offset += CurrBytesToRead;
|
||||
ReadData += CurrBytesToRead;
|
||||
NumBytesLeftInSeg -= CurrBytesToRead;
|
||||
}
|
||||
/* Last I2C read. */
|
||||
else {
|
||||
BytesLeft = 0;
|
||||
}
|
||||
|
||||
/* Increment the segment pointer to access more I2C address
|
||||
* space. */
|
||||
if ((NumBytesLeftInSeg == 0) && (BytesLeft > 0)) {
|
||||
SegPtr++;
|
||||
Offset %= 256;
|
||||
NumBytesLeftInSeg = 256;
|
||||
|
||||
Status = XDptx_RemoteIicWrite(InstancePtr,
|
||||
LinkCountTotal, RelativeAddress, 0x30, 1,
|
||||
&SegPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the segment pointer to 0. */
|
||||
SegPtr = 0;
|
||||
Status = XDptx_RemoteIicWrite(InstancePtr, LinkCountTotal,
|
||||
RelativeAddress, 0x30, 1, &SegPtr);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
u32 XDptx_RemoteIicWrite(XDptx *InstancePtr, u8 LinkCountTotal,
|
||||
u8 *RelativeAddress, u8 IicAddress, u8 BytesToWrite,
|
||||
u8 *WriteData)
|
||||
{
|
||||
u32 Status;
|
||||
|
||||
if (LinkCountTotal == 1) {
|
||||
Status = XDptx_IicWrite(InstancePtr, IicAddress, BytesToWrite,
|
||||
WriteData);
|
||||
}
|
||||
else {
|
||||
Status = XDptx_SendSbMsgRemoteIicWrite(InstancePtr,
|
||||
LinkCountTotal, RelativeAddress, IicAddress,
|
||||
BytesToWrite, WriteData);
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* The AUX read transaction failed. */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This function will allocate bandwidth for all enabled stream.
|
||||
|
@ -1803,14 +1919,8 @@ u32 XDptx_GetRemoteEdid(XDptx *InstancePtr, u8 LinkCountTotal,
|
|||
Xil_AssertNonvoid((RelativeAddress != NULL) || (LinkCountTotal == 1));
|
||||
Xil_AssertNonvoid(Edid != NULL);
|
||||
|
||||
if (LinkCountTotal == 1) {
|
||||
Status = XDptx_GetEdid(InstancePtr, Edid);
|
||||
}
|
||||
else {
|
||||
Status = XDptx_SendSbMsgRemoteIicRead(InstancePtr,
|
||||
LinkCountTotal, RelativeAddress,
|
||||
XDPTX_EDID_ADDR, 0, XDPTX_EDID_SIZE, Edid);
|
||||
}
|
||||
Status = XDptx_RemoteIicRead(InstancePtr, LinkCountTotal,
|
||||
RelativeAddress, XDPTX_EDID_ADDR, 0, XDPTX_EDID_SIZE, Edid);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue