diff --git a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.c b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.c index 544c11ce..36814b05 100644 --- a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.c +++ b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.c @@ -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; diff --git a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h index 89d7cf9f..64e05b95 100644 --- a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h +++ b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h @@ -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) * * * diff --git a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_channel.c b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_channel.c index f9d04be6..436620a7 100644 --- a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_channel.c +++ b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_channel.c @@ -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; } } diff --git a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_i.h b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_i.h index c401c38e..3e93ab70 100644 --- a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_i.h +++ b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma_i.h @@ -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