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:
parent
8d556c0623
commit
69ff24ce97
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue