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();

Reply via email to