soc: esp32s2: drivers: flash: add support
to host SPI Flash driver. Signed-off-by: Glauber Maroto Ferreira <glauber.ferreira@espressif.com>
This commit is contained in:
parent
813a74d415
commit
dcf26d72f5
8 changed files with 87 additions and 10 deletions
|
@ -242,6 +242,7 @@
|
||||||
/drivers/flash/ @nashif @nvlsianpu
|
/drivers/flash/ @nashif @nvlsianpu
|
||||||
/drivers/flash/*b91* @yurvyn
|
/drivers/flash/*b91* @yurvyn
|
||||||
/drivers/flash/*nrf* @nvlsianpu
|
/drivers/flash/*nrf* @nvlsianpu
|
||||||
|
/drivers/flash/*esp32* @glaubermaroto
|
||||||
/drivers/fpga/ @tgorochowik @kgugala
|
/drivers/fpga/ @tgorochowik @kgugala
|
||||||
/drivers/gpio/ @mnkp
|
/drivers/gpio/ @mnkp
|
||||||
/drivers/gpio/*b91* @yurvyn
|
/drivers/gpio/*b91* @yurvyn
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
zephyr,sram = &sram0;
|
zephyr,sram = &sram0;
|
||||||
zephyr,console = &uart0;
|
zephyr,console = &uart0;
|
||||||
zephyr,shell-uart = &uart0;
|
zephyr,shell-uart = &uart0;
|
||||||
|
zephyr,flash = &flash0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ config SOC_FLASH_ESP32
|
||||||
default y
|
default y
|
||||||
select FLASH_HAS_DRIVER_ENABLED
|
select FLASH_HAS_DRIVER_ENABLED
|
||||||
select FLASH_HAS_PAGE_LAYOUT
|
select FLASH_HAS_PAGE_LAYOUT
|
||||||
depends on SOC_ESP32
|
depends on SOC_ESP32 || SOC_ESP32S2
|
||||||
help
|
help
|
||||||
Enable ESP32 internal flash driver.
|
Enable ESP32 internal flash driver.
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,19 @@
|
||||||
#include <soc/spi_struct.h>
|
#include <soc/spi_struct.h>
|
||||||
#include <spi_flash_defs.h>
|
#include <spi_flash_defs.h>
|
||||||
|
|
||||||
#if CONFIG_SOC_ESP32
|
#if defined(CONFIG_SOC_ESP32)
|
||||||
#include "soc/dport_reg.h"
|
#include "soc/dport_reg.h"
|
||||||
#include "esp32/rom/cache.h"
|
#include "esp32/rom/cache.h"
|
||||||
#include "esp32/rom/spi_flash.h"
|
#include "esp32/rom/spi_flash.h"
|
||||||
#include "esp32/spiram.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
|
#endif
|
||||||
|
|
||||||
|
#include "soc/mmu.h"
|
||||||
|
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL);
|
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 ADDRESS_MASK_24BIT 0xFFFFFF
|
||||||
#define SPI_TIMEOUT_MSEC 500
|
#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)
|
static inline void flash_esp32_sem_take(const struct device *dev)
|
||||||
{
|
{
|
||||||
k_sem_take(&DEV_DATA(dev)->sem, K_FOREVER);
|
k_sem_take(&DEV_DATA(dev)->sem, K_FOREVER);
|
||||||
|
@ -108,10 +124,12 @@ int configure_read_mode(spi_dev_t *hw,
|
||||||
return 0;
|
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];
|
int start[2], end[2];
|
||||||
|
|
||||||
|
*out_ptr = NULL;
|
||||||
|
|
||||||
/* SPI_FLASH_MMAP_DATA */
|
/* SPI_FLASH_MMAP_DATA */
|
||||||
start[0] = SOC_MMU_DROM0_PAGES_START;
|
start[0] = SOC_MMU_DROM0_PAGES_START;
|
||||||
end[0] = SOC_MMU_DROM0_PAGES_END;
|
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(
|
if (DPORT_SEQUENCE_REG_READ(
|
||||||
(uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) ==
|
(uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) ==
|
||||||
SOC_MMU_PAGE_IN_FLASH(phys_page)) {
|
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();
|
DPORT_INTERRUPT_RESTORE();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -154,8 +181,10 @@ static void IRAM_ATTR flash_esp32_flush_cache(size_t start_addr, size_t length)
|
||||||
return;
|
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
|
#if CONFIG_ESP_SPIRAM
|
||||||
esp_spiram_writeback_cache();
|
esp_spiram_writeback_cache();
|
||||||
#endif
|
#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);
|
esp_rom_Cache_Flush(1);
|
||||||
#endif
|
#endif
|
||||||
return;
|
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)
|
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;
|
bool byte_cmd = true;
|
||||||
uint32_t read_mode = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL);
|
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_mosi(hw, 0);
|
||||||
spi_ll_enable_miso(hw, 1);
|
spi_ll_enable_miso(hw, 1);
|
||||||
dummy_len = 1 + SPI1_R_QIO_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES;
|
dummy_len = 1 + SPI1_R_QIO_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES;
|
||||||
addr_len = SPI1_R_QIO_ADDR_BITSLEN + 1;
|
addr_len = SPI1_R_QIO_ADDR_BITSLEN + 1;
|
||||||
read_cmd = CMD_FASTRD_QIO;
|
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_mosi(hw, 0);
|
||||||
spi_ll_enable_miso(hw, 1);
|
spi_ll_enable_miso(hw, 1);
|
||||||
if (read_mode & SPI_FREAD_DIO) {
|
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();
|
const spi_flash_guard_funcs_t *guard = spi_flash_guard_get();
|
||||||
uint32_t chip_size = cfg->chip->chip_size;
|
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) {
|
if (length == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -359,7 +399,7 @@ static int read_status(const struct device *dev, uint32_t *status)
|
||||||
while (ESP_ROM_SPIFLASH_BUSY_FLAG ==
|
while (ESP_ROM_SPIFLASH_BUSY_FLAG ==
|
||||||
(status_value & 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_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);
|
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)
|
static inline bool host_idle(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_SOC_ESP32)
|
||||||
bool idle = spi_flash_ll_host_idle(hw);
|
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;
|
return idle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
chosen {
|
chosen {
|
||||||
zephyr,entropy = &trng0;
|
zephyr,entropy = &trng0;
|
||||||
|
zephyr,flash-controller = &flash;
|
||||||
};
|
};
|
||||||
|
|
||||||
cpus {
|
cpus {
|
||||||
|
@ -64,6 +65,23 @@
|
||||||
status = "ok";
|
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 {
|
uart0: uart@3f400000 {
|
||||||
compatible = "espressif,esp32-uart";
|
compatible = "espressif,esp32-uart";
|
||||||
reg = <0x3f400000 0x400>;
|
reg = <0x3f400000 0x400>;
|
||||||
|
|
|
@ -220,6 +220,7 @@ _net_buf_pool_list = _esp_net_buf_pool_list;
|
||||||
*libzephyr.a:log_core.*(.rodata .rodata.*)
|
*libzephyr.a:log_core.*(.rodata .rodata.*)
|
||||||
*libzephyr.a:log_backend_uart.*(.rodata .rodata.*)
|
*libzephyr.a:log_backend_uart.*(.rodata .rodata.*)
|
||||||
*libzephyr.a:log_output.*(.rodata .rodata.*)
|
*libzephyr.a:log_output.*(.rodata .rodata.*)
|
||||||
|
*libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*)
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
__esp_log_const_start = .;
|
__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:rtc_*.*(.literal .text .literal.* .text.*)
|
||||||
*libsoc.a:cpu_util.*(.literal .text .literal.* .text.*)
|
*libsoc.a:cpu_util.*(.literal .text .literal.* .text.*)
|
||||||
*libgcc.a:lib2funcs.*(.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:windowspill_asm.*(.literal .text .literal.* .text.*)
|
||||||
*libzephyr.a:log_noos.*(.literal .text .literal.* .text.*)
|
*libzephyr.a:log_noos.*(.literal .text .literal.* .text.*)
|
||||||
*libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*)
|
*libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "esp_private/system_internal.h"
|
#include "esp_private/system_internal.h"
|
||||||
#include "esp32s2/rom/cache.h"
|
#include "esp32s2/rom/cache.h"
|
||||||
#include "soc/gpio_periph.h"
|
#include "soc/gpio_periph.h"
|
||||||
|
#include "esp_spi_flash.h"
|
||||||
#include "hal/cpu_ll.h"
|
#include "hal/cpu_ll.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "sys/printk.h"
|
#include "sys/printk.h"
|
||||||
|
@ -118,6 +119,9 @@ void __attribute__((section(".iram1"))) __start(void)
|
||||||
*wdt_rtc_protect = 0;
|
*wdt_rtc_protect = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_SOC_FLASH_ESP32
|
||||||
|
spi_flash_guard_set(&g_flash_guard_default_ops);
|
||||||
|
#endif
|
||||||
esp_intr_initialize();
|
esp_intr_initialize();
|
||||||
/* Start Zephyr */
|
/* Start Zephyr */
|
||||||
z_cstart();
|
z_cstart();
|
||||||
|
|
|
@ -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);
|
cache_line_size_t cache_line_size);
|
||||||
|
|
||||||
extern void esp_rom_Cache_Invalidate_ICache_All(void);
|
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;
|
extern uint32_t esp_rom_g_ticks_per_us_pro;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue