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

commit a513770fcb98bfbf4c122df0bed206416de7f61a
Author: Tiago Medicci Serrano <[email protected]>
AuthorDate: Wed Aug 23 16:11:18 2023 -0300

    esp32s3/dma: Split the setup and load of the DMA descriptors
    
    By splitting into two different functions the setup of the DMA
    descriptors and the action of loading it to the GDMA outlink
    register, it enables us to "cache" DMA descriptors ready to be send
    and, then, just load them whenever we are able to actually send it.
---
 arch/xtensa/src/esp32s3/esp32s3_dma.c       | 48 +++++++++++++++++++++--------
 arch/xtensa/src/esp32s3/esp32s3_dma.h       | 37 ++++++++++++++++------
 arch/xtensa/src/esp32s3/esp32s3_qspi.c      | 10 +++---
 arch/xtensa/src/esp32s3/esp32s3_spi.c       |  8 ++---
 arch/xtensa/src/esp32s3/esp32s3_spi_slave.c | 10 +++---
 5 files changed, 74 insertions(+), 39 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.c 
b/arch/xtensa/src/esp32s3/esp32s3_dma.c
index 6381459c5f..6c05b26851 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.c
@@ -174,23 +174,21 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e 
periph,
  * Name: esp32s3_dma_setup
  *
  * Description:
- *   Set up DMA descriptor with given parameters.
+ *   Initialize the DMA inlink/outlink (linked list) and bind the target
+ *   buffer to its DMA descriptors.
  *
  * Input Parameters:
- *   chan    - DMA channel
- *   tx      - true: TX mode; false: RX mode
- *   dmadesc - DMA descriptor pointer
- *   num     - DMA descriptor number
- *   pbuf    - Buffer pointer
- *   len     - Buffer length by byte
+ *   dmadesc - Pointer to the DMA descriptors
+ *   num     - Number of DMA descriptors
+ *   pbuf    - RX/TX buffer pointer
+ *   len     - RX/TX buffer length
  *
  * Returned Value:
- *   Bind pbuf data bytes.
+ *   Bound pbuf data bytes
  *
  ****************************************************************************/
 
