drivers: memc: memc_mcux_flexspi: move device data into RAM

flexspi driver should not interact with flash whenever possible, and
should never use flash while in a critical write or erase section.
Move device data to RAM to prevent this read-while-write hazard.

Fixes #44043

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2022-03-21 15:09:20 -05:00 committed by David Leach
parent 8d556c0623
commit 69ff24ce97

View file

@ -25,7 +25,8 @@
LOG_MODULE_REGISTER(memc_flexspi, CONFIG_MEMC_LOG_LEVEL);
struct memc_flexspi_config {
/* flexspi device data should be stored in RAM to avoid read-while-write hazards */
struct memc_flexspi_data {
FLEXSPI_Type *base;
uint8_t *ahb_base;
bool xip;
@ -36,33 +37,30 @@ struct memc_flexspi_config {
bool combination_mode;
bool sck_differential_clock;
flexspi_read_sample_clock_t rx_sample_clock;
};
struct memc_flexspi_data {
size_t size[kFLEXSPI_PortCount];
};
void memc_flexspi_wait_bus_idle(const struct device *dev)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
while (false == FLEXSPI_GetBusIdleStatus(config->base)) {
while (false == FLEXSPI_GetBusIdleStatus(data->base)) {
}
}
bool memc_flexspi_is_running_xip(const struct device *dev)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
return config->xip;
return data->xip;
}
int memc_flexspi_update_lut(const struct device *dev, uint32_t index,
const uint32_t *cmd, uint32_t count)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
FLEXSPI_UpdateLUT(config->base, index, cmd, count);
FLEXSPI_UpdateLUT(data->base, index, cmd, count);
return 0;
}
@ -71,7 +69,6 @@ int memc_flexspi_set_device_config(const struct device *dev,
const flexspi_device_config_t *device_config,
flexspi_port_t port)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
if (port >= kFLEXSPI_PortCount) {
@ -81,7 +78,7 @@ int memc_flexspi_set_device_config(const struct device *dev,
data->size[port] = device_config->flashSize * KB(1);
FLEXSPI_SetFlashConfig(config->base,
FLEXSPI_SetFlashConfig(data->base,
(flexspi_device_config_t *) device_config,
port);
@ -90,9 +87,9 @@ int memc_flexspi_set_device_config(const struct device *dev,
int memc_flexspi_reset(const struct device *dev)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
FLEXSPI_SoftwareReset(config->base);
FLEXSPI_SoftwareReset(data->base);
return 0;
}
@ -100,8 +97,8 @@ int memc_flexspi_reset(const struct device *dev)
int memc_flexspi_transfer(const struct device *dev,
flexspi_transfer_t *transfer)
{
const struct memc_flexspi_config *config = dev->config;
status_t status = FLEXSPI_TransferBlocking(config->base, transfer);
struct memc_flexspi_data *data = dev->data;
status_t status = FLEXSPI_TransferBlocking(data->base, transfer);
if (status != kStatus_Success) {
LOG_ERR("Transfer error: %d", status);
@ -114,7 +111,6 @@ int memc_flexspi_transfer(const struct device *dev,
void *memc_flexspi_get_ahb_address(const struct device *dev,
flexspi_port_t port, off_t offset)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
int i;
@ -127,12 +123,12 @@ void *memc_flexspi_get_ahb_address(const struct device *dev,
offset += data->size[port];
}
return config->ahb_base + offset;
return data->ahb_base + offset;
}
static int memc_flexspi_init(const struct device *dev)
{
const struct memc_flexspi_config *config = dev->config;
struct memc_flexspi_data *data = dev->data;
flexspi_config_t flexspi_config;
/* we should not configure the device we are running on */
@ -143,18 +139,18 @@ static int memc_flexspi_init(const struct device *dev)
FLEXSPI_GetDefaultConfig(&flexspi_config);
flexspi_config.ahbConfig.enableAHBBufferable = config->ahb_bufferable;
flexspi_config.ahbConfig.enableAHBCachable = config->ahb_cacheable;
flexspi_config.ahbConfig.enableAHBPrefetch = config->ahb_prefetch;
flexspi_config.ahbConfig.enableReadAddressOpt = config->ahb_read_addr_opt;
flexspi_config.ahbConfig.enableAHBBufferable = data->ahb_bufferable;
flexspi_config.ahbConfig.enableAHBCachable = data->ahb_cacheable;
flexspi_config.ahbConfig.enableAHBPrefetch = data->ahb_prefetch;
flexspi_config.ahbConfig.enableReadAddressOpt = data->ahb_read_addr_opt;
#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN) && \
FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN)
flexspi_config.enableCombination = config->combination_mode;
flexspi_config.enableCombination = data->combination_mode;
#endif
flexspi_config.enableSckBDiffOpt = config->sck_differential_clock;
flexspi_config.rxSampleClock = config->rx_sample_clock;
flexspi_config.enableSckBDiffOpt = data->sck_differential_clock;
flexspi_config.rxSampleClock = data->rx_sample_clock;
FLEXSPI_Init(config->base, &flexspi_config);
FLEXSPI_Init(data->base, &flexspi_config);
return 0;
}
@ -170,8 +166,8 @@ static int memc_flexspi_init(const struct device *dev)
#endif
#define MEMC_FLEXSPI(n) \
static const struct memc_flexspi_config \
memc_flexspi_config_##n = { \
static struct memc_flexspi_data \
memc_flexspi_data_##n = { \
.base = (FLEXSPI_Type *) DT_INST_REG_ADDR(n), \
.xip = MEMC_FLEXSPI_CFG_XIP(DT_DRV_INST(n)), \
.ahb_base = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(n, 1), \
@ -184,13 +180,11 @@ static int memc_flexspi_init(const struct device *dev)
.rx_sample_clock = DT_INST_PROP(n, rx_clock_source), \
}; \
\
static struct memc_flexspi_data memc_flexspi_data_##n; \
\
DEVICE_DT_INST_DEFINE(n, \
memc_flexspi_init, \
NULL, \
&memc_flexspi_data_##n, \
&memc_flexspi_config_##n, \
NULL, \
POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
NULL);