This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 5865d2a8ff5bda14497ac65571c2f9d0bccb4964 Author: Eren Terzioglu <eren.terzio...@espressif.com> AuthorDate: Mon Jan 13 10:52:17 2025 +0100 esp32[s2|s3]: Enhance SPIRAM/PSRAM support Add esp_spiram_writeback_range function to flush some areas of spiram cache Signed-off-by: Eren Terzioglu <eren.terzio...@espressif.com> --- arch/xtensa/src/esp32/esp32_spiram.c | 118 +++++++++++++++++++++ arch/xtensa/src/esp32/esp32_spiram.h | 18 ++++ arch/xtensa/src/esp32s2/esp32s2_spiram.c | 22 ++++ arch/xtensa/src/esp32s2/esp32s2_spiram.h | 18 ++++ arch/xtensa/src/esp32s3/esp32s3_spiram.c | 22 ++++ arch/xtensa/src/esp32s3/esp32s3_spiram.h | 18 ++++ .../esp32s2/common/scripts/esp32s2_aliases.ld | 12 +++ .../esp32s3/common/scripts/esp32s3_rom_aliases.ld | 2 + 8 files changed, 230 insertions(+) diff --git a/arch/xtensa/src/esp32/esp32_spiram.c b/arch/xtensa/src/esp32/esp32_spiram.c index 0b94d27490..d9ff290df4 100644 --- a/arch/xtensa/src/esp32/esp32_spiram.c +++ b/arch/xtensa/src/esp32/esp32_spiram.c @@ -34,6 +34,7 @@ #include <sys/param.h> #include <nuttx/spinlock.h> #include <nuttx/init.h> +#include <nuttx/nuttx.h> #include "esp32_spiram.h" #include "esp32_spicache.h" @@ -533,6 +534,123 @@ void IRAM_ATTR esp_spiram_writeback_cache(void) #endif } +/**************************************************************************** + * Name: esp_spiram_writeback_range + * + * Description: + * Writeback the Cache items (also clean the dirty bit) in the region from + * DCache. If the region is not in DCache addr room, nothing will be done. + * + * Input Parameters: + * addr - writeback region start address + * size - writeback region size + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_spiram_writeback_range(uint32_t addr, uint32_t size) +{ + int x; + uint32_t regval; + uint32_t start_len; + uint32_t end_len; + uint32_t start = addr; + uint32_t end = addr + size; + uint32_t dcache_line_size = 32; + volatile int i = 0; + volatile uint8_t *psram = (volatile uint8_t *)SOC_EXTRAM_DATA_LOW; + int cache_was_disabled = 0; + + if (!spiram_inited) + { + return; + } + + /* We need cache enabled for this to work. Re-enable it if needed; make + * sure we disable it again on exit as well. + */ + + regval = getreg32(DPORT_PRO_CACHE_CTRL_REG); + + if ((regval & DPORT_PRO_CACHE_ENABLE) == 0) + { + cache_was_disabled |= (1 << 0); + regval = getreg32(DPORT_PRO_CACHE_CTRL_REG); + regval |= (1 << DPORT_PRO_CACHE_ENABLE_S); + putreg32(regval, DPORT_PRO_CACHE_CTRL_REG); + } + +#ifdef CONFIG_SMP + regval = getreg32(DPORT_APP_CACHE_CTRL_REG); + + if ((regval & DPORT_APP_CACHE_ENABLE) == 0) + { + cache_was_disabled |= (1 << 1); + regval = getreg32(DPORT_APP_CACHE_CTRL_REG); + regval |= 1 << DPORT_APP_CACHE_ENABLE_S; + putreg32(regval, DPORT_APP_CACHE_CTRL_REG); + } +#endif + + /* the start address is unaligned */ + + if (start & (dcache_line_size -1)) + { + addr = ALIGN_UP_MASK(start, dcache_line_size); + start_len = addr - start; + size = (size < start_len) ? 0 : (size - start_len); + i += psram[start_len]; + } + + /* the end address is unaligned */ + + if ((end & (dcache_line_size -1)) && (size != 0)) + { + end = ALIGN_DOWN_MASK(end, dcache_line_size); + end_len = addr + size - end; + size = (size - end_len); + i += psram[end_len]; + } + + if (size != 0) + { + for (x = addr; x < addr + size; x += 32) + { + i += psram[x]; + } + } + + if (cache_was_disabled & (1 << 0)) + { + while (((getreg32(DPORT_PRO_DCACHE_DBUG0_REG) >> + (DPORT_PRO_CACHE_STATE_S)) & + (DPORT_PRO_CACHE_STATE)) != 1) + { + }; + + regval = getreg32(DPORT_PRO_CACHE_CTRL_REG); + regval &= ~(1 << DPORT_PRO_CACHE_ENABLE_S); + putreg32(regval, DPORT_PRO_CACHE_CTRL_REG); + } + +#ifdef CONFIG_SMP + if (cache_was_disabled & (1 << 1)) + { + while (((getreg32(DPORT_APP_DCACHE_DBUG0_REG) >> + (DPORT_APP_CACHE_STATE_S)) & + (DPORT_APP_CACHE_STATE)) != 1) + { + }; + + regval = getreg32(DPORT_APP_CACHE_CTRL_REG); + regval &= ~(1 << DPORT_APP_CACHE_ENABLE_S); + putreg32(regval, DPORT_APP_CACHE_CTRL_REG); + } +#endif +} + /* If SPI RAM(PSRAM) has been initialized * * Return: diff --git a/arch/xtensa/src/esp32/esp32_spiram.h b/arch/xtensa/src/esp32/esp32_spiram.h index 4d2b2b863b..065c538998 100644 --- a/arch/xtensa/src/esp32/esp32_spiram.h +++ b/arch/xtensa/src/esp32/esp32_spiram.h @@ -145,6 +145,24 @@ size_t esp_spiram_get_size(void); void esp_spiram_writeback_cache(void); +/**************************************************************************** + * Name: esp_spiram_writeback_range + * + * Description: + * Writeback the Cache items (also clean the dirty bit) in the region from + * DCache. If the region is not in DCache addr room, nothing will be done. + * + * Input Parameters: + * addr - writeback region start address + * size - writeback region size + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_spiram_writeback_range(uint32_t addr, uint32_t size); + /* Description: Reserve a pool of internal memory for specific DMA/internal * allocations. * diff --git a/arch/xtensa/src/esp32s2/esp32s2_spiram.c b/arch/xtensa/src/esp32s2/esp32s2_spiram.c index 8a8c09357b..e3941bcbac 100644 --- a/arch/xtensa/src/esp32s2/esp32s2_spiram.c +++ b/arch/xtensa/src/esp32s2/esp32s2_spiram.c @@ -40,6 +40,7 @@ #include "hardware/esp32s2_soc.h" #include "hardware/esp32s2_cache_memory.h" #include "hardware/esp32s2_iomux.h" +#include "hal/cache_hal.h" #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" @@ -361,6 +362,27 @@ void IRAM_ATTR esp_spiram_writeback_cache(void) cache_writeback_all(); } +/**************************************************************************** + * Name: esp_spiram_writeback_range + * + * Description: + * Writeback the Cache items (also clean the dirty bit) in the region from + * DCache. If the region is not in DCache addr room, nothing will be done. + * + * Input Parameters: + * addr - writeback region start address + * size - writeback region size + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_spiram_writeback_range(uint32_t addr, uint32_t size) +{ + cache_hal_writeback_addr(addr, size); +} + /* If SPI RAM(PSRAM) has been initialized * * Return true SPI RAM has been initialized successfully diff --git a/arch/xtensa/src/esp32s2/esp32s2_spiram.h b/arch/xtensa/src/esp32s2/esp32s2_spiram.h index fe9e077db1..7d61683595 100644 --- a/arch/xtensa/src/esp32s2/esp32s2_spiram.h +++ b/arch/xtensa/src/esp32s2/esp32s2_spiram.h @@ -87,6 +87,24 @@ size_t esp_spiram_get_size(void); void esp_spiram_writeback_cache(void); +/**************************************************************************** + * Name: esp_spiram_writeback_range + * + * Description: + * Writeback the Cache items (also clean the dirty bit) in the region from + * DCache. If the region is not in DCache addr room, nothing will be done. + * + * Input Parameters: + * addr - writeback region start address + * size - writeback region size + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_spiram_writeback_range(uint32_t addr, uint32_t size); + /* If SPI RAM(PSRAM) has been initialized * * Return diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiram.c b/arch/xtensa/src/esp32s3/esp32s3_spiram.c index aba0956b00..079ba4ce0c 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiram.c +++ b/arch/xtensa/src/esp32s3/esp32s3_spiram.c @@ -42,6 +42,7 @@ #include "hardware/esp32s3_soc.h" #include "hardware/esp32s3_cache_memory.h" #include "hardware/esp32s3_iomux.h" +#include "hal/cache_hal.h" #include "soc/extmem_reg.h" @@ -697,6 +698,27 @@ void IRAM_ATTR esp_spiram_writeback_cache(void) cache_writeback_all(); } +/**************************************************************************** + * Name: esp_spiram_writeback_range + * + * Description: + * Writeback the Cache items (also clean the dirty bit) in the region from + * DCache. If the region is not in DCache addr room, nothing will be done. + * + * Input Parameters: + * addr - writeback region start address + * size - writeback region size + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_spiram_writeback_range(uint32_t addr, uint32_t size) +{ + cache_hal_writeback_addr(addr, size); +} + /* If SPI RAM(PSRAM) has been initialized * * Return true SPI RAM has been initialized successfully diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiram.h b/arch/xtensa/src/esp32s3/esp32s3_spiram.h index 043398788d..788e2e8701 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiram.h +++ b/arch/xtensa/src/esp32s3/esp32s3_spiram.h @@ -105,6 +105,24 @@ size_t esp_spiram_get_size(void); void esp_spiram_writeback_cache(void); +/**************************************************************************** + * Name: esp_spiram_writeback_range + * + * Description: + * Writeback the Cache items (also clean the dirty bit) in the region from + * DCache. If the region is not in DCache addr room, nothing will be done. + * + * Input Parameters: + * addr - writeback region start address + * size - writeback region size + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_spiram_writeback_range(uint32_t addr, uint32_t size); + /* If SPI RAM(PSRAM) has been initialized * * Return diff --git a/boards/xtensa/esp32s2/common/scripts/esp32s2_aliases.ld b/boards/xtensa/esp32s2/common/scripts/esp32s2_aliases.ld index 4a52404933..0208cb53fa 100644 --- a/boards/xtensa/esp32s2/common/scripts/esp32s2_aliases.ld +++ b/boards/xtensa/esp32s2/common/scripts/esp32s2_aliases.ld @@ -36,3 +36,15 @@ PROVIDE( rom_i2c_readreg = rom_i2c_readReg ); PROVIDE( rom_i2c_readreg_mask = rom_i2c_readReg_Mask ); PROVIDE( rom_i2c_writereg = rom_i2c_writeReg ); PROVIDE( rom_i2c_writereg_mask = rom_i2c_writeReg_Mask ); +PROVIDE( cache_dbus_mmu_set = Cache_Dbus_MMU_Set ); +PROVIDE( cache_ibus_mmu_set = Cache_Ibus_MMU_Set ); +PROVIDE( cache_invalidate_addr = Cache_Invalidate_Addr ); +PROVIDE( cache_invalidate_dcache_all = Cache_Invalidate_DCache_All ); +PROVIDE( cache_occupy_addr = Cache_Occupy_Addr ); +PROVIDE( cache_set_idrom_mmu_info = Cache_Set_IDROM_MMU_Info ); +PROVIDE( cache_set_idrom_mmu_size = Cache_Set_IDROM_MMU_Size ); +PROVIDE( cache_writeback_all = Cache_WriteBack_All ); +PROVIDE( cache_writeback_items = Cache_WriteBack_Items ); +PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr ); +PROVIDE( cache_set_dcache_mode = Cache_Set_DCache_Mode ); +PROVIDE( cache_enable_dcache = Cache_Enable_DCache ); diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld index 27d70ec783..245e941f9f 100644 --- a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld +++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld @@ -37,3 +37,5 @@ PROVIDE( cache_set_idrom_mmu_size = Cache_Set_IDROM_MMU_Size ); PROVIDE( cache_suspend_dcache = Cache_Suspend_DCache ); PROVIDE( cache_suspend_icache = Cache_Suspend_ICache ); PROVIDE( cache_writeback_all = Cache_WriteBack_All ); +PROVIDE( cache_writeback_items = Cache_WriteBack_Items ); +PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr );