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); + modifyreg32(SYSTEM_PERIP_CLK_EN1_REG, 0, SYSTEM_DMA_CLK_EN_M); + modifyreg32(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST_M, 0); - 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); + /* enable DMA clock gating */ - 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); - - 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); + 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();