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

acassis 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 bdd02cc624 xtensa/esp32s3: Add APIs to release DMA channel resources
bdd02cc624 is described below

commit bdd02cc624efe3fd2a9a078535ec21c848b2fcca
Author: chen...@espressif.com <chen...@espressif.com>
AuthorDate: Fri Jan 5 10:54:25 2024 +0800

    xtensa/esp32s3: Add APIs to release DMA channel resources
    
    Signed-off-by: chen...@espressif.com <chen...@espressif.com>
---
 arch/xtensa/src/esp32s3/esp32s3_dma.c | 87 +++++++++++++++++++++++++++++++++++
 arch/xtensa/src/esp32s3/esp32s3_dma.h | 32 +++++++++++++
 arch/xtensa/src/esp32s3/esp32s3_spi.c | 60 ++++++++++++++++++------
 arch/xtensa/src/esp32s3/esp32s3_spi.h |  4 +-
 4 files changed, 167 insertions(+), 16 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.c 
b/arch/xtensa/src/esp32s3/esp32s3_dma.c
index 203ba7f130..5c21f371c4 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.c
@@ -52,6 +52,8 @@
 #  define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
 #endif
 
+#define DMA_INVALID_PERIPH_ID        (0x3F)
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -166,6 +168,55 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e 
periph,
   return chan;
 }
 
+/****************************************************************************
+ * Name: esp32s3_dma_release
+ *
+ * Description:
+ *   Release DMA channel from peripheral.
+ *
+ * Input Parameters:
+ *   chan - Peripheral for which the DMA channel request was made
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_release(int chan)
+{
+  DEBUGASSERT(chan  < ESP32S3_DMA_CHAN_MAX);
+
+  nxmutex_lock(&g_dma_lock);
+
+  /* Disconnect DMA TX channel from peripheral */
+
+  SET_GDMA_CH_REG(DMA_OUT_PERI_SEL_CH0_REG, chan, DMA_INVALID_PERIPH_ID);
+
+  /* Disconnect DMA RX channel from peripheral */
+
+  SET_GDMA_CH_REG(DMA_IN_PERI_SEL_CH0_REG, chan, DMA_INVALID_PERIPH_ID);
+  CLR_GDMA_CH_BITS(DMA_IN_CONF0_CH0_REG, chan, DMA_MEM_TRANS_EN_CH0_M);
+
+  /* Disable DMA TX/RX channels burst sending data */
+
+  CLR_GDMA_CH_BITS(DMA_OUT_CONF0_CH0_REG, chan, DMA_OUT_DATA_BURST_EN_CH0_M);
+  CLR_GDMA_CH_BITS(DMA_IN_CONF0_CH0_REG, chan, DMA_IN_DATA_BURST_EN_CH0_M);
+
+  /* Disable DMA TX/RX channels burst reading descriptor link */
+
+  CLR_GDMA_CH_BITS(DMA_OUT_CONF0_CH0_REG, chan, DMA_OUTDSCR_BURST_EN_CH0_M);
+  CLR_GDMA_CH_BITS(DMA_IN_CONF0_CH0_REG, chan, DMA_INDSCR_BURST_EN_CH0_M);
+
+  /* Reset the priority to 0 (lowest) */
+
+  SET_GDMA_CH_REG(DMA_OUT_PRI_CH0_REG, chan, 0);
+  SET_GDMA_CH_REG(DMA_IN_PRI_CH0_REG, chan, 0);
+
+  g_dma_chan_used[chan] = false;
+
+  nxmutex_unlock(&g_dma_lock);
+}
+
 /****************************************************************************
  * Name: esp32s3_dma_setup
  *
@@ -463,3 +514,39 @@ void esp32s3_dma_init(void)
   nxmutex_unlock(&g_dma_lock);
 }
 
+/****************************************************************************
+ * Name: esp32s3_dma_deinit
+ *
+ * Description:
+ *   Deinitialize DMA driver.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_deinit(void)
+{
+  nxmutex_lock(&g_dma_lock);
+
+  g_dma_ref--;
+
+  if (!g_dma_ref)
+    {
+      /* Disable DMA clock gating */
+
+      modifyreg32(DMA_MISC_CONF_REG, DMA_CLK_EN_M, 0);
+
+      /* Disable DMA module by gating the clock and asserting the reset
+       * signal.
+       */
+
+      modifyreg32(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN_M, 0);
+      modifyreg32(SYSTEM_PERIP_RST_EN1_REG, 0, SYSTEM_DMA_RST_M);
+    }
+
+  nxmutex_unlock(&g_dma_lock);
+}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h 
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index a7b5a2984a..bb9c762ec5 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -145,6 +145,22 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e 
periph,
                             uint32_t rx_prio,
                             bool burst_en);
 