-uint32_t esp32s3_dma_setup(int chan, bool tx,
-                           struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
+uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
                            uint8_t *pbuf, uint32_t len)
 {
   int i;
@@ -200,7 +198,6 @@ uint32_t esp32s3_dma_setup(int chan, bool tx,
   uint32_t data_len;
   uint32_t buf_len;
 
-  DEBUGASSERT(chan >= 0);
   DEBUGASSERT(dmadesc != NULL);
   DEBUGASSERT(num > 0);
   DEBUGASSERT(pbuf != NULL);
@@ -232,6 +229,33 @@ uint32_t esp32s3_dma_setup(int chan, bool tx,
   dmadesc[i].ctrl |= ESP32S3_DMA_CTRL_EOF;
   dmadesc[i].next  = NULL;
 
+  return len - bytes;
+}
+
+/****************************************************************************
+ * Name: esp32s3_dma_load
+ *
+ * Description:
+ *   Load the address of the first DMA descriptor of an already bound
+ *   inlink/outlink to the corresponding GDMA_<IN/OUT>LINK_ADDR_CHn register
+ *
+ * Input Parameters:
+ *   chan    - DMA channel of the receiver/transmitter
+ *   tx      - true: TX mode (transmitter); false: RX mode (receiver)
+ *   dmadesc - Pointer of the previously bound inlink/outlink
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_load(struct esp32s3_dmadesc_s *dmadesc, int chan, bool tx)
+{
+  uint32_t regval;
+
+  DEBUGASSERT(chan >= 0);
+  DEBUGASSERT(dmadesc != NULL);
+
   if (tx)
     {
       /* Reset DMA TX channel FSM and FIFO pointer */
@@ -258,8 +282,6 @@ uint32_t esp32s3_dma_setup(int chan, bool tx,
       CLR_BITS(DMA_IN_LINK_CH0_REG, chan, DMA_INLINK_ADDR_CH0);
       SET_BITS(DMA_IN_LINK_CH0_REG, chan, regval);
     }
-
-  return len - bytes;
 }
 
 /****************************************************************************
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h 
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index 913e744587..8af366b8c3 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -132,25 +132,42 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e 
periph,
  * Name: esp32s3_dma_setup
  *
  * Description:
- *   Set up DMA descriptor with given parameters.
+ *   Initialize the DMA inlink/outlink (linked list) and bind the target
+ *   buffer to its DMA descriptors.
  *
  * Input Parameters:
- *   chan    - DMA channel
- *   tx      - true: TX mode; false: RX mode
- *   dmadesc - DMA descriptor pointer
- *   num     - DMA descriptor number
- *   pbuf    - Buffer pointer
- *   len     - Buffer length by byte
+ *   dmadesc - Pointer to the DMA descriptors
+ *   num     - Number of DMA descriptors
+ *   pbuf    - RX/TX buffer pointer
+ *   len     - RX/TX buffer length
  *
  * Returned Value:
- *   Bind pbuf data bytes.
+ *   Bound pbuf data bytes
  *
  ****************************************************************************/
 
-uint32_t esp32s3_dma_setup(int chan, bool tx,
-                           struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
+uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
                            uint8_t *pbuf, uint32_t len);
 
+/****************************************************************************
+ * Name: esp32s3_dma_load
+ *
+ * Description:
+ *   Load the address of the first DMA descriptor of an already bound
+ *   inlink/outlink to the corresponding GDMA_<IN/OUT>LINK_ADDR_CHn register
+ *
+ * Input Parameters:
+ *   chan    - DMA channel of the receiver/transmitter
+ *   tx      - true: TX mode (transmitter); false: RX mode (receiver)
+ *   dmadesc - Pointer of the previously bound inlink/outlink
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_load(struct esp32s3_dmadesc_s *dmadesc, int chan, bool tx);
+
 /****************************************************************************
  * Name: esp32s3_dma_enable
  *
diff --git a/arch/xtensa/src/esp32s3/esp32s3_qspi.c 
b/arch/xtensa/src/esp32s3/esp32s3_qspi.c
index 1438522257..deffcee405 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_qspi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_qspi.c
@@ -975,12 +975,11 @@ static int esp32s3_qspi_memory(struct qspi_dev_s *dev,
           user_reg |= SPI_FWRITE_QUAD_M;
         }
 
-      esp32s3_dma_setup(priv->dma_channel,
-                        true,
-                        priv->dma_desc,
+      esp32s3_dma_setup(priv->dma_desc,
                         QSPI_DMA_DESC_NUM,
                         (uint8_t *)meminfo->buffer,
                         meminfo->buflen);
+      esp32s3_dma_load(priv->dma_desc, priv->dma_channel, true);
       esp32s3_dma_enable(priv->dma_channel, true);
     }
   else if (QSPIMEM_ISREAD(meminfo->flags))
@@ -991,12 +990,11 @@ static int esp32s3_qspi_memory(struct qspi_dev_s *dev,
 
       user_reg |= SPI_USR_MISO_M;
 
-      esp32s3_dma_setup(priv->dma_channel,
-                        false,
-                        priv->dma_desc,
+      esp32s3_dma_setup(priv->dma_desc,
                         QSPI_DMA_DESC_NUM,
                         (uint8_t *)meminfo->buffer,
                         meminfo->buflen);
+      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 b7f048599d..5e35abc960 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi.c
@@ -904,8 +904,8 @@ static void esp32s3_spi_dma_exchange(struct 
esp32s3_spi_priv_s *priv,
       esp32s3_spi_set_regbits(SPI_DMA_CONF_REG(priv->config->id),
                               SPI_DMA_TX_ENA_M);
 
-      n = esp32s3_dma_setup(channel, true, priv->dma_txdesc,
-                            SPI_DMA_DESC_NUM, tp, bytes);
+      n = esp32s3_dma_setup(priv->dma_txdesc, SPI_DMA_DESC_NUM, tp, bytes);
+      esp32s3_dma_load(priv->dma_txdesc, channel, true);
       esp32s3_dma_enable(channel, true);
 
       putreg32((n * 8 - 1), SPI_MS_DLEN_REG(priv->config->id));
@@ -921,8 +921,8 @@ static void esp32s3_spi_dma_exchange(struct 
esp32s3_spi_priv_s *priv,
           esp32s3_spi_set_regbits(SPI_DMA_CONF_REG(priv->config->id),
                                   SPI_DMA_RX_ENA_M);
 
-          esp32s3_dma_setup(channel, false, priv->dma_rxdesc,
-                            SPI_DMA_DESC_NUM, rp, bytes);
+          esp32s3_dma_setup(priv->dma_rxdesc, SPI_DMA_DESC_NUM, rp, bytes);
+          esp32s3_dma_load(priv->dma_rxdesc, channel, false);
           esp32s3_dma_enable(channel, false);
 
           esp32s3_spi_set_regbits(SPI_USER_REG(priv->config->id),
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c 
b/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
index 27ba2257f4..3dce48bab4 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
@@ -900,12 +900,11 @@ static void spislave_setup_rx_dma(struct spislave_priv_s 
*priv)
 {
   uint32_t length = SPI_SLAVE_BUFSIZE - priv->rx_length;
 
-  esp32s3_dma_setup(priv->dma_channel,
-                    false,
-                    priv->dma_rxdesc,
+  esp32s3_dma_setup(priv->dma_rxdesc,
                     SPI_DMA_DESC_NUM,
                     priv->rx_buffer + priv->rx_length,
                     length);
+  esp32s3_dma_load(priv->dma_rxdesc, priv->dma_channel, false);
 
   priv->rx_dma_offset = priv->rx_length;
 
@@ -944,12 +943,11 @@ static void spislave_setup_rx_dma(struct spislave_priv_s 
*priv)
 #ifdef CONFIG_ESP32S3_SPI_DMA
 static void spislave_setup_tx_dma(struct spislave_priv_s *priv)
 {
-  esp32s3_dma_setup(priv->dma_channel,
-                    true,
-                    priv->dma_txdesc,
+  esp32s3_dma_setup(priv->dma_txdesc,
                     SPI_DMA_DESC_NUM,
                     priv->tx_buffer,
                     SPI_SLAVE_BUFSIZE);
+  esp32s3_dma_load(priv->dma_txdesc, priv->dma_channel, true);
 
   spislave_dma_tx_fifo_reset(priv);
 

Reply via email to