This is an automated email from the ASF dual-hosted git repository.
pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 611309b956 imxrt:serial Ensure the cache is updated if the DMA has
updated again
611309b956 is described below
commit 611309b95690b6a5a5017e3bef9b517e44ace44c
Author: David Sidrane <[email protected]>
AuthorDate: Tue Oct 24 08:45:51 2023 -0700
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.
---
arch/arm/src/imxrt/imxrt_serial.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/arch/arm/src/imxrt/imxrt_serial.c
b/arch/arm/src/imxrt/imxrt_serial.c
index 6a2faf50fc..30a487b553 100644
--- a/arch/arm/src/imxrt/imxrt_serial.c
+++ b/arch/arm/src/imxrt/imxrt_serial.c
@@ -1373,6 +1373,7 @@ static inline void imxrt_serialout(struct imxrt_uart_s
*priv,
static int imxrt_dma_nextrx(struct imxrt_uart_s *priv)
{
int dmaresidual = imxrt_dmach_getcount(priv->rxdma);
+ DEBUGASSERT(dmaresidual <= RXDMA_BUFFER_SIZE);
return RXDMA_BUFFER_SIZE - dmaresidual;
}
@@ -2345,14 +2346,26 @@ static bool imxrt_rxflowcontrol(struct uart_dev_s *dev,
#ifdef SERIAL_HAVE_RXDMA
static int imxrt_dma_receive(struct uart_dev_s *dev, unsigned int *status)
{
- struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev;
- uint32_t nextrx = imxrt_dma_nextrx(priv);
- int c = 0;
+ struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev;
+ static uint32_t last_nextrx = -1;
+ uint32_t nextrx = imxrt_dma_nextrx(priv);
+ int c = 0;
/* Check if more data is available */
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 */
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;
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))
{
uart_recvchars(&priv->dev);