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).