This is an automated email from the ASF dual-hosted git repository.

xiaoxiang 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 53f50c8183 xtensa/esp32s3: Configure DMA maximum buffer size based on 
access to different RAM
53f50c8183 is described below

commit 53f50c818372de344b983e9f584cfc30358f7826
Author: [email protected] <[email protected]>
AuthorDate: Tue Feb 27 19:47:17 2024 +0800

    xtensa/esp32s3: Configure DMA maximum buffer size based on access to 
different RAM
    
    Signed-off-by: [email protected] <[email protected]>
---
 arch/xtensa/src/esp32s3/esp32s3_dma.c       | 52 ++++++++++++++++++++++++++---
 arch/xtensa/src/esp32s3/esp32s3_dma.h       | 13 +++++---
 arch/xtensa/src/esp32s3/esp32s3_i2s.c       | 12 ++++---
 arch/xtensa/src/esp32s3/esp32s3_lcd.c       |  4 +--
 arch/xtensa/src/esp32s3/esp32s3_qspi.c      |  4 +--
 arch/xtensa/src/esp32s3/esp32s3_spi.c       |  4 +--
 arch/xtensa/src/esp32s3/esp32s3_spi_slave.c |  4 +--
 7 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.c 
b/arch/xtensa/src/esp32s3/esp32s3_dma.c
index 5c21f371c4..c786d4945d 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.c
@@ -53,6 +53,7 @@
 #endif
 
 #define DMA_INVALID_PERIPH_ID        (0x3F)
+#define GDMA_CH_REG_ADDR(_r, _ch)    ((_r) + (_ch) * GDMA_REG_OFFSET)
 
 /****************************************************************************
  * Private Data
@@ -230,6 +231,7 @@ void esp32s3_dma_release(int chan)
  *   pbuf    - RX/TX buffer pointer
  *   len     - RX/TX buffer length
  *   tx      - true: TX mode (transmitter); false: RX mode (receiver)
+ *   chan    - DMA channel of the receiver/transmitter
  *
  * Returned Value:
  *   Bound pbuf data bytes
@@ -237,7 +239,7 @@ void esp32s3_dma_release(int chan)
  ****************************************************************************/
 
 uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
-                           uint8_t *pbuf, uint32_t len, bool tx)
+                           uint8_t *pbuf, uint32_t len, bool tx, int chan)
 {
   int i;
   uint32_t regval;
@@ -245,19 +247,59 @@ uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s 
*dmadesc, uint32_t num,
   uint8_t *pdata = pbuf;
   uint32_t data_len;
   uint32_t buf_len;
+  int alignment = 4;
+  int dma_size = ESP32S3_DMA_BUFFER_MAX_SIZE;
+  bool buffer_in_psram = esp32s3_ptr_extram(pdata);
+  int block_size_index = 0;
+  uint32_t addr = GDMA_CH_REG_ADDR(DMA_IN_CONF0_CH0_REG, chan);
+  bool burst_en = REG_GET_FIELD(addr, DMA_IN_DATA_BURST_EN_CH0);
 
   DEBUGASSERT(dmadesc != NULL);
   DEBUGASSERT(num > 0);
   DEBUGASSERT(pbuf != NULL);
   DEBUGASSERT(len > 0);
+  DEBUGASSERT(chan >= 0 && chan  < ESP32S3_DMA_CHAN_MAX);
 
-  for (i = 0; i < num; i++)
+  if (!tx && buffer_in_psram)
+    {
+      addr = GDMA_CH_REG_ADDR(DMA_IN_CONF1_CH0_REG, chan);
+      block_size_index = REG_GET_FIELD(addr, DMA_IN_EXT_MEM_BK_SIZE_CH0);
+      switch (block_size_index)
+        {
+          case ESP32S3_DMA_EXT_MEMBLK_64B:
+            alignment = 64;
+            break;
+
+          case ESP32S3_DMA_EXT_MEMBLK_32B:
+            alignment = 32;
+            break;
+
+          case ESP32S3_DMA_EXT_MEMBLK_16B:
+          default:
+            alignment = 16;
+            break;
+        }
+
+      dma_size = 0x1000 - alignment;
+    }
+  else if(!tx && burst_en)
     {
-      data_len = MIN(bytes, ESP32S3_DMA_BUFLEN_MAX);
+      dma_size = ESP32S3_DMA_BUFLEN_MAX_4B_ALIGNED;
+    }
 
-      /* Buffer length must be rounded to next 32-bit boundary. */
+  for (i = 0; i < num; i++)
+    {
+      data_len = MIN(bytes, dma_size);
+      if (!tx && (burst_en || buffer_in_psram))
+        {
+          /* Buffer length must be rounded to next alignment boundary. */
 
-      buf_len = ALIGN_UP(data_len, sizeof(uintptr_t));
+          buf_len = ALIGN_UP(data_len, alignment);
+        }
+      else
+        {
+          buf_len = data_len;
+        }
 
       dmadesc[i].ctrl = ESP32S3_DMA_CTRL_OWN;
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h 
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index bb9c762ec5..29427d4f14 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -54,13 +54,17 @@ extern "C"
 #define SET_GDMA_CH_BITS(_r, _ch, _b)   modifyreg32((_r) + (_ch) * 
GDMA_REG_OFFSET, 0, (_b))
 #define CLR_GDMA_CH_BITS(_r, _ch, _b)   modifyreg32((_r) + (_ch) * 
GDMA_REG_OFFSET, (_b), 0)
 
-/* DMA max data length */
+/* Maximum size of the buffer that can be attached to DMA descriptor  */
 
-#define ESP32S3_DMA_DATALEN_MAX       (0x1000 - 4)
+#define ESP32S3_DMA_BUFFER_MAX_SIZE       (0x1000 - 1)
+
+/* DMA max data length, and aligned to 4Bytes */
+
+#define ESP32S3_DMA_BUFLEN_MAX_4B_ALIGNED (0x1000 - 4)
 
 /* DMA max buffer length */
 
-#define ESP32S3_DMA_BUFLEN_MAX        ESP32S3_DMA_DATALEN_MAX
+#define ESP32S3_DMA_BUFLEN_MAX        ESP32S3_DMA_BUFFER_MAX_SIZE
 
 /* DMA channel number */
 
@@ -174,6 +178,7 @@ void esp32s3_dma_release(int chan);
  *   pbuf    - RX/TX buffer pointer
  *   len     - RX/TX buffer length
  *   tx      - true: TX mode (transmitter); false: RX mode (receiver)
+ *   chan    - DMA channel of the receiver/transmitter
  *
  * Returned Value:
  *   Bound pbuf data bytes
@@ -181,7 +186,7 @@ void esp32s3_dma_release(int chan);
  ****************************************************************************/
 
 uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
-                           uint8_t *pbuf, uint32_t len, bool tx);
+                           uint8_t *pbuf, uint32_t len, bool tx, int chan);
 
 /****************************************************************************
  * Name: esp32s3_dma_load
diff --git a/arch/xtensa/src/esp32s3/esp32s3_i2s.c 
b/arch/xtensa/src/esp32s3/esp32s3_i2s.c
index 34bda4b3c1..06ee0116c2 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_i2s.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_i2s.c
@@ -895,7 +895,8 @@ static IRAM_ATTR int i2s_txdma_setup(struct esp32s3_i2s_s 
*priv,
 
   bytes_queued = esp32s3_dma_setup(outlink, I2S_DMADESC_NUM,
                                    bfcontainer->buf,
-                                   bfcontainer->nbytes, I2S_TX);
+                                   bfcontainer->nbytes, I2S_TX,
+                                   priv->dma_channel);
 
   if (bytes_queued != bfcontainer->nbytes)
     {
@@ -956,7 +957,8 @@ static int i2s_rxdma_setup(struct esp32s3_i2s_s *priv,
 
   bytes_queued = esp32s3_dma_setup(inlink, I2S_DMADESC_NUM,
                                    bfcontainer->apb->samp,
-                                   bfcontainer->nbytes, I2S_RX);
+                                   bfcontainer->nbytes, I2S_RX,
+                                   priv->dma_channel);
 
   if (bytes_queued != bfcontainer->nbytes)
     {
@@ -2772,12 +2774,12 @@ static int i2s_send(struct i2s_dev_s *dev, struct 
ap_buffer_s *apb,
 
       nbytes -= (nbytes % (priv->data_width / 8));
 
-      if (nbytes > (ESP32S3_DMA_DATALEN_MAX * I2S_DMADESC_NUM))
+      if (nbytes > (ESP32S3_DMA_BUFLEN_MAX * I2S_DMADESC_NUM))
         {
           i2serr("Required buffer size can't fit into DMA outlink "
                  "(exceeds in %" PRIu32 " bytes). Try to increase the "
                  "number of the DMA descriptors (CONFIG_I2S_DMADESC_NUM).",
-                 nbytes - (ESP32S3_DMA_DATALEN_MAX * I2S_DMADESC_NUM));
+                 nbytes - (ESP32S3_DMA_BUFLEN_MAX * I2S_DMADESC_NUM));
           return -EFBIG;
         }
 
@@ -2880,7 +2882,7 @@ static int i2s_receive(struct i2s_dev_s *dev, struct 
ap_buffer_s *apb,
 
       nbytes -= (nbytes % (priv->data_width / 8));
 
-      nbytes = MIN(nbytes, ESP32S3_DMA_DATALEN_MAX);
+      nbytes = MIN(nbytes, ESP32S3_DMA_BUFLEN_MAX);
 
       /* Allocate a buffer container in advance */
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_lcd.c 
b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
index 1615fcb1b6..7d3db754c5 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_lcd.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
@@ -135,7 +135,7 @@
                                    ESP32S3_LCD_DATA_WIDTH)
 
 #define ESP32S3_LCD_DMADESC_NUM   (ESP32S3_LCD_FB_SIZE / \
