imxrt:serial Ensure the cache is updated if the DMA has updated again
The DMA can bring in more rx data, than the number of DMA completions call backs. The call back happen on idle, 1/2 and full events. But in between these events the DMA can write more data to the buffers memory that need to be brought in to the cache. (invalidate) We do the invalidate on the reads from the fifo memory if the the DMA as commited since the last read.
This commit is contained in:
parent
87d6084f31
commit
611309b956
@ -1373,6 +1373,7 @@ static inline void imxrt_serialout(struct imxrt_uart_s *priv,
|
|||||||
static int imxrt_dma_nextrx(struct imxrt_uart_s *priv)
|
static int imxrt_dma_nextrx(struct imxrt_uart_s *priv)
|
||||||
{
|
{
|
||||||
int dmaresidual = imxrt_dmach_getcount(priv->rxdma);
|
int dmaresidual = imxrt_dmach_getcount(priv->rxdma);
|
||||||
|
DEBUGASSERT(dmaresidual <= RXDMA_BUFFER_SIZE);
|
||||||
|
|
||||||
return RXDMA_BUFFER_SIZE - dmaresidual;
|
return RXDMA_BUFFER_SIZE - dmaresidual;
|
||||||
}
|
}
|
||||||
@ -2346,6 +2347,7 @@ static bool imxrt_rxflowcontrol(struct uart_dev_s *dev,
|
|||||||
static int imxrt_dma_receive(struct uart_dev_s *dev, unsigned int *status)
|
static int imxrt_dma_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||||
{
|
{
|
||||||
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev;
|
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev;
|
||||||
|
static uint32_t last_nextrx = -1;
|
||||||
uint32_t nextrx = imxrt_dma_nextrx(priv);
|
uint32_t nextrx = imxrt_dma_nextrx(priv);
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
@ -2353,6 +2355,17 @@ static int imxrt_dma_receive(struct uart_dev_s *dev, unsigned int *status)
|
|||||||
|
|
||||||
if (nextrx != priv->rxdmanext)
|
if (nextrx != priv->rxdmanext)
|
||||||
{
|
{
|
||||||
|
/* Now we must ensure the cache is updated if the DMA has
|
||||||
|
* updated again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (last_nextrx != nextrx)
|
||||||
|
{
|
||||||
|
up_invalidate_dcache((uintptr_t)priv->rxfifo,
|
||||||
|
(uintptr_t)priv->rxfifo + RXDMA_BUFFER_SIZE);
|
||||||
|
last_nextrx = nextrx;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now read from the DMA buffer */
|
/* Now read from the DMA buffer */
|
||||||
|
|
||||||
c = priv->rxfifo[priv->rxdmanext];
|
c = priv->rxfifo[priv->rxdmanext];
|
||||||
@ -2721,9 +2734,6 @@ static void imxrt_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
|
|||||||
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)arg;
|
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)arg;
|
||||||
uint32_t sr;
|
uint32_t sr;
|
||||||
|
|
||||||
up_invalidate_dcache((uintptr_t)priv->rxfifo,
|
|
||||||
(uintptr_t)priv->rxfifo + RXDMA_BUFFER_SIZE);
|
|
||||||
|
|
||||||
if (priv->rxenable && imxrt_dma_rxavailable(&priv->dev))
|
if (priv->rxenable && imxrt_dma_rxavailable(&priv->dev))
|
||||||
{
|
{
|
||||||
uart_recvchars(&priv->dev);
|
uart_recvchars(&priv->dev);
|
||||||
|
Loading…
Reference in New Issue
Block a user