vdma: Add checks to align hsize and stride based on channel direction

When DRE is not enabled,adjust hsize and stride to memap data width on write channel(S2MM).
On read channel(mm2s), adjust hsize to stream data width and stride to memap data width.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Acked-by: Anirudha Sarangi <anirudh@xilinx.com>
This commit is contained in:
Anurag Kumar Vulisha 2015-08-26 18:23:21 +05:30 committed by Nava kishore Manne
parent 5d923bad10
commit 6d847e63b2
4 changed files with 36 additions and 14 deletions

View file

@ -181,6 +181,7 @@ int XAxiVdma_CfgInitialize(XAxiVdma *InstancePtr, XAxiVdma_Config *CfgPtr,
WrChannel->IsValid = 0;
if (InstancePtr->HasMm2S) {
RdChannel->direction = XAXIVDMA_READ;
RdChannel->ChanBase = InstancePtr->BaseAddr + XAXIVDMA_TX_OFFSET;
RdChannel->InstanceBase = InstancePtr->BaseAddr;
RdChannel->HasSG = InstancePtr->HasSG;
@ -261,6 +262,7 @@ int XAxiVdma_CfgInitialize(XAxiVdma *InstancePtr, XAxiVdma_Config *CfgPtr,
}
if (InstancePtr->HasS2Mm) {
WrChannel->direction = XAXIVDMA_WRITE;
WrChannel->ChanBase = InstancePtr->BaseAddr + XAXIVDMA_RX_OFFSET;
WrChannel->InstanceBase = InstancePtr->BaseAddr;
WrChannel->HasSG = InstancePtr->HasSG;

View file

@ -284,6 +284,8 @@
* (xaxivdma_selftest.c) and called this from the selftest example
* 6.0 vak 27/07/15 Added example for demonstarting triple buffer api.
* 6.0 vak 27/07/15 Added 64 bit addressing support to the driver.
* 6.0 vak 26/08/15 Added checks to align hsize and stride based on channel direction
* (read or write)(CR 874861)
*
* </pre>
*

View file

@ -627,7 +627,8 @@ int XAxiVdma_ChannelConfig(XAxiVdma_Channel *Channel,
int i;
int NumBds;
int Status;
u32 WordLenBits;
u32 hsize_align;
u32 stride_align;
if (!Channel->IsValid) {
xdbg_printf(XDBG_DEBUG_ERROR, "Channel not initialized\r\n");
@ -644,25 +645,41 @@ int XAxiVdma_ChannelConfig(XAxiVdma_Channel *Channel,
Channel->Vsize = ChannelCfgPtr->VertSizeInput;
WordLenBits = (u32)(Channel->WordLength - 1);
/* Check whether Hsize is properly aligned */
if (Channel->direction == XAXIVDMA_WRITE) {
if (ChannelCfgPtr->HoriSizeInput < Channel->WordLength) {
hsize_align = (u32)Channel->WordLength;
} else {
hsize_align =
(u32)(ChannelCfgPtr->HoriSizeInput % Channel->WordLength);
}
} else {
if (ChannelCfgPtr->HoriSizeInput < Channel->WordLength) {
hsize_align = (u32)Channel->WordLength;
} else {
hsize_align =
(u32)(ChannelCfgPtr->HoriSizeInput % Channel->StreamWidth);
}
}
/* Check whether Stride is properly aligned */
if (ChannelCfgPtr->Stride < Channel->WordLength) {
stride_align = (u32)Channel->WordLength;
} else {
stride_align = (u32)(ChannelCfgPtr->Stride % Channel->WordLength);
}
/* If hardware has no DRE, then Hsize and Stride must
* be word-aligned
*/
if (!Channel->HasDRE) {
if (ChannelCfgPtr->HoriSizeInput & WordLenBits) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Unaligned Hsize %x: without DRE\r\n",
ChannelCfgPtr->HoriSizeInput);
return XST_INVALID_PARAM;
if (hsize_align != 0) {
/* Adjust hsize to multiples of stream/mm data width*/
ChannelCfgPtr->HoriSizeInput += hsize_align;
}
if (ChannelCfgPtr->Stride & WordLenBits) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Unaligned Stride %x: without DRE\r\n",
ChannelCfgPtr->Stride);
return XST_INVALID_PARAM;
if (stride_align != 0) {
/* Adjust stride to multiples of stream/mm data width*/
ChannelCfgPtr->Stride += stride_align;
}
}

View file

@ -116,6 +116,7 @@ typedef struct {
/*Statically allocated BDs */
u32 DbgFeatureFlags; /* Debug Parameter Flags */
int AddrWidth;
int direction; /* Determines whether Read or write channel */
}XAxiVdma_Channel;
/* Duplicate layout of XAxiVdma_DmaSetup