-                                   ESP32S3_DMA_DATALEN_MAX + 1)
+                                   ESP32S3_DMA_BUFLEN_MAX + 1)
 
 #define ESP32S3_LCD_LAYERS        CONFIG_ESP32S3_LCD_BUFFER_LAYERS
 
@@ -666,7 +666,7 @@ static void esp32s3_lcd_dmasetup(void)
                         ESP32S3_LCD_DMADESC_NUM,
                         layer->framebuffer,
                         ESP32S3_LCD_FB_SIZE,
-                        true);
+                        true, priv->dma_channel);
     }
 }
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_qspi.c 
b/arch/xtensa/src/esp32s3/esp32s3_qspi.c
index 544dfc4607..15b1df582f 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_qspi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_qspi.c
@@ -992,7 +992,7 @@ static int esp32s3_qspi_memory(struct qspi_dev_s *dev,
                         QSPI_DMA_DESC_NUM,
                         (uint8_t *)meminfo->buffer,
                         meminfo->buflen,
-                        true);
+                        true, priv->dma_channel);
       esp32s3_dma_load(priv->dma_desc, priv->dma_channel, true);
       esp32s3_dma_enable(priv->dma_channel, true);
     }
@@ -1008,7 +1008,7 @@ static int esp32s3_qspi_memory(struct qspi_dev_s *dev,
                         QSPI_DMA_DESC_NUM,
                         (uint8_t *)meminfo->buffer,
                         meminfo->buflen,
-                        false);
+                        false, priv->dma_channel);
       esp32s3_dma_load(priv->dma_desc, priv->dma_channel, false);
       esp32s3_dma_enable(priv->dma_channel, false);
     }
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi.c 
b/arch/xtensa/src/esp32s3/esp32s3_spi.c
index 54b1238b2a..03f7f2b460 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi.c
@@ -909,7 +909,7 @@ static void esp32s3_spi_dma_exchange(struct 
esp32s3_spi_priv_s *priv,
                               SPI_DMA_TX_ENA_M);
 
       n = esp32s3_dma_setup(priv->dma_txdesc, SPI_DMA_DESC_NUM,
-                            tp, bytes, true);
+                            tp, bytes, true, priv->dma_channel);
       esp32s3_dma_load(priv->dma_txdesc, channel, true);
       esp32s3_dma_enable(channel, true);
 
@@ -935,7 +935,7 @@ static void esp32s3_spi_dma_exchange(struct 
esp32s3_spi_priv_s *priv,
                                   SPI_DMA_RX_ENA_M);
 
           esp32s3_dma_setup(priv->dma_rxdesc, SPI_DMA_DESC_NUM,
-                            rp, bytes, false);
+                            rp, bytes, false, priv->dma_channel);
           esp32s3_dma_load(priv->dma_rxdesc, channel, false);
           esp32s3_dma_enable(channel, false);
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c 
b/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
index a763563a3b..b193123031 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
@@ -904,7 +904,7 @@ static void spislave_setup_rx_dma(struct spislave_priv_s 
*priv)
                     SPI_DMA_DESC_NUM,
                     priv->rx_buffer + priv->rx_length,
                     length,
-                    false);
+                    false, priv->dma_channel);
   esp32s3_dma_load(priv->dma_rxdesc, priv->dma_channel, false);
 
   priv->rx_dma_offset = priv->rx_length;
@@ -948,7 +948,7 @@ static void spislave_setup_tx_dma(struct spislave_priv_s 
*priv)
                     SPI_DMA_DESC_NUM,
                     priv->tx_buffer,
                     SPI_SLAVE_BUFSIZE,
-                    true);
+                    true, priv->dma_channel);
   esp32s3_dma_load(priv->dma_txdesc, priv->dma_channel, true);
 
   spislave_dma_tx_fifo_reset(priv);

Reply via email to