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: [email protected] <[email protected]>
AuthorDate: Fri Jan 5 10:54:25 2024 +0800
xtensa/esp32s3: Add APIs to release DMA channel resources
Signed-off-by: [email protected] <[email protected]>
---
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).