arch/xtensa/esp32s3: Add qspi/spi_slave/lcd DMA request return value.
Optimize DMA initialization for duplicate calls.
This commit is contained in:
parent
6edd1e3f7d
commit
a83a569652
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user