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.terzioglu@espressif.com>
This commit is contained in:
Eren Terzioglu
2025-01-13 10:52:17 +01:00
committed by Alan C. Assis
parent 425ddc7f72
commit 5865d2a8ff
8 changed files with 230 additions and 0 deletions
+118
View File
@@ -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:
+18
View File
@@ -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.
*
+22
View File
@@ -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
+18
View File
@@ -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
+22
View File
@@ -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
+18
View File
@@ -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
@@ -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 );
@@ -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 );