drivers/flash: flash_stm32_qspi: Set DMA as optional
In order to ease reuse on other series, set DMA as optional and use IT if no DMA channel is specified in the qspi node. Tested on disco_l475_iot1 Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
parent
b711028539
commit
dc110506d9
3 changed files with 24 additions and 12 deletions
|
@ -5,17 +5,18 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
DT_COMPAT_ST_STM32_QSPI_NOR := st,stm32-qspi-nor
|
DT_COMPAT_ST_STM32_QSPI_NOR := st,stm32-qspi-nor
|
||||||
|
DT_STM32_QUADSPI_HAS_DMA := $(dt_node_has_prop,quadspi,dmas)
|
||||||
|
|
||||||
config FLASH_STM32_QSPI
|
config FLASH_STM32_QSPI
|
||||||
bool "STM32 Quad SPI Flash driver"
|
bool "STM32 Quad SPI Flash driver"
|
||||||
depends on SOC_FAMILY_STM32
|
depends on SOC_FAMILY_STM32
|
||||||
default $(dt_compat_enabled,$(DT_COMPAT_ST_STM32_QSPI_NOR))
|
default $(dt_compat_enabled,$(DT_COMPAT_ST_STM32_QSPI_NOR))
|
||||||
select USE_STM32_HAL_QSPI
|
select USE_STM32_HAL_QSPI
|
||||||
select USE_STM32_HAL_DMA
|
|
||||||
select DMA
|
|
||||||
select FLASH_HAS_DRIVER_ENABLED
|
select FLASH_HAS_DRIVER_ENABLED
|
||||||
select FLASH_JESD216
|
select FLASH_JESD216
|
||||||
select FLASH_PAGE_LAYOUT
|
select FLASH_PAGE_LAYOUT
|
||||||
select FLASH_HAS_PAGE_LAYOUT
|
select FLASH_HAS_PAGE_LAYOUT
|
||||||
|
select DMA if $(DT_STM32_QUADSPI_HAS_DMA)
|
||||||
|
select USE_STM32_HAL_DMA if $(DT_STM32_QUADSPI_HAS_DMA)
|
||||||
help
|
help
|
||||||
Enable QSPI-NOR support on the STM32 family of processors.
|
Enable QSPI-NOR support on the STM32 family of processors.
|
||||||
|
|
|
@ -32,6 +32,8 @@ LOG_MODULE_REGISTER(flash_stm32_qspi, CONFIG_FLASH_LOG_LEVEL);
|
||||||
#define STM32_QSPI_FIFO_THRESHOLD 8
|
#define STM32_QSPI_FIFO_THRESHOLD 8
|
||||||
#define STM32_QSPI_CLOCK_PRESCALER_MAX 255
|
#define STM32_QSPI_CLOCK_PRESCALER_MAX 255
|
||||||
|
|
||||||
|
#define STM32_QSPI_USE_DMA DT_NODE_HAS_PROP(DT_PARENT(DT_DRV_INST(0)), dmas)
|
||||||
|
|
||||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor)
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor)
|
||||||
|
|
||||||
uint32_t table_m_size[] = {
|
uint32_t table_m_size[] = {
|
||||||
|
@ -151,7 +153,11 @@ static int qspi_read_access(const struct device *dev, QSPI_CommandTypeDef *cmd,
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if STM32_QSPI_USE_DMA
|
||||||
hal_ret = HAL_QSPI_Receive_DMA(&dev_data->hqspi, data);
|
hal_ret = HAL_QSPI_Receive_DMA(&dev_data->hqspi, data);
|
||||||
|
#else
|
||||||
|
hal_ret = HAL_QSPI_Receive_IT(&dev_data->hqspi, data);
|
||||||
|
#endif
|
||||||
if (hal_ret != HAL_OK) {
|
if (hal_ret != HAL_OK) {
|
||||||
LOG_ERR("%d: Failed to read data", hal_ret);
|
LOG_ERR("%d: Failed to read data", hal_ret);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -186,7 +192,11 @@ static int qspi_write_access(const struct device *dev, QSPI_CommandTypeDef *cmd,
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if STM32_QSPI_USE_DMA
|
||||||
hal_ret = HAL_QSPI_Transmit_DMA(&dev_data->hqspi, (uint8_t *)data);
|
hal_ret = HAL_QSPI_Transmit_DMA(&dev_data->hqspi, (uint8_t *)data);
|
||||||
|
#else
|
||||||
|
hal_ret = HAL_QSPI_Transmit_IT(&dev_data->hqspi, (uint8_t *)data);
|
||||||
|
#endif
|
||||||
if (hal_ret != HAL_OK) {
|
if (hal_ret != HAL_OK) {
|
||||||
LOG_ERR("%d: Failed to read data", hal_ret);
|
LOG_ERR("%d: Failed to read data", hal_ret);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -454,6 +464,7 @@ static void flash_stm32_qspi_isr(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is executed in the interrupt context */
|
/* This function is executed in the interrupt context */
|
||||||
|
#if STM32_QSPI_USE_DMA
|
||||||
static void qspi_dma_callback(const struct device *dev, void *arg,
|
static void qspi_dma_callback(const struct device *dev, void *arg,
|
||||||
uint32_t channel, int status)
|
uint32_t channel, int status)
|
||||||
{
|
{
|
||||||
|
@ -466,6 +477,7 @@ static void qspi_dma_callback(const struct device *dev, void *arg,
|
||||||
|
|
||||||
HAL_DMA_IRQHandler(hdma);
|
HAL_DMA_IRQHandler(hdma);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__weak HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
|
__weak HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
|
||||||
{
|
{
|
||||||
|
@ -658,8 +670,6 @@ static int flash_stm32_qspi_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct flash_stm32_qspi_config *dev_cfg = DEV_CFG(dev);
|
const struct flash_stm32_qspi_config *dev_cfg = DEV_CFG(dev);
|
||||||
struct flash_stm32_qspi_data *dev_data = DEV_DATA(dev);
|
struct flash_stm32_qspi_data *dev_data = DEV_DATA(dev);
|
||||||
struct dma_config dma_cfg = dev_data->dma.cfg;
|
|
||||||
static DMA_HandleTypeDef hdma;
|
|
||||||
uint32_t ahb_clock_freq;
|
uint32_t ahb_clock_freq;
|
||||||
uint32_t prescaler = 0;
|
uint32_t prescaler = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -673,6 +683,7 @@ static int flash_stm32_qspi_init(const struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if STM32_QSPI_USE_DMA
|
||||||
/*
|
/*
|
||||||
* DMA configuration
|
* DMA configuration
|
||||||
* Due to use of QSPI HAL API in current driver,
|
* Due to use of QSPI HAL API in current driver,
|
||||||
|
@ -681,7 +692,6 @@ static int flash_stm32_qspi_init(const struct device *dev)
|
||||||
* the minimum information to inform the DMA slot will be in used and
|
* the minimum information to inform the DMA slot will be in used and
|
||||||
* how to route callbacks.
|
* how to route callbacks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct dma_config dma_cfg = dev_data->dma.cfg;
|
struct dma_config dma_cfg = dev_data->dma.cfg;
|
||||||
static DMA_HandleTypeDef hdma;
|
static DMA_HandleTypeDef hdma;
|
||||||
|
|
||||||
|
@ -691,6 +701,8 @@ static int flash_stm32_qspi_init(const struct device *dev)
|
||||||
LOG_ERR("%s device not found", dev_data->dma.name);
|
LOG_ERR("%s device not found", dev_data->dma.name);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Proceed to the minimum Zephyr DMA driver init */
|
/* Proceed to the minimum Zephyr DMA driver init */
|
||||||
|
@ -738,6 +750,8 @@ static int flash_stm32_qspi_init(const struct device *dev)
|
||||||
__HAL_LINKDMA(&dev_data->hqspi, hdma, hdma);
|
__HAL_LINKDMA(&dev_data->hqspi, hdma, hdma);
|
||||||
HAL_DMA_Init(&hdma);
|
HAL_DMA_Init(&hdma);
|
||||||
|
|
||||||
|
#endif /* STM32_QSPI_USE_DMA */
|
||||||
|
|
||||||
/* Clock configuration */
|
/* Clock configuration */
|
||||||
__ASSERT_NO_MSG(device_get_binding(STM32_CLOCK_CONTROL_NAME));
|
__ASSERT_NO_MSG(device_get_binding(STM32_CLOCK_CONTROL_NAME));
|
||||||
|
|
||||||
|
@ -762,7 +776,6 @@ static int flash_stm32_qspi_init(const struct device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__ASSERT_NO_MSG(prescaler <= STM32_QSPI_CLOCK_PRESCALER_MAX);
|
__ASSERT_NO_MSG(prescaler <= STM32_QSPI_CLOCK_PRESCALER_MAX);
|
||||||
|
|
||||||
/* Initialize QSPI HAL */
|
/* Initialize QSPI HAL */
|
||||||
dev_data->hqspi.Init.ClockPrescaler = prescaler;
|
dev_data->hqspi.Init.ClockPrescaler = prescaler;
|
||||||
dev_data->hqspi.Init.FlashSize = find_lsb_set(dev_cfg->flash_size);
|
dev_data->hqspi.Init.FlashSize = find_lsb_set(dev_cfg->flash_size);
|
||||||
|
|
|
@ -30,19 +30,17 @@ properties:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
dmas:
|
dmas:
|
||||||
required: true
|
|
||||||
description: |
|
description: |
|
||||||
DMA channel specifier. Specifier will have a phandle
|
Optional DMA channel specifier. If DMA should be used, specifier should
|
||||||
reference to the dma controller, the channel number, the slot number,
|
hold a phandle reference to the dma controller, the channel number,
|
||||||
channel configuration and finally features.
|
the slot number, channel configuration and finally features.
|
||||||
|
|
||||||
For example dmas for TX/RX on QSPI
|
For example dmas for TX/RX on QSPI
|
||||||
dmas = <&dma1 5 5 0x0000 0x03>;
|
dmas = <&dma1 5 5 0x0000 0x03>;
|
||||||
|
|
||||||
dma-names:
|
dma-names:
|
||||||
required: true
|
|
||||||
description: |
|
description: |
|
||||||
DMA channel name. Expected value "tx_rx".
|
DMA channel name. If DMA should be used, expected value is "tx_rx".
|
||||||
|
|
||||||
For example
|
For example
|
||||||
dma-names = "tx_rx";
|
dma-names = "tx_rx";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue