mirror of
https://github.com/apache/nuttx.git
synced 2026-09-20 21:06:58 +08:00
SAMA5 DMA: Need to flush caches; DMA channel depends upon direction of DMA; the maximum transfer size in bytes depends on the number of bytes per transfer
This commit is contained in:
@@ -424,7 +424,7 @@ static inline uint32_t sam_txctrla(struct sam_dma_s *dmach,
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
|
||||
{
|
||||
dmasize >>= 2;
|
||||
dmasize = (dmasize + 3) >> 2;
|
||||
}
|
||||
|
||||
DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
|
||||
@@ -516,7 +516,7 @@ static inline uint32_t sam_rxctrla(struct sam_dma_s *dmach,
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
|
||||
{
|
||||
dmasize >>= 2;
|
||||
dmasize = (dmasize + 3) >> 2;
|
||||
}
|
||||
|
||||
DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
|
||||
@@ -1311,6 +1311,7 @@ void sam_dmafree(DMA_HANDLE handle)
|
||||
int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
||||
{
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
size_t maxtransfer;
|
||||
int ret = OK;
|
||||
|
||||
dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n",
|
||||
@@ -1318,18 +1319,31 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
DEBUGASSERT(dmach);
|
||||
dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail);
|
||||
|
||||
/* The maximum transfer size in bytes depends upon the maximum number of
|
||||
* transfers and the number of bytes per transfer.
|
||||
*/
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
|
||||
{
|
||||
maxtransfer = 4 * DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxtransfer = DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
}
|
||||
|
||||
/* If this is a large transfer, break it up into smaller buffers */
|
||||
|
||||
while (nbytes > DMACHAN_CTRLA_BTSIZE_MAX)
|
||||
while (nbytes > maxtransfer)
|
||||
{
|
||||
/* Set up the maximum size transfer */
|
||||
|
||||
ret = sam_txbuffer(dmach, paddr, maddr, DMACHAN_CTRLA_BTSIZE_MAX);
|
||||
ret = sam_txbuffer(dmach, paddr, maddr, maxtransfer);
|
||||
if (ret == OK);
|
||||
{
|
||||
/* Decrement the number of bytes left to transfer */
|
||||
|
||||
nbytes -= DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
nbytes -= maxtransfer;
|
||||
|
||||
/* Increment the memory & peripheral address (if it is appropriate to
|
||||
* do do).
|
||||
@@ -1337,12 +1351,12 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
|
||||
{
|
||||
paddr += DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
paddr += maxtransfer;
|
||||
}
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0)
|
||||
{
|
||||
maddr += DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
maddr += maxtransfer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1371,6 +1385,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
||||
{
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
size_t maxtransfer;
|
||||
int ret = OK;
|
||||
|
||||
dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n",
|
||||
@@ -1378,18 +1393,31 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
DEBUGASSERT(dmach);
|
||||
dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail);
|
||||
|
||||
/* The maximum transfer size in bytes depends upon the maximum number of
|
||||
* transfers and the number of bytes per transfer.
|
||||
*/
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
|
||||
{
|
||||
maxtransfer = 4 * DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxtransfer = DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
}
|
||||
|
||||
/* If this is a large transfer, break it up into smaller buffers */
|
||||
|
||||
while (nbytes > DMACHAN_CTRLA_BTSIZE_MAX)
|
||||
while (nbytes > maxtransfer)
|
||||
{
|
||||
/* Set up the maximum size transfer */
|
||||
|
||||
ret = sam_rxbuffer(dmach, paddr, maddr, DMACHAN_CTRLA_BTSIZE_MAX);
|
||||
ret = sam_rxbuffer(dmach, paddr, maddr, maxtransfer);
|
||||
if (ret == OK);
|
||||
{
|
||||
/* Decrement the number of bytes left to transfer */
|
||||
|
||||
nbytes -= DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
nbytes -= maxtransfer;
|
||||
|
||||
/* Increment the memory & peripheral address (if it is appropriate to
|
||||
* do do).
|
||||
@@ -1397,12 +1425,12 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
|
||||
{
|
||||
paddr += DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
paddr += maxtransfer;
|
||||
}
|
||||
|
||||
if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0)
|
||||
{
|
||||
maddr += DMACHAN_CTRLA_BTSIZE_MAX;
|
||||
maddr += maxtransfer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+451
-71
File diff suppressed because it is too large
Load Diff
@@ -104,7 +104,7 @@
|
||||
/* Memory endpoint characteristics */
|
||||
|
||||
#define DMACH_FLAG_MEMPID_SHIFT (17) /* Bits 17-22: Memory PID */
|
||||
#define DMACH_FLAG_MEMPID_MASK (63 << DMACH_FLAG_PERIPHPID_SHIFT)
|
||||
#define DMACH_FLAG_MEMPID_MASK (63 << DMACH_FLAG_MEMPID_SHIFT)
|
||||
#define DMACH_FLAG_MEMH2SEL (1 << 23) /* Bits 23: HW handshaking */
|
||||
#define DMACH_FLAG_MEMISPERIPH (1 << 24) /* Bits 24: 0=memory; 1=peripheral */
|
||||
#define DMACH_FLAG_MEMAHB_SHIFT (25) /* Bits 25-26: Peripheral ABH layer number */
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
( HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RDIRE | \
|
||||
HSMCI_INT_RINDE )
|
||||
#define HSMCI_RESPONSE_TIMEOUT_ERRORS \
|
||||
( HSMCI_INT_CSTOE | HSMCI_INT_RTOE )
|
||||
( HSMCI_INT_CSTOE | HSMCI_INT_RTOE )
|
||||
|
||||
/* Data transfer errors:
|
||||
*
|
||||
@@ -261,7 +261,6 @@
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Register logging support */
|
||||
|
||||
#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG)
|
||||
@@ -432,7 +431,7 @@ static void sam_notransfer(struct sam_dev_s *priv);
|
||||
|
||||
/* Interrupt Handling *******************************************************/
|
||||
|
||||
static int sam_hsmci_interrupt(struct sam_dev_s *priv);
|
||||
static int sam_hsmci_interrupt(struct sam_dev_s *priv);
|
||||
#ifdef CONFIG_SAMA5_HSMCI0
|
||||
static int sam_hsmci0_interrupt(int irq, void *context);
|
||||
#endif
|
||||
@@ -497,7 +496,6 @@ static void sam_callback(void *arg);
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static const struct sdio_dev_s g_callbacks =
|
||||
@@ -2733,7 +2731,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
/* For DMA channel selection */
|
||||
|
||||
dmac = 0;
|
||||
pid = DMAC0_CH_HSMCI0;
|
||||
pid = SAM_PID_HSMCI0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -2770,7 +2768,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
/* For DMA channel selection */
|
||||
|
||||
dmac = 1;
|
||||
pid = DMAC1_CH_HSMCI1;
|
||||
pid = SAM_PID_HSMCI1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -2807,7 +2805,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
/* For DMA channel selection */
|
||||
|
||||
dmac = 1;
|
||||
pid = DMAC1_CH_HSMCI2;
|
||||
pid = SAM_PID_HSMCI2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -2827,7 +2825,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
|
||||
/* Initialize the callbacks */
|
||||
|
||||
memcpy(&priv->dev, &g_callbacks, sizeof(struct sdio_dev_s ));
|
||||
memcpy(&priv->dev, &g_callbacks, sizeof(struct sdio_dev_s));
|
||||
|
||||
/* Allocate a DMA channel */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user