xtensa/esp32s3: Add APIs to release DMA channel resources

Signed-off-by: chenwen@espressif.com <chenwen@espressif.com>
This commit is contained in:
chenwen@espressif.com 2024-01-05 10:54:25 +08:00 committed by Alan Carvalho de Assis
parent 22110b3b83
commit bdd02cc624
4 changed files with 167 additions and 16 deletions

View File

@ -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);
}

View File

@ -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

View File

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

View File

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