drivers: flash: stm32 ospi driver aborts memmap before erase/write

This change is aborting the memoryMapped mode of the octo-flash
before erasing or writing the NOR. Operations are performed in
command mode.
Reading is always performed in MemoryMapped mode (memcopy)

Signed-off-by: Francois Ramu <francois.ramu@st.com>
This commit is contained in:
Francois Ramu 2024-01-24 12:55:47 +01:00 committed by David Leach
commit 7b73a343cb

View file

@ -1018,7 +1018,7 @@ static int stm32_ospi_set_memorymap(const struct device *dev)
HAL_OSPI_ADDRESS_24_BITS) HAL_OSPI_ADDRESS_24_BITS)
? SPI_NOR_CMD_READ_FAST ? SPI_NOR_CMD_READ_FAST
: SPI_NOR_CMD_READ_FAST_4B) : SPI_NOR_CMD_READ_FAST_4B)
: SPI_NOR_OCMD_RD) : dev_data->read_opcode)
: SPI_NOR_OCMD_DTR_RD; : SPI_NOR_OCMD_DTR_RD;
s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER) s_command.AddressMode = (dev_cfg->data_rate == OSPI_STR_TRANSFER)
? ((dev_cfg->data_mode == OSPI_SPI_MODE) ? ((dev_cfg->data_mode == OSPI_SPI_MODE)
@ -1099,6 +1099,20 @@ static bool stm32_ospi_is_memorymap(const struct device *dev)
OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ? OCTOSPI_CR_FMODE) == OCTOSPI_CR_FMODE) ?
true : false); true : false);
} }
static int stm32_ospi_abort(const struct device *dev)
{
struct flash_stm32_ospi_data *dev_data = dev->data;
HAL_StatusTypeDef hal_ret;
hal_ret = HAL_OSPI_Abort(&dev_data->hospi);
if (hal_ret != HAL_OK) {
LOG_ERR("%d: OSPI abort failed", hal_ret);
return -EIO;
}
return 0;
}
#endif /* CONFIG_STM32_MEMMAP */ #endif /* CONFIG_STM32_MEMMAP */
/* /*
@ -1136,11 +1150,18 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
return -ENOTSUP; return -ENOTSUP;
} }
ospi_lock_thread(dev);
#ifdef CONFIG_STM32_MEMMAP #ifdef CONFIG_STM32_MEMMAP
if (stm32_ospi_is_memorymap(dev)) { if (stm32_ospi_is_memorymap(dev)) {
LOG_DBG("MemoryMap : cannot erase"); /* Abort ongoing transfer to force CS high/BUSY deasserted */
return 0; ret = stm32_ospi_abort(dev);
if (ret != 0) {
LOG_ERR("Failed to abort memory-mapped access before erase");
goto end_erase;
}
} }
/* Continue with Indirect Mode */
#endif /* CONFIG_STM32_MEMMAP */ #endif /* CONFIG_STM32_MEMMAP */
OSPI_RegularCmdTypeDef cmd_erase = { OSPI_RegularCmdTypeDef cmd_erase = {
@ -1153,8 +1174,6 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD, .SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD,
}; };
ospi_lock_thread(dev);
if (stm32_ospi_mem_ready(dev_data, if (stm32_ospi_mem_ready(dev_data,
dev_cfg->data_mode, dev_cfg->data_rate) != 0) { dev_cfg->data_mode, dev_cfg->data_rate) != 0) {
LOG_ERR("Erase failed : flash busy"); LOG_ERR("Erase failed : flash busy");
@ -1265,8 +1284,8 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr,
ret = stm32_ospi_mem_ready(dev_data, dev_cfg->data_mode, ret = stm32_ospi_mem_ready(dev_data, dev_cfg->data_mode,
dev_cfg->data_rate); dev_cfg->data_rate);
} }
} }
goto end_erase;
end_erase: end_erase:
ospi_unlock_thread(dev); ospi_unlock_thread(dev);
@ -1278,9 +1297,7 @@ end_erase:
static int flash_stm32_ospi_read(const struct device *dev, off_t addr, static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
void *data, size_t size) void *data, size_t size)
{ {
const struct flash_stm32_ospi_config *dev_cfg = dev->config; int ret = 0;
struct flash_stm32_ospi_data *dev_data = dev->data;
int ret;
if (!ospi_address_is_valid(dev, addr, size)) { if (!ospi_address_is_valid(dev, addr, size)) {
LOG_ERR("Error: address or size exceeds expected values: " LOG_ERR("Error: address or size exceeds expected values: "
@ -1294,15 +1311,23 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
} }
#ifdef CONFIG_STM32_MEMMAP #ifdef CONFIG_STM32_MEMMAP
if (stm32_ospi_is_memorymap(dev)) { /* If not MemMapped then configure it */
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu", if (!stm32_ospi_is_memorymap(dev)) {
(long)(STM32_OSPI_BASE_ADDRESS + addr), if (stm32_ospi_set_memorymap(dev) != 0) {
size); LOG_ERR("READ failed: cannot enable MemoryMap");
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size); return -EIO;
}
return 0;
} }
#endif /* CONFIG_STM32_MEMMAP */ /* Now in MemMapped mode : read with memcopy */
LOG_DBG("MemoryMapped Read offset: 0x%lx, len: %zu",
(long)(STM32_OSPI_BASE_ADDRESS + addr),
size);
memcpy(data, (uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, size);
#else /* CONFIG_STM32_MEMMAP */
const struct flash_stm32_ospi_config *dev_cfg = dev->config;
struct flash_stm32_ospi_data *dev_data = dev->data;
OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate); OSPI_RegularCmdTypeDef cmd = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
@ -1369,6 +1394,7 @@ static int flash_stm32_ospi_read(const struct device *dev, off_t addr,
ospi_unlock_thread(dev); ospi_unlock_thread(dev);
#endif /* CONFIG_STM32_MEMMAP */
return ret; return ret;
} }
@ -1395,15 +1421,18 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
return 0; return 0;
} }
ospi_lock_thread(dev);
#ifdef CONFIG_STM32_MEMMAP #ifdef CONFIG_STM32_MEMMAP
if (stm32_ospi_is_memorymap(dev)) { if (stm32_ospi_is_memorymap(dev)) {
LOG_DBG("MemoryMapped Write offset: 0x%lx, len: %zu", /* Abort ongoing transfer to force CS high/BUSY deasserted */
(long)(STM32_OSPI_BASE_ADDRESS + addr), ret = stm32_ospi_abort(dev);
size); if (ret != 0) {
memcpy((uint8_t *)STM32_OSPI_BASE_ADDRESS + addr, data, size); LOG_ERR("Failed to abort memory-mapped access before write");
goto end_write;
return 0; }
} }
/* Continue with Indirect Mode */
#endif /* CONFIG_STM32_MEMMAP */ #endif /* CONFIG_STM32_MEMMAP */
/* page program for STR or DTR mode */ /* page program for STR or DTR mode */
OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate); OSPI_RegularCmdTypeDef cmd_pp = ospi_prepare_cmd(dev_cfg->data_mode, dev_cfg->data_rate);
@ -1448,7 +1477,6 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
cmd_pp.DummyCycles = 0U; cmd_pp.DummyCycles = 0U;
LOG_DBG("OSPI: write %zu data", size); LOG_DBG("OSPI: write %zu data", size);
ospi_lock_thread(dev);
ret = stm32_ospi_mem_ready(dev_data, ret = stm32_ospi_mem_ready(dev_data,
dev_cfg->data_mode, dev_cfg->data_rate); dev_cfg->data_mode, dev_cfg->data_rate);
@ -1497,7 +1525,9 @@ static int flash_stm32_ospi_write(const struct device *dev, off_t addr,
break; break;
} }
} }
goto end_write;
end_write:
ospi_unlock_thread(dev); ospi_unlock_thread(dev);
return ret; return ret;