+/****************************************************************************
+ * Name: esp32s3_dma_release
+ *
+ * Description:
+ *   Release DMA channel from peripheral.
+ *
+ * Input Parameters:
+ *   chan - Peripheral for which the DMA channel request was made
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_release(int chan);
+
 /****************************************************************************
  * Name: esp32s3_dma_setup
  *
@@ -272,6 +288,22 @@ void esp32s3_dma_set_ext_memblk(int chan, bool tx,
 
 void esp32s3_dma_init(void);
 
+/****************************************************************************
+ * Name: esp32s3_dma_deinit
+ *
+ * Description:
+ *   Deinitialize DMA driver.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_deinit(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi.c 
b/arch/xtensa/src/esp32s3/esp32s3_spi.c
index 2c0d2a6c46..5f26902981 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi.c
@@ -430,8 +430,8 @@ static struct esp32s3_spi_priv_s esp32s3_spi3_priv =
  *   Set the bits of the SPI register.
  *
  * Input Parameters:
- *   addr   - Address of the register of interest
- *   bits   - Bits to be set
+ *   addr - Address of the register of interest
+ *   bits - Bits to be set
  *
  * Returned Value:
  *   None.
@@ -452,8 +452,8 @@ static inline void esp32s3_spi_set_regbits(uint32_t addr, 
uint32_t bits)
  *   Clear the bits of the SPI register.
  *
  * Input Parameters:
- *   addr   - Address of the register of interest
- *   bits   - Bits to be cleared
+ *   addr - Address of the register of interest
+ *   bits - Bits to be cleared
  *
  * Returned Value:
  *   None.
@@ -511,8 +511,8 @@ static inline bool esp32s3_spi_iomux(struct 
esp32s3_spi_priv_s *priv)
  *   Lock or unlock the SPI device.
  *
  * Input Parameters:
- *   dev    - Device-specific state data
- *   lock   - true: Lock SPI bus, false: unlock SPI bus
+ *   dev  - Device-specific state data
+ *   lock - true: Lock SPI bus, false: unlock SPI bus
  *
  * Returned Value:
  *   The result of lock or unlock the SPI device.
@@ -1302,7 +1302,7 @@ static void esp32s3_spi_recvblock(struct spi_dev_s *dev,
  *   Trigger a previously configured DMA transfer.
  *
  * Input Parameters:
- *   dev      - Device-specific state data
+ *   dev - Device-specific state data
  *
  * Returned Value:
  *   OK       - Trigger was fired
@@ -1318,6 +1318,8 @@ static int esp32s3_spi_trigger(struct spi_dev_s *dev)
 }
 #endif
 
+#ifdef CONFIG_ESP32S3_SPI_DMA
+
 /****************************************************************************
  * Name: esp32s3_spi_dma_init
  *
@@ -1325,14 +1327,13 @@ static int esp32s3_spi_trigger(struct spi_dev_s *dev)
  *   Initialize ESP32-S3 SPI connection to GDMA engine.
  *
  * Input Parameters:
- *   dev      - Device-specific state data
+ *   dev - Device-specific state data
  *
  * Returned Value:
  *   None.
  *
  ****************************************************************************/
 
-#ifdef CONFIG_ESP32S3_SPI_DMA
 void esp32s3_spi_dma_init(struct spi_dev_s *dev)
 {
   struct esp32s3_spi_priv_s *priv = (struct esp32s3_spi_priv_s *)dev;
@@ -1374,6 +1375,37 @@ void esp32s3_spi_dma_init(struct spi_dev_s *dev)
   putreg32((SPI_SLV_RX_SEG_TRANS_CLR_EN_M | SPI_SLV_TX_SEG_TRANS_CLR_EN_M),
            SPI_DMA_CONF_REG(priv->config->id));
 }
+
+/****************************************************************************
+ * Name: esp32s3_spi_dma_deinit
+ *
+ * Description:
+ *   Deinitialize ESP32-S3 SPI GDMA engine.
+ *
+ * Input Parameters:
+ *   dev - Device-specific state data
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_spi_dma_deinit(struct spi_dev_s *dev)
+{
+  struct esp32s3_spi_priv_s *priv = (struct esp32s3_spi_priv_s *)dev;
+
+  /* Release a DMA channel from peripheral */
+
+  esp32s3_dma_release(priv->dma_channel);
+
+  /* Deinitialize DMA controller */
+
+  esp32s3_dma_deinit();
+
+  /* Disable DMA clock for the SPI peripheral */
+
+  modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, priv->config->dma_clk_bit, 0);
+}
 #endif
 
 /****************************************************************************
@@ -1383,7 +1415,7 @@ void esp32s3_spi_dma_init(struct spi_dev_s *dev)
  *   Initialize ESP32-S3 SPI hardware interface.
  *
  * Input Parameters:
- *   dev      - Device-specific state data
+ *   dev - Device-specific state data
  *
  * Returned Value:
  *   None.
@@ -1476,7 +1508,7 @@ static void esp32s3_spi_init(struct spi_dev_s *dev)
  *   Deinitialize ESP32-S3 SPI hardware interface.
  *
  * Input Parameters:
- *   dev      - Device-specific state data
+ *   dev - Device-specific state data
  *
  * Returned Value:
  *   None.
@@ -1488,7 +1520,7 @@ static void esp32s3_spi_deinit(struct spi_dev_s *dev)
   struct esp32s3_spi_priv_s *priv = (struct esp32s3_spi_priv_s *)dev;
 
 #ifdef CONFIG_ESP32S3_SPI_DMA
-  modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, priv->config->dma_clk_bit, 0);
+  esp32s3_spi_dma_deinit(dev);
 #endif
 
   modifyreg32(SYSTEM_PERIP_RST_EN0_REG, 0, priv->config->clk_bit);
@@ -1538,7 +1570,7 @@ static int esp32s3_spi_interrupt(int irq, void *context, 
void *arg)
  *   Initialize the selected SPI bus.
  *
  * Input Parameters:
- *   port     - Port number (for hardware that has multiple SPI interfaces)
+ *   port - Port number (for hardware that has multiple SPI interfaces)
  *
  * Returned Value:
  *   Valid SPI device structure reference on success; NULL on failure.
@@ -1637,7 +1669,7 @@ struct spi_dev_s *esp32s3_spibus_initialize(int port)
  *   Uninitialize an SPI bus.
  *
  * Input Parameters:
- *   dev      - Device-specific state data
+ *   dev - Device-specific state data
  *
  * Returned Value:
  *   Zero (OK) is returned on success. Otherwise -1 (ERROR).
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi.h 
b/arch/xtensa/src/esp32s3/esp32s3_spi.h
index 3afed087b7..37e7565d2c 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi.h
@@ -69,7 +69,7 @@ extern "C"
  *   Initialize the selected SPI bus.
  *
  * Input Parameters:
- *   port     - Port number (for hardware that has multiple SPI interfaces)
+ *   port - Port number (for hardware that has multiple SPI interfaces)
  *
  * Returned Value:
  *   Valid SPI device structure reference on success; NULL on failure
@@ -134,7 +134,7 @@ int esp32s3_spi3_cmddata(struct spi_dev_s *dev,
  *   Uninitialize an SPI bus.
  *
  * Input Parameters:
- *   dev      - Device-specific state data
+ *   dev - Device-specific state data
  *
  * Returned Value:
  *   Zero (OK) is returned on success.  Otherwise -1 (ERROR).

Reply via email to