Skip to content

drivers: flash: fix RWW issues in flash_mcux_flexspi_hyperflash #88469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 25 additions & 23 deletions drivers/flash/flash_mcux_flexspi_hyperflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <zephyr/kernel.h>
#include <errno.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/cache.h>

#include <zephyr/logging/log.h>

Expand Down Expand Up @@ -256,9 +257,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;
Expand Down Expand Up @@ -289,9 +289,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;

Expand Down Expand Up @@ -370,11 +370,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,
Expand Down Expand Up @@ -411,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;
Expand All @@ -424,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 ====
Expand All @@ -449,23 +449,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;
Expand All @@ -478,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 ==== */
Expand All @@ -506,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;
}
Expand All @@ -530,7 +533,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;
Expand All @@ -551,7 +554,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;
Expand All @@ -563,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 ==== */
Expand Down