From 0b4c9823ceebe0d246270eb799d4cf30ada62ad7 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 10 Apr 2025 18:19:18 -0500 Subject: [PATCH 1/2] drivers: flash: flash_mcux_flexspi_hyperflash: don't access device ptr Don't access device pointer from critical sections when programming the hyperflash, as this could cause a RWW hazard Signed-off-by: Daniel DeGrasse --- drivers/flash/flash_mcux_flexspi_hyperflash.c | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_hyperflash.c b/drivers/flash/flash_mcux_flexspi_hyperflash.c index d50c73c936d4..9719e1092d4e 100644 --- a/drivers/flash/flash_mcux_flexspi_hyperflash.c +++ b/drivers/flash/flash_mcux_flexspi_hyperflash.c @@ -256,9 +256,8 @@ struct flash_flexspi_hyperflash_data { struct flash_parameters flash_parameters; }; -static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev) +static int flash_flexspi_hyperflash_wait_bus_busy(struct flash_flexspi_hyperflash_data *data) { - struct flash_flexspi_hyperflash_data *data = dev->data; flexspi_transfer_t transfer; int ret; bool is_busy; @@ -289,9 +288,9 @@ static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev) return ret; } -static int flash_flexspi_hyperflash_write_enable(const struct device *dev, uint32_t address) +static int flash_flexspi_hyperflash_write_enable(struct flash_flexspi_hyperflash_data *data, + uint32_t address) { - struct flash_flexspi_hyperflash_data *data = dev->data; flexspi_transfer_t transfer; int ret; @@ -370,11 +369,9 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev) return ret; } -static int flash_flexspi_hyperflash_page_program(const struct device *dev, off_t - offset, const void *buffer, size_t len) +static int flash_flexspi_hyperflash_page_program(struct flash_flexspi_hyperflash_data *data, + off_t offset, const void *buffer, size_t len) { - struct flash_flexspi_hyperflash_data *data = dev->data; - flexspi_transfer_t transfer = { .deviceAddress = offset, .port = data->port, @@ -464,23 +461,23 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset memc_flexspi_wait_bus_idle(&data->controller); } #endif - ret = flash_flexspi_hyperflash_write_enable(dev, offset); + ret = flash_flexspi_hyperflash_write_enable(data, offset); if (ret != 0) { LOG_ERR("failed to enable write"); break; } #ifdef CONFIG_FLASH_MCUX_FLEXSPI_HYPERFLASH_WRITE_BUFFER - ret = flash_flexspi_hyperflash_page_program(dev, offset, + ret = flash_flexspi_hyperflash_page_program(data, offset, hyperflash_write_buf, i); #else - ret = flash_flexspi_hyperflash_page_program(dev, offset, src, i); + ret = flash_flexspi_hyperflash_page_program(data, offset, src, i); #endif if (ret != 0) { LOG_ERR("failed to write"); break; } - ret = flash_flexspi_hyperflash_wait_bus_busy(dev); + ret = flash_flexspi_hyperflash_wait_bus_busy(data); if (ret != 0) { LOG_ERR("failed to wait bus busy"); break; @@ -546,7 +543,7 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset } for (i = 0; i < num_sectors; i++) { - ret = flash_flexspi_hyperflash_write_enable(dev, offset); + ret = flash_flexspi_hyperflash_write_enable(data, offset); if (ret != 0) { LOG_ERR("failed to write_enable"); break; @@ -567,7 +564,7 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset } /* wait bus busy */ - ret = flash_flexspi_hyperflash_wait_bus_busy(dev); + ret = flash_flexspi_hyperflash_wait_bus_busy(data); if (ret != 0) { LOG_ERR("failed to wait bus busy"); break; From c3971f0ab3e5defcad5ddf0e9843d12884112a97 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 10 Apr 2025 18:20:48 -0500 Subject: [PATCH 2/2] drivers: flash: flash_mcux_flexspi_hyperflash: disable cache during prgm Disable the cache during erase and programming operations, as cache pre-fetch operations can cause flash access outside of the application's control Also, reduce the SCLK frequency used after erase operations to 200MHz. Without this, the RT1050 appears to hang after flash program operations Signed-off-by: Daniel DeGrasse --- drivers/flash/flash_mcux_flexspi_hyperflash.c | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_hyperflash.c b/drivers/flash/flash_mcux_flexspi_hyperflash.c index 9719e1092d4e..a414092d28be 100644 --- a/drivers/flash/flash_mcux_flexspi_hyperflash.c +++ b/drivers/flash/flash_mcux_flexspi_hyperflash.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -416,7 +417,6 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset const void *buffer, size_t len) { struct flash_flexspi_hyperflash_data *data = dev->data; - size_t size = len; uint8_t *src = (uint8_t *)buffer; unsigned int key = 0; int i, j; @@ -429,6 +429,9 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset return -EINVAL; } + sys_cache_instr_disable(); + sys_cache_data_disable(); + if (memc_flexspi_is_running_xip(&data->controller)) { /* * ==== ENTER CRITICAL SECTION ==== @@ -490,13 +493,12 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset len -= i; } - /* Clock FlexSPI at 332 MHZ (166 MHz SCLK in DDR mode) */ + /* Clock FlexSPI at 200 MHZ (100 MHz SCLK in DDR mode) */ (void)memc_flexspi_update_clock(&data->controller, &data->config, - data->port, MHZ(332)); + data->port, MHZ(200)); -#ifdef CONFIG_HAS_MCUX_CACHE - DCACHE_InvalidateByRange((uint32_t) dst, size); -#endif + sys_cache_instr_enable(); + sys_cache_data_enable(); if (memc_flexspi_is_running_xip(&data->controller)) { /* ==== EXIT CRITICAL SECTION ==== */ @@ -518,6 +520,10 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset data->port, offset); + + sys_cache_instr_disable(); + sys_cache_data_disable(); + if (!dst) { return -EINVAL; } @@ -576,9 +582,8 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset offset += SPI_HYPERFLASH_SECTOR_SIZE; } -#ifdef CONFIG_HAS_MCUX_CACHE - DCACHE_InvalidateByRange((uint32_t) dst, size); -#endif + sys_cache_instr_enable(); + sys_cache_data_enable(); if (memc_flexspi_is_running_xip(&data->controller)) { /* ==== EXIT CRITICAL SECTION ==== */