drivers: flash_mcux_flexspi_hyperflash: move all device data to RAM
since the flexspi driver interacts with the flash device, storing device data in flash can cause RWW hazards when running in XIP mode. Move all device data to RAM to limit these RWW hazards. Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
parent
7aa883b5df
commit
836f0f5ee5
1 changed files with 27 additions and 40 deletions
|
@ -17,6 +17,8 @@
|
||||||
* called while interacting with the flexspi MUST be relocated to SRAM or ITCM
|
* called while interacting with the flexspi MUST be relocated to SRAM or ITCM
|
||||||
* at runtime, so that the chip does not access the flexspi to read program
|
* at runtime, so that the chip does not access the flexspi to read program
|
||||||
* instructions while it is being written to
|
* instructions while it is being written to
|
||||||
|
*
|
||||||
|
* Additionally, no data used by this driver should be stored in flash.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_FLASH_MCUX_FLEXSPI_XIP) && (CONFIG_FLASH_LOG_LEVEL > 0)
|
#if defined(CONFIG_FLASH_MCUX_FLEXSPI_XIP) && (CONFIG_FLASH_LOG_LEVEL > 0)
|
||||||
#warning "Enabling flash driver logging and XIP mode simultaneously can cause \
|
#warning "Enabling flash driver logging and XIP mode simultaneously can cause \
|
||||||
|
@ -240,21 +242,17 @@ static const uint32_t flash_flexspi_hyperflash_lut[CUSTOM_LUT_LENGTH] = {
|
||||||
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10),
|
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct flash_flexspi_hyperflash_config {
|
/* Device variables used in critical sections should be in this structure */
|
||||||
flexspi_port_t port;
|
struct flash_flexspi_hyperflash_data {
|
||||||
|
const struct device *controller;
|
||||||
flexspi_device_config_t config;
|
flexspi_device_config_t config;
|
||||||
|
flexspi_port_t port;
|
||||||
struct flash_pages_layout layout;
|
struct flash_pages_layout layout;
|
||||||
struct flash_parameters flash_parameters;
|
struct flash_parameters flash_parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device variables used in critical sections should be in this structure */
|
|
||||||
struct flash_flexspi_hyperflash_data {
|
|
||||||
const struct device *controller;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
|
static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
flexspi_transfer_t transfer;
|
flexspi_transfer_t transfer;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -262,7 +260,7 @@ static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
|
||||||
uint32_t read_value;
|
uint32_t read_value;
|
||||||
|
|
||||||
transfer.deviceAddress = 0;
|
transfer.deviceAddress = 0;
|
||||||
transfer.port = config->port;
|
transfer.port = data->port;
|
||||||
transfer.cmdType = kFLEXSPI_Read;
|
transfer.cmdType = kFLEXSPI_Read;
|
||||||
transfer.SeqNumber = 2;
|
transfer.SeqNumber = 2;
|
||||||
transfer.seqIndex = READ_STATUS;
|
transfer.seqIndex = READ_STATUS;
|
||||||
|
@ -288,13 +286,12 @@ static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
|
||||||
|
|
||||||
static int flash_flexspi_hyperflash_write_enable(const struct device *dev, uint32_t address)
|
static int flash_flexspi_hyperflash_write_enable(const struct device *dev, uint32_t address)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
flexspi_transfer_t transfer;
|
flexspi_transfer_t transfer;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
transfer.deviceAddress = address;
|
transfer.deviceAddress = address;
|
||||||
transfer.port = config->port;
|
transfer.port = data->port;
|
||||||
transfer.cmdType = kFLEXSPI_Command;
|
transfer.cmdType = kFLEXSPI_Command;
|
||||||
transfer.SeqNumber = 2;
|
transfer.SeqNumber = 2;
|
||||||
transfer.seqIndex = WRITE_ENABLE;
|
transfer.seqIndex = WRITE_ENABLE;
|
||||||
|
@ -306,7 +303,6 @@ static int flash_flexspi_hyperflash_write_enable(const struct device *dev, uint3
|
||||||
|
|
||||||
static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
|
static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
uint8_t writebuf[4] = {0x00, 0x98};
|
uint8_t writebuf[4] = {0x00, 0x98};
|
||||||
uint32_t buffer[2];
|
uint32_t buffer[2];
|
||||||
|
@ -314,7 +310,7 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
|
||||||
flexspi_transfer_t transfer;
|
flexspi_transfer_t transfer;
|
||||||
|
|
||||||
transfer.deviceAddress = (0x555 * 2);
|
transfer.deviceAddress = (0x555 * 2);
|
||||||
transfer.port = config->port;
|
transfer.port = data->port;
|
||||||
transfer.cmdType = kFLEXSPI_Write;
|
transfer.cmdType = kFLEXSPI_Write;
|
||||||
transfer.SeqNumber = 1;
|
transfer.SeqNumber = 1;
|
||||||
transfer.seqIndex = WRITE_DATA;
|
transfer.seqIndex = WRITE_DATA;
|
||||||
|
@ -330,7 +326,7 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer.deviceAddress = (0x10 * 2);
|
transfer.deviceAddress = (0x10 * 2);
|
||||||
transfer.port = config->port;
|
transfer.port = data->port;
|
||||||
transfer.cmdType = kFLEXSPI_Read;
|
transfer.cmdType = kFLEXSPI_Read;
|
||||||
transfer.SeqNumber = 1;
|
transfer.SeqNumber = 1;
|
||||||
transfer.seqIndex = READ_DATA;
|
transfer.seqIndex = READ_DATA;
|
||||||
|
@ -351,7 +347,7 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
|
||||||
|
|
||||||
writebuf[1] = 0xF0;
|
writebuf[1] = 0xF0;
|
||||||
transfer.deviceAddress = 0;
|
transfer.deviceAddress = 0;
|
||||||
transfer.port = config->port;
|
transfer.port = data->port;
|
||||||
transfer.cmdType = kFLEXSPI_Write;
|
transfer.cmdType = kFLEXSPI_Write;
|
||||||
transfer.SeqNumber = 1;
|
transfer.SeqNumber = 1;
|
||||||
transfer.seqIndex = WRITE_DATA;
|
transfer.seqIndex = WRITE_DATA;
|
||||||
|
@ -372,12 +368,11 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
|
||||||
static int flash_flexspi_hyperflash_page_program(const struct device *dev, off_t
|
static int flash_flexspi_hyperflash_page_program(const struct device *dev, off_t
|
||||||
offset, const void *buffer, size_t len)
|
offset, const void *buffer, size_t len)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
|
|
||||||
flexspi_transfer_t transfer = {
|
flexspi_transfer_t transfer = {
|
||||||
.deviceAddress = offset,
|
.deviceAddress = offset,
|
||||||
.port = config->port,
|
.port = data->port,
|
||||||
.cmdType = kFLEXSPI_Write,
|
.cmdType = kFLEXSPI_Write,
|
||||||
.SeqNumber = 2,
|
.SeqNumber = 2,
|
||||||
.seqIndex = PAGE_PROGRAM,
|
.seqIndex = PAGE_PROGRAM,
|
||||||
|
@ -393,11 +388,10 @@ static int flash_flexspi_hyperflash_page_program(const struct device *dev, off_t
|
||||||
static int flash_flexspi_hyperflash_read(const struct device *dev, off_t offset,
|
static int flash_flexspi_hyperflash_read(const struct device *dev, off_t offset,
|
||||||
void *buffer, size_t len)
|
void *buffer, size_t len)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
|
|
||||||
uint8_t *src = memc_flexspi_get_ahb_address(data->controller,
|
uint8_t *src = memc_flexspi_get_ahb_address(data->controller,
|
||||||
config->port,
|
data->port,
|
||||||
offset);
|
offset);
|
||||||
if (!src) {
|
if (!src) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -411,7 +405,6 @@ static int flash_flexspi_hyperflash_read(const struct device *dev, off_t offset,
|
||||||
static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset,
|
static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset,
|
||||||
const void *buffer, size_t len)
|
const void *buffer, size_t len)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
size_t size = len;
|
size_t size = len;
|
||||||
uint8_t *src = (uint8_t *)buffer;
|
uint8_t *src = (uint8_t *)buffer;
|
||||||
|
@ -420,7 +413,7 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
|
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
|
||||||
config->port,
|
data->port,
|
||||||
offset);
|
offset);
|
||||||
if (!dst) {
|
if (!dst) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -488,7 +481,6 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset
|
||||||
|
|
||||||
static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset, size_t size)
|
static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset, size_t size)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
flexspi_transfer_t transfer;
|
flexspi_transfer_t transfer;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
@ -496,7 +488,7 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset
|
||||||
unsigned int key = 0;
|
unsigned int key = 0;
|
||||||
int num_sectors = size / SPI_HYPERFLASH_SECTOR_SIZE;
|
int num_sectors = size / SPI_HYPERFLASH_SECTOR_SIZE;
|
||||||
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
|
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
|
||||||
config->port,
|
data->port,
|
||||||
offset);
|
offset);
|
||||||
|
|
||||||
if (!dst) {
|
if (!dst) {
|
||||||
|
@ -532,7 +524,7 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset
|
||||||
LOG_DBG("Erasing sector at 0x%08x", offset);
|
LOG_DBG("Erasing sector at 0x%08x", offset);
|
||||||
|
|
||||||
transfer.deviceAddress = offset;
|
transfer.deviceAddress = offset;
|
||||||
transfer.port = config->port;
|
transfer.port = data->port;
|
||||||
transfer.cmdType = kFLEXSPI_Command;
|
transfer.cmdType = kFLEXSPI_Command;
|
||||||
transfer.SeqNumber = 4;
|
transfer.SeqNumber = 4;
|
||||||
transfer.seqIndex = ERASE_SECTOR;
|
transfer.seqIndex = ERASE_SECTOR;
|
||||||
|
@ -571,9 +563,9 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset
|
||||||
static const struct flash_parameters *flash_flexspi_hyperflash_get_parameters(
|
static const struct flash_parameters *flash_flexspi_hyperflash_get_parameters(
|
||||||
const struct device *dev)
|
const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
|
|
||||||
return &config->flash_parameters;
|
return &data->flash_parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -581,15 +573,14 @@ static void flash_flexspi_hyperflash_pages_layout(const struct device *dev,
|
||||||
const struct flash_pages_layout **layout,
|
const struct flash_pages_layout **layout,
|
||||||
size_t *layout_size)
|
size_t *layout_size)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
|
|
||||||
*layout = &config->layout;
|
*layout = &data->layout;
|
||||||
*layout_size = 1;
|
*layout_size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flash_flexspi_hyperflash_init(const struct device *dev)
|
static int flash_flexspi_hyperflash_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
|
||||||
struct flash_flexspi_hyperflash_data *data = dev->data;
|
struct flash_flexspi_hyperflash_data *data = dev->data;
|
||||||
|
|
||||||
if (!device_is_ready(data->controller)) {
|
if (!device_is_ready(data->controller)) {
|
||||||
|
@ -599,8 +590,8 @@ static int flash_flexspi_hyperflash_init(const struct device *dev)
|
||||||
|
|
||||||
memc_flexspi_wait_bus_idle(data->controller);
|
memc_flexspi_wait_bus_idle(data->controller);
|
||||||
|
|
||||||
if (memc_flexspi_set_device_config(data->controller, &config->config,
|
if (memc_flexspi_set_device_config(data->controller, &data->config,
|
||||||
config->port)) {
|
data->port)) {
|
||||||
LOG_ERR("Could not set device configuration");
|
LOG_ERR("Could not set device configuration");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -665,10 +656,11 @@ static const struct flash_driver_api flash_flexspi_hyperflash_api = {
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define FLASH_FLEXSPI_HYPERFLASH(n) \
|
#define FLASH_FLEXSPI_HYPERFLASH(n) \
|
||||||
static const struct flash_flexspi_hyperflash_config \
|
static struct flash_flexspi_hyperflash_data \
|
||||||
flash_flexspi_hyperflash_config_##n = { \
|
flash_flexspi_hyperflash_data_##n = { \
|
||||||
.port = DT_INST_REG_ADDR(n), \
|
.controller = DEVICE_DT_GET(DT_INST_BUS(n)), \
|
||||||
.config = FLASH_FLEXSPI_DEVICE_CONFIG(n), \
|
.config = FLASH_FLEXSPI_DEVICE_CONFIG(n), \
|
||||||
|
.port = DT_INST_REG_ADDR(n), \
|
||||||
.layout = { \
|
.layout = { \
|
||||||
.pages_count = DT_INST_PROP(n, size) / 8 \
|
.pages_count = DT_INST_PROP(n, size) / 8 \
|
||||||
/ SPI_HYPERFLASH_SECTOR_SIZE, \
|
/ SPI_HYPERFLASH_SECTOR_SIZE, \
|
||||||
|
@ -680,16 +672,11 @@ static const struct flash_driver_api flash_flexspi_hyperflash_api = {
|
||||||
}, \
|
}, \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
static struct flash_flexspi_hyperflash_data \
|
|
||||||
flash_flexspi_hyperflash_data_##n = { \
|
|
||||||
.controller = DEVICE_DT_GET(DT_INST_BUS(n)), \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
DEVICE_DT_INST_DEFINE(n, \
|
DEVICE_DT_INST_DEFINE(n, \
|
||||||
flash_flexspi_hyperflash_init, \
|
flash_flexspi_hyperflash_init, \
|
||||||
NULL, \
|
NULL, \
|
||||||
&flash_flexspi_hyperflash_data_##n, \
|
&flash_flexspi_hyperflash_data_##n, \
|
||||||
&flash_flexspi_hyperflash_config_##n, \
|
NULL, \
|
||||||
POST_KERNEL, \
|
POST_KERNEL, \
|
||||||
CONFIG_FLASH_INIT_PRIORITY, \
|
CONFIG_FLASH_INIT_PRIORITY, \
|
||||||
&flash_flexspi_hyperflash_api);
|
&flash_flexspi_hyperflash_api);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue