drivers: flash: stm32h7x: use barriers to ensure the writes are flushed
The STM32H7 flash driver read-back a register after writing it to ensure it is flushed. This is very fragile and might break if a new compiler version slightly reorder the instructions. Instead use a __DSB() barrier like done on other STM32 SoC, which ensures that the registers and the data writes are flushed at the compiler level, but also at the Cortex-M7 level. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
67bceb0257
commit
c337b9f80b
1 changed files with 6 additions and 4 deletions
|
@ -239,7 +239,6 @@ static struct flash_stm32_sector_t get_sector(const struct device *dev,
|
||||||
static int erase_sector(const struct device *dev, int offset)
|
static int erase_sector(const struct device *dev, int offset)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
uint32_t tmp;
|
|
||||||
struct flash_stm32_sector_t sector = get_sector(dev, offset);
|
struct flash_stm32_sector_t sector = get_sector(dev, offset);
|
||||||
|
|
||||||
if (sector.bank == 0) {
|
if (sector.bank == 0) {
|
||||||
|
@ -263,7 +262,7 @@ static int erase_sector(const struct device *dev, int offset)
|
||||||
| ((sector.sector_index << FLASH_CR_SNB_Pos) & FLASH_CR_SNB));
|
| ((sector.sector_index << FLASH_CR_SNB_Pos) & FLASH_CR_SNB));
|
||||||
*(sector.cr) |= FLASH_CR_START;
|
*(sector.cr) |= FLASH_CR_START;
|
||||||
/* flush the register write */
|
/* flush the register write */
|
||||||
tmp = *(sector.cr);
|
__DSB();
|
||||||
|
|
||||||
rc = flash_stm32_wait_flash_idle(dev);
|
rc = flash_stm32_wait_flash_idle(dev);
|
||||||
*(sector.cr) &= ~(FLASH_CR_SER | FLASH_CR_SNB);
|
*(sector.cr) &= ~(FLASH_CR_SER | FLASH_CR_SNB);
|
||||||
|
@ -314,7 +313,6 @@ static int write_ndwords(const struct device *dev,
|
||||||
{
|
{
|
||||||
volatile uint64_t *flash = (uint64_t *)(offset
|
volatile uint64_t *flash = (uint64_t *)(offset
|
||||||
+ CONFIG_FLASH_BASE_ADDRESS);
|
+ CONFIG_FLASH_BASE_ADDRESS);
|
||||||
uint32_t tmp;
|
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
struct flash_stm32_sector_t sector = get_sector(dev, offset);
|
struct flash_stm32_sector_t sector = get_sector(dev, offset);
|
||||||
|
@ -346,11 +344,15 @@ static int write_ndwords(const struct device *dev,
|
||||||
*(sector.cr) |= FLASH_CR_PG;
|
*(sector.cr) |= FLASH_CR_PG;
|
||||||
|
|
||||||
/* Flush the register write */
|
/* Flush the register write */
|
||||||
tmp = *(sector.cr);
|
__DSB();
|
||||||
|
|
||||||
/* Perform the data write operation at the desired memory address */
|
/* Perform the data write operation at the desired memory address */
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
flash[i] = data[i];
|
flash[i] = data[i];
|
||||||
|
|
||||||
|
/* Flush the data write */
|
||||||
|
__DSB();
|
||||||
|
|
||||||
wait_write_queue(dev, offset);
|
wait_write_queue(dev, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue