SAM3,4,A5 DMAC driver fixes
This commit is contained in:
parent
03f24c7a1d
commit
d1da100cf0
@ -902,6 +902,7 @@ static int sam_rxbuffer(struct sam_dma_s *dmach, uint32_t paddr,
|
||||
regval = sam_rxctrlabits(dmach);
|
||||
ctrlb = sam_rxctrlb(dmach);
|
||||
}
|
||||
|
||||
ctrla = sam_rxctrla(dmach, regval, nbytes);
|
||||
|
||||
/* Add the new link list entry */
|
||||
@ -1158,6 +1159,8 @@ static int sam_dmainterrupt(int irq, void *context)
|
||||
|
||||
void weak_function up_dmainitialize(void)
|
||||
{
|
||||
dmallvdbg("Iinitialize DMAC0\n");
|
||||
|
||||
/* Enable peripheral clock */
|
||||
|
||||
sam_dmac_enableclk();
|
||||
@ -1224,6 +1227,7 @@ DMA_HANDLE sam_dmachannel(uint32_t dmach_flags)
|
||||
|
||||
dmach = NULL;
|
||||
sam_takechsem();
|
||||
|
||||
for (chndx = 0; chndx < SAM34_NDMACHAN; chndx++)
|
||||
{
|
||||
struct sam_dma_s *candidate = &g_dma[chndx];
|
||||
@ -1256,7 +1260,10 @@ DMA_HANDLE sam_dmachannel(uint32_t dmach_flags)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sam_givechsem();
|
||||
|
||||
dmavdbg("dmach_flags: %08x returning dmach: %p\n", (int)dmach_flags, dmach);
|
||||
return (DMA_HANDLE)dmach;
|
||||
}
|
||||
|
||||
@ -1277,11 +1284,13 @@ void sam_dmafree(DMA_HANDLE handle)
|
||||
{
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
|
||||
dmavdbg("dmach: %p\n", dmach);
|
||||
DEBUGASSERT((dmach != NULL) && (dmach->inuse));
|
||||
|
||||
/* Mark the channel no longer in use. Clearing the inuse flag is an atomic
|
||||
* operation and so should be safe.
|
||||
*/
|
||||
|
||||
DEBUGASSERT((dmach != NULL) && (dmach->inuse));
|
||||
dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
|
||||
dmach->inuse = false; /* No longer in use */
|
||||
}
|
||||
@ -1302,7 +1311,10 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(dmach && dmach->llhead != NULL && dmach->lltail != 0);
|
||||
dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n",
|
||||
dmach, (int)paddr, (int)maddr, (int)nbytes);
|
||||
DEBUGASSERT(dmach);
|
||||
dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail);
|
||||
|
||||
/* If this is a large transfer, break it up into smaller buffers */
|
||||
|
||||
@ -1339,6 +1351,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
{
|
||||
ret = sam_txbuffer(dmach, paddr, maddr, nbytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1358,7 +1371,10 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(dmach && dmach->llhead != NULL && dmach->lltail != 0);
|
||||
dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n",
|
||||
dmach, (int)paddr, (int)maddr, (int)nbytes);
|
||||
DEBUGASSERT(dmach);
|
||||
dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail);
|
||||
|
||||
/* If this is a large transfer, break it up into smaller buffers */
|
||||
|
||||
@ -1395,6 +1411,7 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
{
|
||||
ret = sam_rxbuffer(dmach, paddr, maddr, nbytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1411,11 +1428,13 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
int ret = -EINVAL;
|
||||
|
||||
dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
/* Verify that the DMA has been setup (i.e., at least one entry in the
|
||||
* link list).
|
||||
*/
|
||||
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
if (dmach->llhead)
|
||||
{
|
||||
/* Save the callback info. This will be invoked whent the DMA commpletes */
|
||||
@ -1452,7 +1471,9 @@ void sam_dmastop(DMA_HANDLE handle)
|
||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||
irqstate_t flags;
|
||||
|
||||
dmavdbg("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = irqsave();
|
||||
sam_dmaterminate(dmach, -EINTR);
|
||||
irqrestore(flags);
|
||||
|
@ -1157,6 +1157,7 @@ static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
regval = sam_rxctrlabits(dmach);
|
||||
ctrlb = sam_rxctrlb(dmach);
|
||||
}
|
||||
|
||||
ctrla = sam_rxctrla(dmach, regval, nbytes);
|
||||
|
||||
/* Add the new link list entry */
|
||||
@ -1479,6 +1480,8 @@ void sam_dmainitialize(struct sam_dmac_s *dmac)
|
||||
void weak_function up_dmainitialize(void)
|
||||
{
|
||||
#ifdef CONFIG_SAMA5_DMAC0
|
||||
dmallvdbg("Iinitialize DMAC0\n");
|
||||
|
||||
/* Enable peripheral clock */
|
||||
|
||||
sam_dmac0_enableclk();
|
||||
@ -1497,6 +1500,8 @@ void weak_function up_dmainitialize(void)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SAMA5_DMAC1
|
||||
dmallvdbg("Iinitialize DMAC1\n");
|
||||
|
||||
/* Enable peripheral clock */
|
||||
|
||||
sam_dmac1_enableclk();
|
||||
@ -1560,7 +1565,7 @@ DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags)
|
||||
#endif
|
||||
|
||||
{
|
||||
fdbg("Bad DMAC number: %d\n", dmacno);
|
||||
dmadbg("Bad DMAC number: %d\n", dmacno);
|
||||
DEBUGPANIC();
|
||||
return (DMA_HANDLE)NULL;
|
||||
}
|
||||
@ -1599,6 +1604,9 @@ DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags)
|
||||
}
|
||||
|
||||
sam_givechsem(dmac);
|
||||
|
||||
dmavdbg("dmacno: %d chflags: %08x returning dmach: %p\n",
|
||||
(int)dmacno, (int)chflags, dmach);
|
||||
return (DMA_HANDLE)dmach;
|
||||
}
|
||||
|
||||
@ -1619,11 +1627,13 @@ void sam_dmafree(DMA_HANDLE handle)
|
||||
{
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
|
||||
dmavdbg("dmach: %p\n", dmach);
|
||||
DEBUGASSERT((dmach != NULL) && (dmach->inuse));
|
||||
|
||||
/* Mark the channel no longer in use. Clearing the inuse flag is an atomic
|
||||
* operation and so should be safe.
|
||||
*/
|
||||
|
||||
DEBUGASSERT((dmach != NULL) && (dmach->inuse));
|
||||
dmach->flags = 0;
|
||||
dmach->inuse = false; /* No longer in use */
|
||||
}
|
||||
@ -1644,7 +1654,10 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(dmach && dmach->llhead != NULL && dmach->lltail != 0);
|
||||
dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n",
|
||||
dmach, (int)paddr, (int)maddr, (int)nbytes);
|
||||
DEBUGASSERT(dmach);
|
||||
dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail);
|
||||
|
||||
/* If this is a large transfer, break it up into smaller buffers */
|
||||
|
||||
@ -1696,12 +1709,16 @@ 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)
|
||||
int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
|
||||
size_t nbytes)
|
||||
{
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(dmach && dmach->llhead != NULL && dmach->lltail != 0);
|
||||
dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n",
|
||||
dmach, (int)paddr, (int)maddr, (int)nbytes);
|
||||
DEBUGASSERT(dmach);
|
||||
dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail);
|
||||
|
||||
/* If this is a large transfer, break it up into smaller buffers */
|
||||
|
||||
@ -1755,11 +1772,13 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
int ret = -EINVAL;
|
||||
|
||||
dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
/* Verify that the DMA has been setup (i.e., at least one entry in the
|
||||
* link list).
|
||||
*/
|
||||
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
if (dmach->llhead)
|
||||
{
|
||||
/* Save the callback info. This will be invoked whent the DMA commpletes */
|
||||
@ -1797,7 +1816,9 @@ void sam_dmastop(DMA_HANDLE handle)
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
irqstate_t flags;
|
||||
|
||||
dmavdbg("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = irqsave();
|
||||
sam_dmaterminate(dmach, -EINTR);
|
||||
irqrestore(flags);
|
||||
|
@ -736,7 +736,7 @@ static void sam_disablewaitints(struct sam_dev_s *priv,
|
||||
priv->waitevents = 0;
|
||||
priv->wkupevent = wkupevent;
|
||||
priv->waitmask = 0;
|
||||
putreg32(~priv->xfrmask, SAM_HSMCI_IDR_OFFSET);
|
||||
sam_putreg(priv, ~priv->xfrmask, SAM_HSMCI_IDR_OFFSET);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
@ -782,7 +782,7 @@ static void sam_disablexfrints(struct sam_dev_s *priv)
|
||||
{
|
||||
irqstate_t flags = irqsave();
|
||||
priv->xfrmask = 0;
|
||||
putreg32(~priv->waitmask, SAM_HSMCI_IDR_OFFSET);
|
||||
sam_putreg(priv, ~priv->waitmask, SAM_HSMCI_IDR_OFFSET);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user