drivers: flash: stm32g4: Flush caches after erase
This commit fixes sporadic kernel panics when writing big data chunks to the flash. (data bus errors) Reference manual: If an erase operation in Flash memory also concerns data in the data or instruction cache, you have to make sure that these data are rewritten before they are accessed during code execution. If this cannot be done safely, it is recommended to flush the caches by setting the DCRST and ICRST bits in the Flash access control register (FLASH_ACR). Signed-off-by: Alexander Wachter <alexander.wachter@leica-geosystems.com>
This commit is contained in:
parent
8c9b06ad82
commit
09fea5cc5e
|
@ -46,6 +46,29 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset,
|
|||
flash_stm32_range_exists(dev, offset, len);
|
||||
}
|
||||
|
||||
static inline void flush_cache(FLASH_TypeDef *regs)
|
||||
{
|
||||
if (regs->ACR & FLASH_ACR_DCEN) {
|
||||
regs->ACR &= ~FLASH_ACR_DCEN;
|
||||
/* Datasheet: DCRST: Data cache reset
|
||||
* This bit can be written only when thes data cache is disabled
|
||||
*/
|
||||
regs->ACR |= FLASH_ACR_DCRST;
|
||||
regs->ACR &= ~FLASH_ACR_DCRST;
|
||||
regs->ACR |= FLASH_ACR_DCEN;
|
||||
}
|
||||
|
||||
if (regs->ACR & FLASH_ACR_ICEN) {
|
||||
regs->ACR &= ~FLASH_ACR_ICEN;
|
||||
/* Datasheet: ICRST: Instruction cache reset :
|
||||
* This bit can be written only when the instruction cache
|
||||
* is disabled
|
||||
*/
|
||||
regs->ACR |= FLASH_ACR_ICRST;
|
||||
regs->ACR &= ~FLASH_ACR_ICRST;
|
||||
regs->ACR |= FLASH_ACR_ICEN;
|
||||
}
|
||||
}
|
||||
|
||||
static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
||||
{
|
||||
|
@ -159,6 +182,8 @@ static int erase_page(const struct device *dev, unsigned int offset)
|
|||
/* Wait for the BSY bit */
|
||||
rc = flash_stm32_wait_flash_idle(dev);
|
||||
|
||||
flush_cache(regs);
|
||||
|
||||
#ifdef FLASH_OPTR_DBANK
|
||||
regs->CR &= ~(FLASH_CR_PER | FLASH_CR_BKER);
|
||||
#else
|
||||
|
|
Loading…
Reference in a new issue