diff --git a/CODEOWNERS b/CODEOWNERS index d3dd3263998..e154695da38 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -242,6 +242,7 @@ /drivers/flash/ @nashif @nvlsianpu /drivers/flash/*b91* @yurvyn /drivers/flash/*nrf* @nvlsianpu +/drivers/flash/*esp32* @glaubermaroto /drivers/fpga/ @tgorochowik @kgugala /drivers/gpio/ @mnkp /drivers/gpio/*b91* @yurvyn diff --git a/boards/xtensa/esp32s2_saola/esp32s2_saola.dts b/boards/xtensa/esp32s2_saola/esp32s2_saola.dts index 52c5b8e0a40..6d2e03897bc 100644 --- a/boards/xtensa/esp32s2_saola/esp32s2_saola.dts +++ b/boards/xtensa/esp32s2_saola/esp32s2_saola.dts @@ -16,6 +16,7 @@ zephyr,sram = &sram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; }; }; diff --git a/drivers/flash/Kconfig.esp32 b/drivers/flash/Kconfig.esp32 index be1d621c277..6306ba18931 100644 --- a/drivers/flash/Kconfig.esp32 +++ b/drivers/flash/Kconfig.esp32 @@ -6,7 +6,7 @@ config SOC_FLASH_ESP32 default y select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT - depends on SOC_ESP32 + depends on SOC_ESP32 || SOC_ESP32S2 help Enable ESP32 internal flash driver. diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c index 7f8bf0b150f..06f575066c7 100644 --- a/drivers/flash/flash_esp32.c +++ b/drivers/flash/flash_esp32.c @@ -24,14 +24,19 @@ #include #include -#if CONFIG_SOC_ESP32 +#if defined(CONFIG_SOC_ESP32) #include "soc/dport_reg.h" #include "esp32/rom/cache.h" #include "esp32/rom/spi_flash.h" #include "esp32/spiram.h" -#include "soc/mmu.h" +#elif defined(CONFIG_SOC_ESP32S2) +#include "soc/spi_mem_reg.h" +#include "esp32s2/rom/cache.h" +#include "esp32s2/rom/spi_flash.h" #endif +#include "soc/mmu.h" + #include LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL); @@ -58,6 +63,17 @@ static const struct flash_parameters flash_esp32_parameters = { #define ADDRESS_MASK_24BIT 0xFFFFFF #define SPI_TIMEOUT_MSEC 500 +#if defined(CONFIG_SOC_ESP32) +#define HOST_FLASH_CONTROLLER SPI0 +#define HOST_FLASH_RDSR SPI_FLASH_RDSR +#define HOST_FLASH_FASTRD SPI_FASTRD_MODE +#elif defined(CONFIG_SOC_ESP32S2) +#define HOST_FLASH_CONTROLLER SPIMEM0 +#define HOST_FLASH_RDSR SPI_MEM_FLASH_RDSR +#define HOST_FLASH_FASTRD SPI_MEM_FASTRD_MODE +#endif + + static inline void flash_esp32_sem_take(const struct device *dev) { k_sem_take(&DEV_DATA(dev)->sem, K_FOREVER); @@ -108,10 +124,12 @@ int configure_read_mode(spi_dev_t *hw, return 0; } -static bool IRAM_ATTR flash_esp32_mapped_in_cache(uint32_t phys_page) +static bool IRAM_ATTR flash_esp32_mapped_in_cache(uint32_t phys_page, const void **out_ptr) { int start[2], end[2]; + *out_ptr = NULL; + /* SPI_FLASH_MMAP_DATA */ start[0] = SOC_MMU_DROM0_PAGES_START; end[0] = SOC_MMU_DROM0_PAGES_END; @@ -126,6 +144,15 @@ static bool IRAM_ATTR flash_esp32_mapped_in_cache(uint32_t phys_page) if (DPORT_SEQUENCE_REG_READ( (uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) == SOC_MMU_PAGE_IN_FLASH(phys_page)) { +#if !defined(CONFIG_SOC_ESP32) + if (j == 0) { /* SPI_FLASH_MMAP_DATA */ + *out_ptr = (const void *)(SOC_MMU_VADDR0_START_ADDR + + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0])); + } else { + *out_ptr = (const void *)(SOC_MMU_VADDR1_FIRST_USABLE_ADDR + + SPI_FLASH_MMU_PAGE_SIZE * (i - start[1])); + } +#endif DPORT_INTERRUPT_RESTORE(); return true; } @@ -154,8 +181,10 @@ static void IRAM_ATTR flash_esp32_flush_cache(size_t start_addr, size_t length) return; } - if (flash_esp32_mapped_in_cache(page)) { + const void *vaddr = NULL; + if (flash_esp32_mapped_in_cache(page, &vaddr)) { +#if defined(CONFIG_SOC_ESP32) #if CONFIG_ESP_SPIRAM esp_spiram_writeback_cache(); #endif @@ -164,8 +193,15 @@ static void IRAM_ATTR flash_esp32_flush_cache(size_t start_addr, size_t length) esp_rom_Cache_Flush(1); #endif return; +#else /* CONFIG_SOC_ESP32 */ + if (vaddr != NULL) { + esp_rom_Cache_Invalidate_Addr((uint32_t)vaddr, + SPI_FLASH_MMU_PAGE_SIZE); + } +#endif /* CONFIG_SOC_ESP32 */ } } + return; } static int set_read_options(const struct device *dev) @@ -177,13 +213,13 @@ static int set_read_options(const struct device *dev) bool byte_cmd = true; uint32_t read_mode = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL); - if ((read_mode & SPI_FREAD_QIO) && (read_mode & SPI_FASTRD_MODE)) { + if ((read_mode & SPI_FREAD_QIO) && (read_mode & HOST_FLASH_FASTRD)) { spi_ll_enable_mosi(hw, 0); spi_ll_enable_miso(hw, 1); dummy_len = 1 + SPI1_R_QIO_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES; addr_len = SPI1_R_QIO_ADDR_BITSLEN + 1; read_cmd = CMD_FASTRD_QIO; - } else if (read_mode & SPI_FASTRD_MODE) { + } else if (read_mode & HOST_FLASH_FASTRD) { spi_ll_enable_mosi(hw, 0); spi_ll_enable_miso(hw, 1); if (read_mode & SPI_FREAD_DIO) { @@ -271,6 +307,10 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); uint32_t chip_size = cfg->chip->chip_size; +#if defined(CONFIG_SOC_ESP32S2) + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CTRL, 0); +#endif + if (length == 0) { return 0; } @@ -359,7 +399,7 @@ static int read_status(const struct device *dev, uint32_t *status) while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_RDSR); + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, HOST_FLASH_RDSR); int rc = flash_esp32_wait_cmd_done(cfg->controller); @@ -382,9 +422,15 @@ static int read_status(const struct device *dev, uint32_t *status) static inline bool host_idle(spi_dev_t *hw) { +#if defined(CONFIG_SOC_ESP32) bool idle = spi_flash_ll_host_idle(hw); - idle &= spi_flash_ll_host_idle(&SPI0); + idle &= spi_flash_ll_host_idle(&HOST_FLASH_CONTROLLER); +#elif defined(CONFIG_SOC_ESP32S2) + bool idle = spimem_flash_ll_host_idle((spi_mem_dev_t *)hw); + + idle &= spimem_flash_ll_host_idle(&HOST_FLASH_CONTROLLER); +#endif return idle; } diff --git a/dts/xtensa/espressif/esp32s2.dtsi b/dts/xtensa/espressif/esp32s2.dtsi index 43756489c83..bfde3a4651e 100644 --- a/dts/xtensa/espressif/esp32s2.dtsi +++ b/dts/xtensa/espressif/esp32s2.dtsi @@ -15,6 +15,7 @@ chosen { zephyr,entropy = &trng0; + zephyr,flash-controller = &flash; }; cpus { @@ -64,6 +65,23 @@ status = "ok"; }; + flash: flash-controller@3f402000 { + compatible = "espressif,esp32-flash-controller"; + label = "FLASH_CTRL"; + reg = <0x3f402000 0x1000>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + label = "FLASH_ESP32S2"; + reg = <0 0x400000>; + erase-block-size = <4096>; + write-block-size = <4>; + }; + }; + uart0: uart@3f400000 { compatible = "espressif,esp32-uart"; reg = <0x3f400000 0x400>; diff --git a/soc/xtensa/esp32s2/linker.ld b/soc/xtensa/esp32s2/linker.ld index c4ac4e83a94..3cb9e53dacd 100644 --- a/soc/xtensa/esp32s2/linker.ld +++ b/soc/xtensa/esp32s2/linker.ld @@ -220,6 +220,7 @@ _net_buf_pool_list = _esp_net_buf_pool_list; *libzephyr.a:log_core.*(.rodata .rodata.*) *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) *libzephyr.a:log_output.*(.rodata .rodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) . = ALIGN(4); __esp_log_const_start = .; @@ -310,6 +311,7 @@ __shell_root_cmds_end = __esp_shell_root_cmds_end; *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) *libgcc.a:lib2funcs.*(.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.*) *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) diff --git a/soc/xtensa/esp32s2/soc.c b/soc/xtensa/esp32s2/soc.c index fa874b5bf16..1b0cd0b37e4 100644 --- a/soc/xtensa/esp32s2/soc.c +++ b/soc/xtensa/esp32s2/soc.c @@ -20,6 +20,7 @@ #include "esp_private/system_internal.h" #include "esp32s2/rom/cache.h" #include "soc/gpio_periph.h" +#include "esp_spi_flash.h" #include "hal/cpu_ll.h" #include "esp_err.h" #include "sys/printk.h" @@ -118,6 +119,9 @@ void __attribute__((section(".iram1"))) __start(void) *wdt_rtc_protect = 0; #endif +#if CONFIG_SOC_FLASH_ESP32 + spi_flash_guard_set(&g_flash_guard_default_ops); +#endif esp_intr_initialize(); /* Start Zephyr */ z_cstart(); diff --git a/soc/xtensa/esp32s2/soc.h b/soc/xtensa/esp32s2/soc.h index 9545edd85e4..ae1d3622207 100644 --- a/soc/xtensa/esp32s2/soc.h +++ b/soc/xtensa/esp32s2/soc.h @@ -42,7 +42,12 @@ extern void esp_rom_Cache_Set_ICache_Mode(cache_size_t cache_size, cache_ways_t cache_line_size_t cache_line_size); extern void esp_rom_Cache_Invalidate_ICache_All(void); -void esp_rom_Cache_Resume_ICache(uint32_t autoload); +extern void esp_rom_Cache_Resume_ICache(uint32_t autoload); +extern int esp_rom_Cache_Invalidate_Addr(uint32_t addr, uint32_t size); + +/* ROM information related to SPI Flash chip timing and device */ +extern esp_rom_spiflash_chip_t g_rom_flashchip; +extern uint8_t g_rom_spiflash_dummy_len_plus[]; extern uint32_t esp_rom_g_ticks_per_us_pro;