drivers: flash: flash_mcux_flexspi_*: copy LUT to ram when updating
Copy the LUT to SRAM before updating it. This avoids the application reading LUT entries from FlexSPI while trying to write them to FlexSPI configuration registers, which could result in invalid LUT entries being added. This update is applied to all in tree flash FlexSPI drivers, although the failure has only been observed with the flash_mcux_flexspi_nor driver. Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
parent
44415eb881
commit
095d453d7a
3 changed files with 42 additions and 8 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Volvo Construction Equipment
|
* Copyright (c) 2021 Volvo Construction Equipment
|
||||||
|
* Copyright 2023 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -595,6 +596,7 @@ static int flash_flexspi_hyperflash_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct flash_flexspi_hyperflash_config *config = dev->config;
|
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;
|
||||||
|
uint32_t temp_lut[sizeof(flash_flexspi_hyperflash_lut) / sizeof(uint32_t)];
|
||||||
|
|
||||||
/* Since the controller variable may be used in critical sections,
|
/* Since the controller variable may be used in critical sections,
|
||||||
* copy the device pointer into a variable stored in RAM
|
* copy the device pointer into a variable stored in RAM
|
||||||
|
@ -615,9 +617,19 @@ static int flash_flexspi_hyperflash_init(const struct device *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using the LUT stored in the FlexSPI directly when updating
|
||||||
|
* the FlexSPI can result in an invalid LUT entry being stored,
|
||||||
|
* as the LUT itself describes how the FlexSPI should access the flash.
|
||||||
|
* To resolve this, copy the LUT to a array placed in RAM before
|
||||||
|
* updating the FlexSPI.
|
||||||
|
*/
|
||||||
|
memcpy(temp_lut, flash_flexspi_hyperflash_lut,
|
||||||
|
sizeof(flash_flexspi_hyperflash_lut));
|
||||||
|
|
||||||
if (memc_flexspi_update_lut(&data->controller, 0,
|
if (memc_flexspi_update_lut(&data->controller, 0,
|
||||||
(const uint32_t *) flash_flexspi_hyperflash_lut,
|
(const uint32_t *) temp_lut,
|
||||||
sizeof(flash_flexspi_hyperflash_lut)/4)) {
|
sizeof(temp_lut) / sizeof(uint32_t))) {
|
||||||
LOG_ERR("Could not update lut");
|
LOG_ERR("Could not update lut");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 NXP
|
* Copyright 2021,2023 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -504,6 +504,7 @@ static int flash_flexspi_nor_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct flash_flexspi_nor_data *data = dev->data;
|
struct flash_flexspi_nor_data *data = dev->data;
|
||||||
uint8_t vendor_id;
|
uint8_t vendor_id;
|
||||||
|
uint32_t temp_lut[sizeof(flash_flexspi_nor_lut) / sizeof(uint32_t)];
|
||||||
|
|
||||||
if (!device_is_ready(data->controller)) {
|
if (!device_is_ready(data->controller)) {
|
||||||
LOG_ERR("Controller device not ready");
|
LOG_ERR("Controller device not ready");
|
||||||
|
@ -517,9 +518,19 @@ static int flash_flexspi_nor_init(const struct device *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using the LUT stored in the FlexSPI directly when updating
|
||||||
|
* the FlexSPI can result in an invalid LUT entry being stored,
|
||||||
|
* as the LUT itself describes how the FlexSPI should access the flash.
|
||||||
|
* To resolve this, copy the LUT to a array placed in RAM before
|
||||||
|
* updating the FlexSPI.
|
||||||
|
*/
|
||||||
|
memcpy(temp_lut, flash_flexspi_nor_lut,
|
||||||
|
sizeof(flash_flexspi_nor_lut));
|
||||||
|
|
||||||
if (memc_flexspi_update_lut(data->controller, 0,
|
if (memc_flexspi_update_lut(data->controller, 0,
|
||||||
(const uint32_t *) flash_flexspi_nor_lut,
|
(const uint32_t *) temp_lut,
|
||||||
sizeof(flash_flexspi_nor_lut) / 4)) {
|
sizeof(temp_lut) / sizeof(uint32_t))) {
|
||||||
LOG_ERR("Could not update lut");
|
LOG_ERR("Could not update lut");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 NXP
|
* Copyright 2020,2023 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -506,6 +506,7 @@ static int flash_flexspi_nor_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct flash_flexspi_nor_data *data = dev->data;
|
struct flash_flexspi_nor_data *data = dev->data;
|
||||||
uint8_t vendor_id;
|
uint8_t vendor_id;
|
||||||
|
uint32_t temp_lut[sizeof(flash_flexspi_nor_lut) / sizeof(uint32_t)];
|
||||||
|
|
||||||
if (!device_is_ready(data->controller)) {
|
if (!device_is_ready(data->controller)) {
|
||||||
LOG_ERR("Controller device is not ready");
|
LOG_ERR("Controller device is not ready");
|
||||||
|
@ -519,9 +520,19 @@ static int flash_flexspi_nor_init(const struct device *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using the LUT stored in the FlexSPI directly when updating
|
||||||
|
* the FlexSPI can result in an invalid LUT entry being stored,
|
||||||
|
* as the LUT itself describes how the FlexSPI should access the flash.
|
||||||
|
* To resolve this, copy the LUT to a array placed in RAM before
|
||||||
|
* updating the FlexSPI.
|
||||||
|
*/
|
||||||
|
memcpy(temp_lut, flash_flexspi_nor_lut,
|
||||||
|
sizeof(flash_flexspi_nor_lut));
|
||||||
|
|
||||||
if (memc_flexspi_update_lut(data->controller, 0,
|
if (memc_flexspi_update_lut(data->controller, 0,
|
||||||
(const uint32_t *) flash_flexspi_nor_lut,
|
(const uint32_t *) temp_lut,
|
||||||
sizeof(flash_flexspi_nor_lut) / 4)) {
|
sizeof(temp_lut) / sizeof(uint32_t))) {
|
||||||
LOG_ERR("Could not update lut");
|
LOG_ERR("Could not update lut");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue