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
The following commit(s) were added to refs/heads/master by this push:
new a83a569652 arch/xtensa/esp32s3: Add qspi/spi_slave/lcd DMA request
return value. Optimize DMA initialization for duplicate
calls.
a83a569652 is described below
commit a83a569652da88b73f04c4cc1c33879ee72476f9
Author: nuttxs <[email protected]>
AuthorDate: Tue Jul 23 17:38:34 2024 +0800
arch/xtensa/esp32s3: Add qspi/spi_slave/lcd DMA request return value.
Optimize DMA initialization for duplicate calls.
---
arch/xtensa/src/esp32s3/esp32s3_dma.c | 53 +++--------------------------
arch/xtensa/src/esp32s3/esp32s3_dma.h | 16 ---------
arch/xtensa/src/esp32s3/esp32s3_i2s.c | 5 ---
arch/xtensa/src/esp32s3/esp32s3_lcd.c | 33 ++++++++++++------
arch/xtensa/src/esp32s3/esp32s3_qspi.c | 47 +++++++++++++++----------
arch/xtensa/src/esp32s3/esp32s3_spi.c | 10 ------
arch/xtensa/src/esp32s3/esp32s3_spi_slave.c | 37 +++++++++++---------
arch/xtensa/src/esp32s3/esp32s3_start.c | 7 ++++
8 files changed, 84 insertions(+), 124 deletions(-)
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.c
b/arch/xtensa/src/esp32s3/esp32s3_dma.c
index c786d4945d..0f77803ad9 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.c
@@ -61,7 +61,6 @@
static bool g_dma_chan_used[ESP32S3_DMA_CHAN_MAX];
static mutex_t g_dma_lock = NXMUTEX_INITIALIZER;
-static int g_dma_ref;
/****************************************************************************
* Public Functions
@@ -541,54 +540,10 @@ void esp32s3_dma_set_ext_memblk(int chan, bool tx,
void esp32s3_dma_init(void)
{
- nxmutex_lock(&g_dma_lock);
-
- if (!g_dma_ref)
- {
- modifyreg32(SYSTEM_PERIP_CLK_EN1_REG, 0, SYSTEM_DMA_CLK_EN_M);
- modifyreg32(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST_M, 0);
-
- modifyreg32(DMA_MISC_CONF_REG, 0, DMA_CLK_EN_M);
- }
-
- g_dma_ref++;
-
- 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);
+ modifyreg32(SYSTEM_PERIP_CLK_EN1_REG, 0, SYSTEM_DMA_CLK_EN_M);
+ modifyreg32(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST_M, 0);
- g_dma_ref--;
+ /* enable DMA clock gating */
- 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);
+ modifyreg32(DMA_MISC_CONF_REG, 0, DMA_CLK_EN_M);
}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index 29427d4f14..74e28e0649 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -293,22 +293,6 @@ 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_i2s.c
b/arch/xtensa/src/esp32s3/esp32s3_i2s.c
index 06ee0116c2..18fa10e5f4 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_i2s.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_i2s.c
@@ -3053,10 +3053,6 @@ static int i2s_dma_setup(struct esp32s3_i2s_s *priv)
int ret;
int i2s_dma_dev;
- /* Initialize GDMA controller */
-
- esp32s3_dma_init();
-
if (priv->config->port == 0)
{
i2s_dma_dev = ESP32S3_DMA_PERIPH_I2S0;
@@ -3072,7 +3068,6 @@ static int i2s_dma_setup(struct esp32s3_i2s_s *priv)
if (priv->dma_channel < 0)
{
i2serr("Failed to allocate GDMA channel\n");
-
return ERROR;
}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_lcd.c
b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
index 7d84e627e0..4b24eac29a 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_lcd.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
@@ -246,7 +246,7 @@ static int esp32s3_lcd_base_updatearea(struct fb_vtable_s
*vtable,
/* Initialization ***********************************************************/
-static void esp32s3_lcd_dmasetup(void);
+static int esp32s3_lcd_dmasetup(void);
static void esp32s3_lcd_gpio_config(void);
static void esp32s3_lcd_disable(void);
static void esp32s3_lcd_enable(void);
@@ -638,19 +638,22 @@ static int IRAM_ATTR lcd_interrupt(int irq, void
*context, void *arg)
* None
*
* Returned Value:
- * None
+ * Zero on success; a negated errno on failure
*
****************************************************************************/
-static void esp32s3_lcd_dmasetup(void)
+static int esp32s3_lcd_dmasetup(void)
{
struct esp32s3_lcd_s *priv = &g_lcd_priv;
- esp32s3_dma_init();
-
priv->dma_channel = esp32s3_dma_request(ESP32S3_DMA_PERIPH_LCDCAM,
10, 1, true);
- DEBUGASSERT(priv->dma_channel >= 0);
+ if (priv->dma_channel < 0)
+ {
+ spierr("Failed to allocate GDMA channel\n");
+ return ERROR;
+ }
+
esp32s3_dma_set_ext_memblk(priv->dma_channel,
true,
ESP32S3_DMA_EXT_MEMBLK_64B);
@@ -669,6 +672,8 @@ static void esp32s3_lcd_dmasetup(void)
ESP32S3_LCD_FB_SIZE,
true, priv->dma_channel);
}
+
+ return OK;
}
/****************************************************************************
@@ -758,11 +763,11 @@ static void esp32s3_lcd_enableclk(void)
* None
*
* Returned Value:
- * None
+ * OK on success; A negated errno value on failure.
*
****************************************************************************/
-static void esp32s3_lcd_config(void)
+static int esp32s3_lcd_config(void)
{
uint32_t regval;
irqstate_t flags;
@@ -830,7 +835,10 @@ static void esp32s3_lcd_config(void)
/* Set GDMA */
- esp32s3_lcd_dmasetup();
+ if (esp32s3_lcd_dmasetup() != OK)
+ {
+ return ERROR;
+ }
/* Configure interrupt */
@@ -851,6 +859,8 @@ static void esp32s3_lcd_config(void)
spin_unlock_irqrestore(&priv->lock, flags);
up_enable_irq(ESP32S3_IRQ_LCD_CAM);
+
+ return OK;
}
/****************************************************************************
@@ -965,7 +975,10 @@ int up_fbinitialize(int display)
/* Configure LCD controller */
- esp32s3_lcd_config();
+ if (esp32s3_lcd_config() != OK)
+ {
+ return ERROR;
+ }
/* And turn the LCD on */
diff --git a/arch/xtensa/src/esp32s3/esp32s3_qspi.c
b/arch/xtensa/src/esp32s3/esp32s3_qspi.c
index d3fd20326d..ec776b4766 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_qspi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_qspi.c
@@ -236,9 +236,9 @@ static void esp32s3_qspi_free(struct qspi_dev_s *dev, void
*buffer);
#ifdef CONFIG_ESP32S3_SPI_DMA
static int esp32s3_qspi_interrupt(int irq, void *context, void *arg);
static int esp32s3_qspi_wait_sem(struct esp32s3_qspi_priv_s *priv);
-static void esp32s3_qspi_init_dma(struct esp32s3_qspi_priv_s *priv);
+static int esp32s3_qspi_init_dma(struct esp32s3_qspi_priv_s *priv);
#endif
-static void esp32s3_qspi_init(struct esp32s3_qspi_priv_s *priv);
+static int esp32s3_qspi_init(struct esp32s3_qspi_priv_s *priv);
static void esp32s3_qspi_deinit(struct esp32s3_qspi_priv_s *priv);
/****************************************************************************
@@ -1171,12 +1171,12 @@ static int esp32s3_qspi_wait_sem(struct
esp32s3_qspi_priv_s *priv)
* priv - QSPI private state data
*
* Returned Value:
- * None.
+ * Zero on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_ESP32S3_SPI_DMA
-void esp32s3_qspi_init_dma(struct esp32s3_qspi_priv_s *priv)
+static int esp32s3_qspi_init_dma(struct esp32s3_qspi_priv_s *priv)
{
const struct esp32s3_qspi_config_s *config = priv->config;
@@ -1188,24 +1188,21 @@ void esp32s3_qspi_init_dma(struct esp32s3_qspi_priv_s
*priv)
modifyreg32(SYSTEM_PERIP_RST_EN0_REG, config->dma_rst_bit, 0);
- /* Initialize GDMA controller */
-
- esp32s3_dma_init();
-
/* Request a GDMA channel for QSPI peripheral */
priv->dma_channel = esp32s3_dma_request(config->dma_periph, 1, 1, true);
if (priv->dma_channel < 0)
{
spierr("Failed to allocate GDMA channel\n");
-
- DEBUGPANIC();
+ return ERROR;
}
/* Disable segment transaction mode for QSPI Master */
putreg32((SPI_SLV_RX_SEG_TRANS_CLR_EN_M | SPI_SLV_TX_SEG_TRANS_CLR_EN_M),
SPI_DMA_CONF_REG(config->id));
+
+ return OK;
}
/****************************************************************************
@@ -1228,10 +1225,6 @@ void esp32s3_qspi_dma_deinit(struct esp32s3_qspi_priv_s
*priv)
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);
@@ -1368,11 +1361,11 @@ static void esp32s3_qspi_init_gpio(struct
esp32s3_qspi_priv_s *priv)
* priv - QSPI private state data
*
* Returned Value:
- * None.
+ * Zero on success; a negated errno on failure
*
****************************************************************************/
-static void esp32s3_qspi_init(struct esp32s3_qspi_priv_s *priv)
+static int esp32s3_qspi_init(struct esp32s3_qspi_priv_s *priv)
{
const struct esp32s3_qspi_config_s *config = priv->config;
uint8_t id = config->id;
@@ -1394,12 +1387,19 @@ static void esp32s3_qspi_init(struct
esp32s3_qspi_priv_s *priv)
putreg32(0, SPI_CTRL_REG(id));
#ifdef CONFIG_ESP32S3_SPI_DMA
- esp32s3_qspi_init_dma(priv);
+ if (esp32s3_qspi_init_dma(priv) != OK)
+ {
+ modifyreg32(SYSTEM_PERIP_RST_EN0_REG, 0, priv->config->clk_bit);
+ modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, priv->config->clk_bit, 0);
+ return ERROR;
+ }
#endif
esp32s3_qspi_setfrequency(&priv->spi_dev, QSPI_DEFAULT_FREQ);
esp32s3_qspi_setbits(&priv->spi_dev, QSPI_DEFAULT_WIDTH);
esp32s3_qspi_setmode(&priv->spi_dev, QSPI_DEFAULT_MODE);
+
+ return OK;
}
/****************************************************************************
@@ -1603,7 +1603,18 @@ struct qspi_dev_s *esp32s3_qspibus_initialize(int port)
up_enable_irq(priv->config->irq);
#endif
- esp32s3_qspi_init(priv);
+ if (esp32s3_qspi_init(priv) != OK)
+ {
+#ifdef CONFIG_ESP32S3_SPI_DMA
+ up_disable_irq(priv->config->irq);
+ esp32s3_teardown_irq(priv->cpu, priv->config->periph, priv->cpuint);
+ irq_detach(priv->config->irq);
+ priv->cpuint = -ENOMEM;
+#endif
+ nxmutex_unlock(&priv->lock);
+ return NULL;
+ }
+
priv->refs++;
nxmutex_unlock(&priv->lock);
return spi_dev;
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi.c
b/arch/xtensa/src/esp32s3/esp32s3_spi.c
index 03f7f2b460..d8c24e43f0 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi.c
@@ -1349,10 +1349,6 @@ static int esp32s3_spi_dma_init(struct spi_dev_s *dev)
modifyreg32(SYSTEM_PERIP_RST_EN0_REG, priv->config->dma_rst_bit, 0);
- /* Initialize GDMA controller */
-
- esp32s3_dma_init();
-
/* Request a GDMA channel for SPI peripheral */
priv->dma_channel = esp32s3_dma_request(priv->config->dma_periph, 1, 1,
@@ -1360,8 +1356,6 @@ static int esp32s3_spi_dma_init(struct spi_dev_s *dev)
if (priv->dma_channel < 0)
{
spierr("Failed to allocate GDMA channel\n");
-
- esp32s3_dma_deinit();
return ERROR;
}
@@ -1395,10 +1389,6 @@ void esp32s3_spi_dma_deinit(struct spi_dev_s *dev)
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);
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
b/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
index b193123031..86456c088e 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi_slave.c
@@ -267,7 +267,7 @@ static void spislave_prepare_next_tx(struct spislave_priv_s
*priv);
#else
static void spislave_write_tx_buffer(struct spislave_priv_s *priv);
#endif
-static void spislave_initialize(struct spi_slave_ctrlr_s *ctrlr);
+static int spislave_initialize(struct spi_slave_ctrlr_s *ctrlr);
static void spislave_deinitialize(struct spi_slave_ctrlr_s *ctrlr);
/* SPI Slave controller operations */
@@ -1117,7 +1117,7 @@ static int spislave_periph_interrupt(int irq, void
*context, void *arg)
****************************************************************************/
#ifdef CONFIG_ESP32S3_SPI_DMA
-void spislave_dma_init(struct spislave_priv_s *priv)
+static int spislave_dma_init(struct spislave_priv_s *priv)
{
/* Enable GDMA clock for the SPI peripheral */
@@ -1127,10 +1127,6 @@ void spislave_dma_init(struct spislave_priv_s *priv)
resetbits(priv->config->dma_rst_bit, SYSTEM_PERIP_RST_EN0_REG);
- /* Initialize GDMA controller */
-
- esp32s3_dma_init();
-
/* Request a GDMA channel for SPI peripheral */
priv->dma_channel = esp32s3_dma_request(priv->config->dma_periph, 1, 1,
@@ -1138,8 +1134,7 @@ void spislave_dma_init(struct spislave_priv_s *priv)
if (priv->dma_channel < 0)
{
spierr("Failed to allocate GDMA channel\n");
-
- DEBUGPANIC();
+ return ERROR;
}
/* Disable segment transaction mode for SPI Slave */
@@ -1149,6 +1144,8 @@ void spislave_dma_init(struct spislave_priv_s *priv)
/* Configure DMA In-Link EOF to be generated by trans_done */
resetbits(SPI_RX_EOF_EN_M, SPI_DMA_CONF_REG(priv->config->id));
+
+ return OK;
}
/****************************************************************************
@@ -1171,10 +1168,6 @@ void spislave_dma_deinit(struct spislave_priv_s *priv)
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);
@@ -1322,11 +1315,11 @@ static void spislave_gpio_initialize(struct
spislave_priv_s *priv)
* ctrlr - SPI Slave controller interface instance
*
* Returned Value:
- * None.
+ * Zero on success; a negated errno on failure
*
****************************************************************************/
-static void spislave_initialize(struct spi_slave_ctrlr_s *ctrlr)
+static int spislave_initialize(struct spi_slave_ctrlr_s *ctrlr)
{
uint32_t regval;
struct spislave_priv_s *priv = (struct spislave_priv_s *)ctrlr;
@@ -1373,7 +1366,12 @@ static void spislave_initialize(struct spi_slave_ctrlr_s
*ctrlr)
resetbits(SPI_INT_MASK, SPI_DMA_INT_ENA_REG(priv->config->id));
#ifdef CONFIG_ESP32S3_SPI_DMA
- spislave_dma_init(priv);
+ if (spislave_dma_init(priv) != OK)
+ {
+ setbits(priv->config->clk_bit, SYSTEM_PERIP_RST_EN0_REG);
+ resetbits(priv->config->clk_bit, SYSTEM_PERIP_CLK_EN0_REG);
+ return ERROR;
+ }
#endif
esp32s3_gpioirqenable(ESP32S3_PIN2IRQ(config->cs_pin), RISING);
@@ -1392,6 +1390,8 @@ static void spislave_initialize(struct spi_slave_ctrlr_s
*ctrlr)
#endif
setbits(regval, SPI_DMA_INT_RAW_REG(priv->config->id));
setbits(regval, SPI_DMA_INT_ENA_REG(priv->config->id));
+
+ return OK;
}
/****************************************************************************
@@ -1493,7 +1493,12 @@ static void spislave_bind(struct spi_slave_ctrlr_s
*ctrlr,
priv->tx_length = 0;
priv->is_tx_enabled = false;
- spislave_initialize(ctrlr);
+ if (spislave_initialize(ctrlr) != OK)
+ {
+ spierr("spislave_initialize failed!\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+ DEBUGPANIC();
+ }
spislave_setmode(ctrlr, mode);
spislave_setbits(ctrlr, nbits);
diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c
b/arch/xtensa/src/esp32s3/esp32s3_start.c
index 36e853f760..19e77a9f89 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_start.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_start.c
@@ -40,6 +40,7 @@
#include "esp32s3_rtc.h"
#include "esp32s3_spiram.h"
#include "esp32s3_wdt.h"
+#include "esp32s3_dma.h"
#ifdef CONFIG_BUILD_PROTECTED
# include "esp32s3_userspace.h"
#endif
@@ -409,6 +410,12 @@ noinstrument_function void noreturn_function IRAM_ATTR
__esp32s3_start(void)
esp_setup_syscall_table();
+#if defined(CONFIG_ESP32S3_DMA)
+ /* Initialize GDMA controller */
+
+ esp32s3_dma_init();
+#endif
+
/* Initialize onboard resources */
esp32s3_board_initialize();