drivers: flash: stm32l5: use write-block-size when writing
STM32L5 have a write block size of 8, but STM32U5 and STM32H5 have a write block size of 16. Convert write_dword() and flash_stm32_write_range() to write write-block-size data at a time. Fixes #60724 Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
This commit is contained in:
parent
199486546a
commit
4c9e42925e
1 changed files with 25 additions and 11 deletions
|
@ -155,13 +155,15 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset,
|
||||||
return flash_stm32_range_exists(dev, offset, len);
|
return flash_stm32_range_exists(dev, offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
static int write_nwords(const struct device *dev, off_t offset, const uint32_t *buff, size_t n)
|
||||||
{
|
{
|
||||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||||
volatile uint32_t *flash = (uint32_t *)(offset
|
volatile uint32_t *flash = (uint32_t *)(offset
|
||||||
+ CONFIG_FLASH_BASE_ADDRESS);
|
+ CONFIG_FLASH_BASE_ADDRESS);
|
||||||
|
bool full_zero = true;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
int rc;
|
int rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* if the non-secure control register is locked,do not fail silently */
|
/* if the non-secure control register is locked,do not fail silently */
|
||||||
if (regs->NSCR & FLASH_STM32_NSLOCK) {
|
if (regs->NSCR & FLASH_STM32_NSLOCK) {
|
||||||
|
@ -175,16 +177,26 @@ static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this double word is erased and value isn't 0.
|
/* Check if this double/quad word is erased and value isn't 0.
|
||||||
*
|
*
|
||||||
* It is allowed to write only zeros over an already written dword
|
* It is allowed to write only zeros over an already written dword / qword
|
||||||
* See 6.3.7 in STM32L5 reference manual.
|
* See 6.3.7 in STM32L5 reference manual.
|
||||||
* See 7.3.7 in STM32U5 reference manual.
|
* See 7.3.7 in STM32U5 reference manual.
|
||||||
|
* See 7.3.5 in STM32H5 reference manual.
|
||||||
*/
|
*/
|
||||||
if ((flash[0] != 0xFFFFFFFFUL ||
|
for (i = 0; i < n; i++) {
|
||||||
flash[1] != 0xFFFFFFFFUL) && val != 0UL) {
|
if (buff[i] != 0) {
|
||||||
LOG_ERR("Word at offs %ld not erased", (long)offset);
|
full_zero = false;
|
||||||
return -EIO;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!full_zero) {
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (flash[i] != 0xFFFFFFFFUL) {
|
||||||
|
LOG_ERR("Word at offs %ld not erased", (long)(offset + i));
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the NSPG bit */
|
/* Set the NSPG bit */
|
||||||
|
@ -194,8 +206,9 @@ static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
||||||
tmp = regs->NSCR;
|
tmp = regs->NSCR;
|
||||||
|
|
||||||
/* Perform the data write operation at the desired memory address */
|
/* Perform the data write operation at the desired memory address */
|
||||||
flash[0] = (uint32_t)val;
|
for (i = 0; i < n; i++) {
|
||||||
flash[1] = (uint32_t)(val >> 32);
|
flash[i] = buff[i];
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait until the NSBSY bit is cleared */
|
/* Wait until the NSBSY bit is cleared */
|
||||||
rc = flash_stm32_wait_flash_idle(dev);
|
rc = flash_stm32_wait_flash_idle(dev);
|
||||||
|
@ -343,8 +356,9 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < len; i += 8, offset += 8) {
|
for (i = 0; i < len; i += FLASH_STM32_WRITE_BLOCK_SIZE) {
|
||||||
rc = write_dword(dev, offset, ((const uint64_t *) data)[i>>3]);
|
rc = write_nwords(dev, offset + i, ((const uint32_t *) data + (i>>2)),
|
||||||
|
FLASH_STM32_WRITE_BLOCK_SIZE / 4);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue