soc: riscv: esp32c3: drivers: flash: add support

to host SPI Flash driver.

Signed-off-by: Glauber Maroto Ferreira <glauber.ferreira@espressif.com>
This commit is contained in:
Glauber Maroto Ferreira 2021-10-08 12:44:01 -03:00 committed by Christopher Friedt
commit 1af506dd32
8 changed files with 76 additions and 15 deletions

View file

@ -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;
}; };
aliases { aliases {

View file

@ -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 || SOC_ESP32S2 depends on SOC_ESP32 || SOC_ESP32S2 || SOC_ESP32C3
help help
Enable ESP32 internal flash driver. Enable ESP32 internal flash driver.

View file

@ -10,6 +10,17 @@
#define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size) #define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size)
#define FLASH_ERASE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) #define FLASH_ERASE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)
/*
* HAL includes go first to
* avoid BIT macro redefinition
*/
#include <esp_spi_flash.h>
#include <hal/spi_ll.h>
#include <hal/spi_flash_ll.h>
#include <hal/spi_flash_hal.h>
#include <soc/spi_struct.h>
#include <spi_flash_defs.h>
#include <kernel.h> #include <kernel.h>
#include <device.h> #include <device.h>
#include <stddef.h> #include <stddef.h>
@ -17,12 +28,6 @@
#include <errno.h> #include <errno.h>
#include <drivers/flash.h> #include <drivers/flash.h>
#include <soc.h> #include <soc.h>
#include <esp_spi_flash.h>
#include <hal/spi_ll.h>
#include <hal/spi_flash_ll.h>
#include <hal/spi_flash_hal.h>
#include <soc/spi_struct.h>
#include <spi_flash_defs.h>
#if defined(CONFIG_SOC_ESP32) #if defined(CONFIG_SOC_ESP32)
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
@ -33,6 +38,13 @@
#include "soc/spi_mem_reg.h" #include "soc/spi_mem_reg.h"
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
#include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/spi_flash.h"
#elif defined(CONFIG_SOC_ESP32C3)
#include "soc/spi_periph.h"
#include "soc/spi_mem_reg.h"
#include "soc/dport_access.h"
#include "esp32c3/dport_access.h"
#include "esp32c3/rom/cache.h"
#include "esp32c3/rom/spi_flash.h"
#endif #endif
#include "soc/mmu.h" #include "soc/mmu.h"
@ -56,7 +68,15 @@ static const struct flash_parameters flash_esp32_parameters = {
#define DEV_DATA(dev) ((struct flash_esp32_dev_data *const)(dev)->data) #define DEV_DATA(dev) ((struct flash_esp32_dev_data *const)(dev)->data)
#define DEV_CFG(dev) ((const struct flash_esp32_dev_config *const)(dev)->config) #define DEV_CFG(dev) ((const struct flash_esp32_dev_config *const)(dev)->config)
#if !defined(CONFIG_SOC_ESP32C3)
#define SPI1_EXTRA_DUMMIES (g_rom_spiflash_dummy_len_plus[1]) #define SPI1_EXTRA_DUMMIES (g_rom_spiflash_dummy_len_plus[1])
#else
#define SPI1_EXTRA_DUMMIES ((uint8_t)((rom_spiflash_legacy_data->dummy_len_plus)[1]))
#define SPI_FREAD_QIO 0
#define SPI_FREAD_DIO 0
#endif
#define MAX_BUFF_ALLOC_RETRIES 5 #define MAX_BUFF_ALLOC_RETRIES 5
#define MAX_READ_CHUNK 16384 #define MAX_READ_CHUNK 16384
#define MAX_WRITE_CHUNK 8192 #define MAX_WRITE_CHUNK 8192
@ -67,12 +87,17 @@ static const struct flash_parameters flash_esp32_parameters = {
#define HOST_FLASH_CONTROLLER SPI0 #define HOST_FLASH_CONTROLLER SPI0
#define HOST_FLASH_RDSR SPI_FLASH_RDSR #define HOST_FLASH_RDSR SPI_FLASH_RDSR
#define HOST_FLASH_FASTRD SPI_FASTRD_MODE #define HOST_FLASH_FASTRD SPI_FASTRD_MODE
#elif defined(CONFIG_SOC_ESP32S2) #elif defined(CONFIG_SOC_ESP32S2) || defined(CONFIG_SOC_ESP32C3)
#define HOST_FLASH_CONTROLLER SPIMEM0 #define HOST_FLASH_CONTROLLER SPIMEM0
#define HOST_FLASH_RDSR SPI_MEM_FLASH_RDSR #define HOST_FLASH_RDSR SPI_MEM_FLASH_RDSR
#define HOST_FLASH_FASTRD SPI_MEM_FASTRD_MODE #define HOST_FLASH_FASTRD SPI_MEM_FASTRD_MODE
#endif #endif
#if defined(CONFIG_SOC_ESP32C3)
static esp_rom_spiflash_chip_t esp_flashchip_info;
#else
#define esp_flashchip_info g_rom_flashchip
#endif
static inline void flash_esp32_sem_take(const struct device *dev) static inline void flash_esp32_sem_take(const struct device *dev)
{ {
@ -307,7 +332,7 @@ 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) #if defined(CONFIG_SOC_ESP32S2) || defined(CONFIG_SOC_ESP32C3)
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CTRL, 0); WRITE_PERI_REG(PERIPHS_SPI_FLASH_CTRL, 0);
#endif #endif
@ -426,7 +451,7 @@ static inline bool host_idle(spi_dev_t *hw)
bool idle = spi_flash_ll_host_idle(hw); bool idle = spi_flash_ll_host_idle(hw);
idle &= spi_flash_ll_host_idle(&HOST_FLASH_CONTROLLER); idle &= spi_flash_ll_host_idle(&HOST_FLASH_CONTROLLER);
#elif defined(CONFIG_SOC_ESP32S2) #elif defined(CONFIG_SOC_ESP32S2) || defined(CONFIG_SOC_ESP32C3)
bool idle = spimem_flash_ll_host_idle((spi_mem_dev_t *)hw); bool idle = spimem_flash_ll_host_idle((spi_mem_dev_t *)hw);
idle &= spimem_flash_ll_host_idle(&HOST_FLASH_CONTROLLER); idle &= spimem_flash_ll_host_idle(&HOST_FLASH_CONTROLLER);
@ -458,7 +483,6 @@ static int wait_idle(const struct device *dev)
static int write_protect(const struct device *dev, bool write_protect) static int write_protect(const struct device *dev, bool write_protect)
{ {
const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev);
uint32_t flash_status = 0;
wait_idle(dev); wait_idle(dev);
@ -470,12 +494,14 @@ static int write_protect(const struct device *dev, bool write_protect)
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }
#if !defined(CONFIG_SOC_ESP32C3)
uint32_t flash_status = 0;
/* make sure the flash is ready for writing */ /* make sure the flash is ready for writing */
while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) { while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) {
read_status(dev, &flash_status); read_status(dev, &flash_status);
} }
#endif
return 0; return 0;
} }
@ -670,7 +696,6 @@ out:
guard->start(); guard->start();
flash_esp32_flush_cache(address, length); flash_esp32_flush_cache(address, length);
guard->end(); guard->end();
flash_esp32_sem_give(dev); flash_esp32_sem_give(dev);
return rc; return rc;
@ -777,6 +802,14 @@ static int flash_esp32_init(const struct device *dev)
{ {
struct flash_esp32_dev_data *const dev_data = DEV_DATA(dev); struct flash_esp32_dev_data *const dev_data = DEV_DATA(dev);
#if defined(CONFIG_SOC_ESP32C3)
spiflash_legacy_data_t *legacy_data = rom_spiflash_legacy_data;
esp_flashchip_info.chip_size = legacy_data->chip.chip_size;
esp_flashchip_info.sector_size = legacy_data->chip.sector_size;
esp_flashchip_info.page_size = legacy_data->chip.page_size;
#endif
k_sem_init(&dev_data->sem, 1, 1); k_sem_init(&dev_data->sem, 1, 1);
return 0; return 0;
@ -796,7 +829,7 @@ static struct flash_esp32_dev_data flash_esp32_data;
static const struct flash_esp32_dev_config flash_esp32_config = { static const struct flash_esp32_dev_config flash_esp32_config = {
.controller = (spi_dev_t *) DT_INST_REG_ADDR(0), .controller = (spi_dev_t *) DT_INST_REG_ADDR(0),
.chip = &g_rom_flashchip .chip = &esp_flashchip_info
}; };
DEVICE_DT_INST_DEFINE(0, flash_esp32_init, DEVICE_DT_INST_DEFINE(0, flash_esp32_init,

View file

@ -13,6 +13,7 @@
#size-cells = <1>; #size-cells = <1>;
chosen { chosen {
zephyr,entropy = &trng0; zephyr,entropy = &trng0;
zephyr,flash-controller = &flash;
}; };
cpus { cpus {
@ -70,6 +71,23 @@
status = "ok"; status = "ok";
}; };
flash: flash-controller@60002000 {
compatible = "espressif,esp32-flash-controller";
label = "FLASH_CTRL";
reg = <0x60002000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
flash0: flash@0 {
compatible = "soc-nv-flash";
label = "FLASH_ESP32C3";
reg = <0 0x400000>;
erase-block-size = <4096>;
write-block-size = <4>;
};
};
gpio0: gpio@60004000 { gpio0: gpio@60004000 {
compatible = "espressif,esp32-gpio"; compatible = "espressif,esp32-gpio";
gpio-controller; gpio-controller;

View file

@ -118,6 +118,7 @@ SECTIONS
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
*libkernel.a:(.literal .text .literal.* .text.*) *libkernel.a:(.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:log_noos.*(.literal .text .literal.* .text.*) *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*)
*libdrivers__timer.a:esp32c3_sys_timer.*(.literal .text .literal.* .text.*) *libdrivers__timer.a:esp32c3_sys_timer.*(.literal .text .literal.* .text.*)
*libzephyr.a:log_core.*(.literal .text .literal.* .text.*) *libzephyr.a:log_core.*(.literal .text .literal.* .text.*)
@ -175,6 +176,7 @@ SECTIONS
*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 = .;
KEEP(*(SORT(.log_const_*))); KEEP(*(SORT(.log_const_*)));

View file

@ -97,6 +97,10 @@ void __attribute__((section(".iram1"))) __start(void)
REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN); REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN);
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
#if CONFIG_SOC_FLASH_ESP32
spi_flash_guard_set(&g_flash_guard_default_ops);
#endif
/*Initialize the esp32c3 interrupt controller */ /*Initialize the esp32c3 interrupt controller */
esp_intr_initialize(); esp_intr_initialize();

View file

@ -43,6 +43,9 @@ extern STATUS esp_rom_uart_rx_one_char(uint8_t *chr);
extern void esp_rom_ets_set_user_start(uint32_t start); extern void esp_rom_ets_set_user_start(uint32_t start);
extern void esprv_intc_int_set_threshold(int priority_threshold); extern void esprv_intc_int_set_threshold(int priority_threshold);
uint32_t soc_intr_get_next_source(void); uint32_t soc_intr_get_next_source(void);
extern void esp_rom_Cache_Resume_ICache(uint32_t autoload);
extern int esp_rom_Cache_Invalidate_Addr(uint32_t addr, uint32_t size);
extern spiflash_legacy_data_t esp_rom_spiflash_legacy_data;
#endif /* _ASMLANGUAGE */ #endif /* _ASMLANGUAGE */

View file

@ -67,7 +67,7 @@ manifest:
groups: groups:
- hal - hal
- name: hal_espressif - name: hal_espressif
revision: a360365cb7858826809c82e375524ee5faf497ac revision: 7c46a3fc5b336199392cba0f66c3c27d5fe9025c
path: modules/hal/espressif path: modules/hal/espressif
west-commands: west/west-commands.yml west-commands: west/west-commands.yml
groups: groups: