SAMV7: Use D-Cache clean/flush/invalidate by range in EMAC and XDMAC drivers

This commit is contained in:
Gregory Nutt 2015-03-17 09:28:27 -06:00
parent fdbbab013b
commit 42c33033a8
3 changed files with 19 additions and 93 deletions

View File

@ -289,13 +289,11 @@ void arch_disable_dcache(void);
* *
****************************************************************************/ ****************************************************************************/
#if 0 /* Not implemented */
#ifdef CONFIG_ARMV7M_DCACHE #ifdef CONFIG_ARMV7M_DCACHE
void arch_invalidate_dcache(uintptr_t start, uintptr_t end); void arch_invalidate_dcache(uintptr_t start, uintptr_t end);
#else #else
# define arch_invalidate_dcache(s,e) # define arch_invalidate_dcache(s,e)
#endif #endif
#endif
/**************************************************************************** /****************************************************************************
* Name: arch_invalidate_dcache_all * Name: arch_invalidate_dcache_all
@ -338,13 +336,11 @@ void arch_invalidate_dcache_all(void);
* *
****************************************************************************/ ****************************************************************************/
#if 0 /* Not implemented */
#ifdef CONFIG_ARMV7M_DCACHE #ifdef CONFIG_ARMV7M_DCACHE
void arch_clean_dcache(uintptr_t start, uintptr_t end); void arch_clean_dcache(uintptr_t start, uintptr_t end);
#else #else
# define arch_clean_dcache(s,e) # define arch_clean_dcache(s,e)
#endif #endif
#endif
/**************************************************************************** /****************************************************************************
* Name: arch_clean_dcache_all * Name: arch_clean_dcache_all
@ -393,13 +389,11 @@ void arch_clean_dcache_all(void);
* *
****************************************************************************/ ****************************************************************************/
#if 0 /* Not implemented */
#ifdef CONFIG_ARMV7M_DCACHE #ifdef CONFIG_ARMV7M_DCACHE
void arch_flush_dcache(uintptr_t start, uintptr_t end); void arch_flush_dcache(uintptr_t start, uintptr_t end);
#else #else
# define arch_flush_dcache(s,e) # define arch_flush_dcache(s,e)
#endif #endif
#endif
/**************************************************************************** /****************************************************************************
* Name: arch_flush_dcache_all * Name: arch_flush_dcache_all

View File

@ -316,11 +316,6 @@
#define EMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */ #define EMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */
#define EMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */ #define EMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */
/* These cache operations are not yet available */
#undef HAVE_CLEAN_DCACHE_RANGE
#undef HAVE_INVALIDATE_DCACHE_RANGE
/* Timing *******************************************************************/ /* Timing *******************************************************************/
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
* second * second
@ -1118,11 +1113,8 @@ static int sam_transmit(struct sam_emac_s *priv)
/* Driver managed the ring buffer */ /* Driver managed the ring buffer */
memcpy((void *)txdesc->addr, dev->d_buf, dev->d_len); memcpy((void *)txdesc->addr, dev->d_buf, dev->d_len);
#ifdef HAVE_CLEAN_DCACHE_RANGE
arch_clean_dcache((uintptr_t)txdesc->addr, arch_clean_dcache((uintptr_t)txdesc->addr,
(uintptr_t)txdesc->addr + dev->d_len); (uintptr_t)txdesc->addr + dev->d_len);
#endif
} }
/* Update TX descriptor status. */ /* Update TX descriptor status. */
@ -1136,13 +1128,8 @@ static int sam_transmit(struct sam_emac_s *priv)
/* Update the descriptor status and flush the updated value to RAM */ /* Update the descriptor status and flush the updated value to RAM */
txdesc->status = status; txdesc->status = status;
#ifdef HAVE_CLEAN_DCACHE_RANGE
arch_clean_dcache((uint32_t)txdesc, arch_clean_dcache((uint32_t)txdesc,
(uint32_t)txdesc + sizeof(struct emac_txdesc_s)); (uint32_t)txdesc + sizeof(struct emac_txdesc_s));
#else
arch_clean_dcache_all();
#endif
/* Increment the head index */ /* Increment the head index */
@ -1346,13 +1333,13 @@ static int sam_recvframe(struct sam_emac_s *priv)
rxdesc = &priv->rxdesc[rxndx]; rxdesc = &priv->rxdesc[rxndx];
isframe = false; isframe = false;
/* Invalidate the RX descriptor to force re-fetching from RAM */ /* Invalidate the RX descriptor to force re-fetching from RAM.
* REVISIT: If the rxdesc is not aligned with the cacheline boundary
* then won't this also invalidate some surrounding memory?
*/
#warning FIXME!!!
#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */
arch_invalidate_dcache((uintptr_t)rxdesc, arch_invalidate_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s));
#endif
nllvdbg("rxndx: %d\n", rxndx); nllvdbg("rxndx: %d\n", rxndx);
@ -1373,14 +1360,11 @@ static int sam_recvframe(struct sam_emac_s *priv)
rxdesc = &priv->rxdesc[priv->rxndx]; rxdesc = &priv->rxdesc[priv->rxndx];
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
/* Flush the modified RX descriptor to RAM */ /* Flush the modified RX descriptor to RAM */
arch_clean_dcache((uintptr_t)rxdesc, arch_clean_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + (uintptr_t)rxdesc +
sizeof(struct emac_rxdesc_s)); sizeof(struct emac_rxdesc_s));
#endif
/* Increment the RX index */ /* Increment the RX index */
@ -1421,14 +1405,11 @@ static int sam_recvframe(struct sam_emac_s *priv)
rxdesc = &priv->rxdesc[priv->rxndx]; rxdesc = &priv->rxdesc[priv->rxndx];
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
/* Flush the modified RX descriptor to RAM */ /* Flush the modified RX descriptor to RAM */
arch_clean_dcache((uintptr_t)rxdesc, arch_clean_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + (uintptr_t)rxdesc +
sizeof(struct emac_rxdesc_s)); sizeof(struct emac_rxdesc_s));
#endif
/* Increment the RX index */ /* Increment the RX index */
@ -1451,14 +1432,14 @@ static int sam_recvframe(struct sam_emac_s *priv)
/* Get the data source. Invalidate the source memory region to /* Get the data source. Invalidate the source memory region to
* force reload from RAM. * force reload from RAM.
*
* REVISIT: If the rxdesc is not aligned with the cacheline
* boundary then won't this also invalidate some surrounding
* memory?
*/ */
src = (const uint8_t *)(rxdesc->addr & EMACRXD_ADDR_MASK); src = (const uint8_t *)(rxdesc->addr & EMACRXD_ADDR_MASK);
#warning FIXME!!!
#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */
arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen); arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen);
#endif
/* And do the copy */ /* And do the copy */
@ -1486,14 +1467,11 @@ static int sam_recvframe(struct sam_emac_s *priv)
rxdesc = &priv->rxdesc[priv->rxndx]; rxdesc = &priv->rxdesc[priv->rxndx];
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
/* Flush the modified RX descriptor to RAM */ /* Flush the modified RX descriptor to RAM */
arch_clean_dcache((uintptr_t)rxdesc, arch_clean_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + (uintptr_t)rxdesc +
sizeof(struct emac_rxdesc_s)); sizeof(struct emac_rxdesc_s));
#endif
/* Increment the RX index */ /* Increment the RX index */
@ -1529,14 +1507,11 @@ static int sam_recvframe(struct sam_emac_s *priv)
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
/* Flush the modified RX descriptor to RAM */ /* Flush the modified RX descriptor to RAM */
arch_clean_dcache((uintptr_t)rxdesc, arch_clean_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + (uintptr_t)rxdesc +
sizeof(struct emac_rxdesc_s)); sizeof(struct emac_rxdesc_s));
#endif
priv->rxndx = rxndx; priv->rxndx = rxndx;
} }
@ -1544,13 +1519,14 @@ static int sam_recvframe(struct sam_emac_s *priv)
rxdesc = &priv->rxdesc[rxndx]; rxdesc = &priv->rxdesc[rxndx];
#warning FIXME!!! /* Invalidate the RX descriptor to force re-fetching from RAM
#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ *
/* Invalidate the RX descriptor to force re-fetching from RAM */ * REVISIT: If the rxdesc is not aligned with the cacheline boundary
* then won't this also invalidate some surrounding memory?
*/
arch_invalidate_dcache((uintptr_t)rxdesc, arch_invalidate_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s));
#endif
} }
/* No packet was found */ /* No packet was found */
@ -1747,11 +1723,12 @@ static void sam_txdone(struct sam_emac_s *priv)
txdesc = &priv->txdesc[priv->txtail]; txdesc = &priv->txdesc[priv->txtail];
#warning FIXME!!! /* REVISIT: If the rxdesc is not aligned with the cacheline boundary
#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ * then won't this also invalidate some surrounding memory?
*/
arch_invalidate_dcache((uintptr_t)txdesc, arch_invalidate_dcache((uintptr_t)txdesc,
(uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); (uintptr_t)txdesc + sizeof(struct emac_txdesc_s));
#endif
/* Is this TX descriptor still in use? */ /* Is this TX descriptor still in use? */
@ -1801,11 +1778,8 @@ static void sam_txdone(struct sam_emac_s *priv)
/* Make sure that the USED bit is set */ /* Make sure that the USED bit is set */
txdesc->status = (uint32_t)EMACTXD_STA_USED; txdesc->status = (uint32_t)EMACTXD_STA_USED;
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
arch_clean_dcache((uintptr_t)txdesc, arch_clean_dcache((uintptr_t)txdesc,
(uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); (uintptr_t)txdesc + sizeof(struct emac_txdesc_s));
#endif
#endif #endif
/* Increment the tail index */ /* Increment the tail index */
@ -4075,14 +4049,11 @@ static void sam_txreset(struct sam_emac_s *priv)
txdesc[priv->attr->ntxbuffers - 1].status = txdesc[priv->attr->ntxbuffers - 1].status =
EMACTXD_STA_USED | EMACTXD_STA_WRAP; EMACTXD_STA_USED | EMACTXD_STA_WRAP;
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
/* Flush the entire TX descriptor table to RAM */ /* Flush the entire TX descriptor table to RAM */
arch_clean_dcache((uintptr_t)txdesc, arch_clean_dcache((uintptr_t)txdesc,
(uintptr_t)txdesc + (uintptr_t)txdesc +
priv->attr->ntxbuffers * sizeof(struct emac_txdesc_s)); priv->attr->ntxbuffers * sizeof(struct emac_txdesc_s));
#endif
/* Set the Transmit Buffer Queue Pointer Register */ /* Set the Transmit Buffer Queue Pointer Register */
@ -4139,14 +4110,11 @@ static void sam_rxreset(struct sam_emac_s *priv)
rxdesc[priv->attr->nrxbuffers - 1].addr |= EMACRXD_ADDR_WRAP; rxdesc[priv->attr->nrxbuffers - 1].addr |= EMACRXD_ADDR_WRAP;
#warning FIXME!!!
#ifdef HAVE_CLEAN_DCACHE_RANGE
/* Flush the entire RX descriptor table to RAM */ /* Flush the entire RX descriptor table to RAM */
arch_clean_dcache((uintptr_t)rxdesc, arch_clean_dcache((uintptr_t)rxdesc,
(uintptr_t)rxdesc + (uintptr_t)rxdesc +
priv->attr->nrxbuffers * sizeof(struct emac_rxdesc_s)); priv->attr->nrxbuffers * sizeof(struct emac_rxdesc_s));
#endif
/* Set the Receive Buffer Queue Pointer Register */ /* Set the Receive Buffer Queue Pointer Register */

View File

@ -92,11 +92,6 @@
# define CONFIG_SAMV7_NLLDESC SAMV7_NDMACHAN # define CONFIG_SAMV7_NLLDESC SAMV7_NDMACHAN
#endif #endif
/* These cache operations are not yet available */
#undef HAVE_CLEAN_DCACHE_RANGE
#undef HAVE_INVALIDATE_DCACHE_RANGE
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@ -1091,26 +1086,16 @@ sam_allocdesc(struct sam_xdmach_s *xdmach, struct chnext_view1_s *prev,
xdmach->lltail = descr; xdmach->lltail = descr;
#ifdef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */
/* Assume that we will be doing multiple buffer transfers and that /* Assume that we will be doing multiple buffer transfers and that
* that hardware will be accessing the descriptor via DMA. * that hardware will be accessing the descriptor via DMA.
*/ */
arch_clean_dcache((uintptr_t)descr, arch_clean_dcache((uintptr_t)descr,
(uintptr_t)descr + sizeof(struct chnext_view1_s)); (uintptr_t)descr + sizeof(struct chnext_view1_s));
#endif
break; break;
} }
} }
#ifndef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */
/* Assume that we will be doing multiple buffer transfers and that
* that hardware will be accessing the descriptors via DMA.
*/
arch_clean_dcache_all();
#endif
/* Because we hold a count from the counting semaphore, the above /* Because we hold a count from the counting semaphore, the above
* search loop should always be successful. * search loop should always be successful.
*/ */
@ -1503,17 +1488,6 @@ static void sam_dmaterminate(struct sam_xdmach_s *xdmach, int result)
sam_freelinklist(xdmach); sam_freelinklist(xdmach);
#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */
/* If this was an RX DMA (peripheral-to-memory), then invalidate the cache
* to force reloads from memory.
*/
if (xdmach->rx)
{
arch_invalidate_dcache(xdmach->rxaddr, xdmach->rxaddr + xdmach->rxsize);
}
#endif
/* Perform the DMA complete callback */ /* Perform the DMA complete callback */
if (xdmach->callback) if (xdmach->callback)
@ -1873,11 +1847,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
/* Clean caches associated with the DMA memory */ /* Clean caches associated with the DMA memory */
#ifdef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */
arch_clean_dcache(maddr, maddr + nbytes); arch_clean_dcache(maddr, maddr + nbytes);
#else
arch_clean_dcache_all();
#endif
return ret; return ret;
} }
@ -1958,11 +1928,7 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
/* Clean caches associated with the DMA memory */ /* Clean caches associated with the DMA memory */
#ifdef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */
arch_clean_dcache(maddr, maddr + nbytes); arch_clean_dcache(maddr, maddr + nbytes);
#else
arch_clean_dcache_all();
#endif
return ret; return ret;
} }
@ -1993,17 +1959,15 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
xdmach->callback = callback; xdmach->callback = callback;
xdmach->arg = arg; xdmach->arg = arg;
#ifndef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */
/* If this is an RX DMA (peripheral-to-memory), then flush and /* If this is an RX DMA (peripheral-to-memory), then flush and
* invalidate the data cache to force reloading from memory when the * invalidate the data cache to force reloading from memory when the
* DMA completes. * DMA completes.
*/ */
if (xdmach->rx) if (xdmach->rx)
{ {
arch_flush_dcache_all(); arch_flush_dcache(xdmach->rxaddr, xdmach->rxaddr + xdmach->rxsize);
} }
#endif
/* Is this a single block transfer? Or a multiple block transfer? */ /* Is this a single block transfer? Or a multiple block transfer? */