diff --git a/drivers/flash/Kconfig.nrf_rram b/drivers/flash/Kconfig.nrf_rram index a59560e86a4..d8a5abf64b2 100644 --- a/drivers/flash/Kconfig.nrf_rram +++ b/drivers/flash/Kconfig.nrf_rram @@ -56,8 +56,15 @@ config SOC_FLASH_NRF_RADIO_SYNC_NONE bool "none" help disable synchronization between flash memory driver and radio. + endchoice +config SOC_FLASH_NRF_THROTTLING + bool "Nordic nRFx throttling for flash write operations" + help + Enable throttling for flash write operations to avoid overloading the + flash memory controller. + config SOC_FLASH_NRF_TIMEOUT_MULTIPLIER int "Multiplier for flash operation timeouts [x0.1]" depends on !SOC_FLASH_NRF_RADIO_SYNC_NONE @@ -81,4 +88,20 @@ config NRF_RRAM_REGION_SIZE_UNIT help Base unit for the size of RRAMC's region protection. +config NRF_RRAM_THROTTLING_DELAY + int "Delay between flash write operations" + depends on SOC_FLASH_NRF_THROTTLING + default 2000 + help + This is the delay (in microseconds) between consecutive flash write + operations when throttling is enabled. + +config NRF_RRAM_THROTTLING_DATA_BLOCK + int "Number of Data blocks for each flash write operations" + depends on SOC_FLASH_NRF_THROTTLING + default 16 + help + This is the number of data blocks (in number of 128-bit words) for flash write + operations when throttling is enabled. + endif # SOC_FLASH_NRF_RRAM diff --git a/drivers/flash/soc_flash_nrf_rram.c b/drivers/flash/soc_flash_nrf_rram.c index d46e3524ea8..84c7e958f3c 100644 --- a/drivers/flash/soc_flash_nrf_rram.c +++ b/drivers/flash/soc_flash_nrf_rram.c @@ -164,11 +164,24 @@ static void rram_write(off_t addr, const void *data, size_t len) nrf_rramc_config_set(NRF_RRAMC, &config); #endif - if (data) { - memcpy((void *)addr, data, len); - } else { - memset((void *)addr, ERASE_VALUE, len); + size_t chunk_len = len; + +#ifdef CONFIG_SOC_FLASH_NRF_THROTTLING + while (len > 0) { + chunk_len = MIN(len, CONFIG_NRF_RRAM_THROTTLING_DATA_BLOCK * WRITE_LINE_SIZE); +#endif /* CONFIG_SOC_FLASH_NRF_THROTTLING */ + if (data) { + memcpy((void *)addr, data, chunk_len); + } else { + memset((void *)addr, ERASE_VALUE, chunk_len); + } +#ifdef CONFIG_SOC_FLASH_NRF_THROTTLING + addr += chunk_len; + data = (const uint8_t *)data + chunk_len; + len -= chunk_len; + k_usleep(CONFIG_NRF_RRAM_THROTTLING_DELAY); } +#endif /* CONFIG_SOC_FLASH_NRF_THROTTLING */ barrier_dmem_fence_full(); /* Barrier following our last write. */