From 79d899e14422ab625e4453c0f199fb851901781e 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 a44693ab2be7..5a30d082e50b 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, @@ -449,23 +446,23 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset hyperflash_write_buf[j] = src[j]; } #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; @@ -530,7 +527,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; @@ -551,7 +548,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 d3bcc612ef4206d458c0b667506c6b0542c4c7a9 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 5a30d082e50b..50ea3e7c1fe5 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 @@ -408,7 +409,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; @@ -421,6 +421,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 ==== @@ -475,13 +478,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 ==== */ @@ -503,6 +505,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; } @@ -560,9 +566,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 ==== */