diff --git a/soc/xtensa/espressif_esp32/common/Kconfig.soc b/soc/xtensa/espressif_esp32/common/Kconfig.soc index 4cf8bf9095f824d..3446e6882434cfc 100644 --- a/soc/xtensa/espressif_esp32/common/Kconfig.soc +++ b/soc/xtensa/espressif_esp32/common/Kconfig.soc @@ -40,6 +40,15 @@ config ESP_HEAP_SEARCH_ALL_REGIONS menu "SPI RAM config" depends on ESP_SPIRAM +choice SPIRAM_MODE + prompt "Mode (QUAD/OCT) of SPI RAM chip in use" + default SPIRAM_MODE_QUAD + +config SPIRAM_MODE_QUAD + bool "Quad Mode PSRAM" + +endchoice # SPIRAM_MODE + choice SPIRAM_TYPE prompt "Type of SPI RAM chip in use" depends on ESP_SPIRAM @@ -98,6 +107,10 @@ config SPIRAM_SPEED_80M depends on ESPTOOLPY_FLASHFREQ_80M bool "80MHz clock speed" +config SPIRAM_SPEED_120M + depends on SPIRAM_MODE_QUAD && SOC_SERIES_ESP32S3 + bool "120MHz clock speed" + endchoice # SPIRAM_SPEED menu "PSRAM clock and cs IO for ESP32-DOWD" diff --git a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc index 7dd8fc4dddb83a6..ac265e5edb011fb 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc +++ b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc @@ -293,4 +293,23 @@ config MAC_BB_PD endmenu # Cache config +menu "PSRAM Clock and CS IO for ESP32S3" + depends on ESP_SPIRAM + +config DEFAULT_PSRAM_CLK_IO + int "PSRAM CLK IO number" + range 0 33 + default 30 + help + The PSRAM Clock IO can be any unused GPIO, please refer to your hardware design. + +config DEFAULT_PSRAM_CS_IO + int "PSRAM CS IO number" + range 0 33 + default 26 + help + The PSRAM CS IO can be any unused GPIO, please refer to your hardware design. + +endmenu # PSRAM clock and cs IO for ESP32S3 + endif # SOC_SERIES_ESP32S3 diff --git a/soc/xtensa/espressif_esp32/esp32s3/default.ld b/soc/xtensa/espressif_esp32/esp32s3/default.ld index 4361e7b38e3abf3..0dc46e7d7f7ac75 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/default.ld @@ -39,6 +39,8 @@ #define RAMABLE_REGION dram0_0_seg #define ROMABLE_REGION ROM +#define EXT_RAM_ORG (0x3E000000 - CONFIG_ESP_SPIRAM_SIZE) + #ifdef CONFIG_FLASH_SIZE #define FLASH_SIZE CONFIG_FLASH_SIZE #else @@ -70,7 +72,13 @@ MEMORY * Hence, an offset of 0x40 is added to DROM segment origin. */ drom0_0_seg(R): org = 0x3C000040, len = FLASH_SIZE - 0x40 - + /** + * `extern_ram_seg` and `drom0_0_seg` share the same bus and the address region. + * so we allocate `extern_ram_seg` at the end of the address region. + */ +#if defined(CONFIG_ESP_SPIRAM) + ext_ram_seg(RWX): org = EXT_RAM_ORG, len = CONFIG_ESP_SPIRAM_SIZE +#endif /* RTC fast memory (executable). Persists over deep sleep. */ rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000 @@ -219,6 +227,17 @@ SECTIONS _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) +#if defined(CONFIG_ESP_SPIRAM) + /* This section holds .ext_ram.bss data, and will be put in PSRAM */ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + . = ALIGN(0x10000); + _ext_ram_bss_end = ABSOLUTE(.); + } > ext_ram_seg +#endif + /* Send .iram0 code to iram */ .iram0.vectors : ALIGN(4) { @@ -272,6 +291,9 @@ SECTIONS *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libzephyr.a:spiram*.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_timing*.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash*.*(.literal .text .literal.* .text.*) *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) *libzephyr.a:windowspill_asm.*(.literal .text .literal.* .text.*) *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) @@ -642,3 +664,8 @@ SECTIONS ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), "IRAM0 segment data does not fit.") + +#if defined(CONFIG_ESP_SPIRAM) +ASSERT(((ORIGIN(ext_ram_seg)) > _image_rodata_end), + "External RAM segment does not fit.") +#endif diff --git a/soc/xtensa/espressif_esp32/esp32s3/soc.c b/soc/xtensa/espressif_esp32/esp32s3/soc.c index 3e8bb7373202e71..9c230c9d6b8b566 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/soc.c +++ b/soc/xtensa/espressif_esp32/esp32s3/soc.c @@ -34,11 +34,18 @@ #include "esp_app_format.h" #include "esp_clk_internal.h" +#include "esp32s3/spiram.h" + #ifdef CONFIG_MCUBOOT #include "bootloader_init.h" #endif /* CONFIG_MCUBOOT */ #include +#if CONFIG_ESP_SPIRAM +extern int _ext_ram_bss_start; +extern int _ext_ram_bss_end; +#endif + extern void z_cstart(void); #ifndef CONFIG_MCUBOOT @@ -104,6 +111,31 @@ void IRAM_ATTR __esp_platform_start(void) /* Apply SoC patches */ esp_errata(); + +#if CONFIG_ESP_SPIRAM + esp_err_t err = esp_spiram_init(); + + if (err != ESP_OK) { + printk("Failed to Initialize external RAM, aborting.\n"); + abort(); + } + + esp_spiram_init_cache(); + if (esp_spiram_get_size() < CONFIG_ESP_SPIRAM_SIZE) { + printk("External RAM size is less than configured, aborting.\n"); + abort(); + } + + if (!esp_spiram_test()) { + printk("External RAM failed memory test!\n"); + abort(); + } + + memset(&_ext_ram_bss_start, 0, + (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); + +#endif /* CONFIG_ESP_SPIRAM */ + /* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check on startup sequence * related issues in application. Hence disable that as we are about to start * Zephyr environment.