arch/xtensa/esp32s3: Fix bug regarding SPI flash operation mode

SPI flash operation modes - Dual Output (dout), Dual I/O (dio),
Quad Output (qout), Quad I/O (qio) and Octal (opi) were not being
properly selected. This commit fixes this behavior and the device
is now able to boot and initialize the proper SPI flash mode.

Signed-off-by: Tiago Medicci Serrano <tiago.medicci@espressif.com>
This commit is contained in:
Tiago Medicci Serrano 2025-02-26 14:12:43 -03:00 committed by Xiang Xiao
parent b81c4d3aa6
commit 622355b5c3
9 changed files with 253 additions and 120 deletions

View file

@ -1789,6 +1789,7 @@ config ESP32S3_FLASH_MODE_QOUT
bool "Quad Output (QOUT)" bool "Quad Output (QOUT)"
config ESP32S3_FLASH_MODE_OCT config ESP32S3_FLASH_MODE_OCT
select ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
bool "Octal" bool "Octal"
endchoice # ESP32S3_FLASH_MODE endchoice # ESP32S3_FLASH_MODE

View file

@ -225,7 +225,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = 5d4868f08b94efbe76383382f7a843c6cdeaf811 ESP_HAL_3RDPARTY_VERSION = 0b15e1a642d7005ad11c3c0394c784959f478f5f
endif endif
ifndef ESP_HAL_3RDPARTY_URL ifndef ESP_HAL_3RDPARTY_URL

View file

@ -586,72 +586,6 @@ static void IRAM_ATTR config_psram_spi_phases(void)
cache_resume_dcache(0); cache_resume_dcache(0);
} }
/****************************************************************************
* Name: spi_flash_set_rom_required_regs
*
* Description:
* Set flash ROM required register.
*
* Input Parameters:
* None
*
* Returned Value:
* None.
*
****************************************************************************/
void IRAM_ATTR spi_flash_set_rom_required_regs(void)
{
#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT
/* Disable the variable dummy mode when doing timing tuning.
* STR /DTR mode setting is done every time when
* "esp_rom_opiflash_exec_cmd" is called.
* Add any registers that are not set in ROM SPI flash functions here
* in the future.
*/
CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY);
#endif
}
/****************************************************************************
* Name: flash_set_vendor_required_regs
*
* Description:
* Set flash vendor required register.
*
* Input Parameters:
* None
*
* Returned Value:
* None.
*
****************************************************************************/
static inline void flash_set_vendor_required_regs(void)
{
#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT
/* Set MSPI specifical configuration,
* "esp32s3_bsp_opiflash_set_required_regs" is board defined function.
*/
esp32s3_bsp_opiflash_set_required_regs();
SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1),
SPI_MEM_CACHE_USR_CMD_4BYTE_V,
1,
SPI_MEM_CACHE_USR_CMD_4BYTE_S);
#else
/* Restore MSPI registers after Octal PSRAM initialization. */
SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1),
SPI_MEM_CACHE_USR_CMD_4BYTE_V,
0,
SPI_MEM_CACHE_USR_CMD_4BYTE_S);
#endif
}
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -722,7 +656,7 @@ int IRAM_ATTR psram_enable(int mode, int vaddrmode)
/* Flash chip requires MSPI specifically, call this function to set them */ /* Flash chip requires MSPI specifically, call this function to set them */
flash_set_vendor_required_regs(); spi_flash_set_vendor_required_regs();
config_psram_spi_phases(); config_psram_spi_phases();

View file

@ -37,6 +37,7 @@
#include <nuttx/init.h> #include <nuttx/init.h>
#include <nuttx/kthread.h> #include <nuttx/kthread.h>
#include <nuttx/signal.h> #include <nuttx/signal.h>
#include <nuttx/kmalloc.h>
#include "sched/sched.h" #include "sched/sched.h"
@ -48,6 +49,7 @@
#include "esp32s3_irq.h" #include "esp32s3_irq.h"
#include "esp32s3_spiflash.h" #include "esp32s3_spiflash.h"
#include "spi_flash_defs.h"
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
#include "soc/extmem_reg.h" #include "soc/extmem_reg.h"
#include "soc/spi_mem_reg.h" #include "soc/spi_mem_reg.h"
@ -121,27 +123,90 @@
# define FLASH_SR1_BUSY ESP_ROM_SPIFLASH_BUSY_FLAG # define FLASH_SR1_BUSY ESP_ROM_SPIFLASH_BUSY_FLAG
# define FLASH_SR1_WREN ESP_ROM_SPIFLASH_WRENABLE_FLAG # define FLASH_SR1_WREN ESP_ROM_SPIFLASH_WRENABLE_FLAG
#define SPI_FLASH_DIO_ADDR_BITLEN 24
#define SPI_FLASH_DIO_DUMMY_BITLEN 4
#define SPI_FLASH_QIO_ADDR_BITLEN 24
#define SPI_FLASH_QIO_DUMMY_BITLEN 6
#define SPI_FLASH_QOUT_ADDR_BITLEN 24
#define SPI_FLASH_QOUT_DUMMY_BITLEN 8
#define SPI_FLASH_DOUT_ADDR_BITLEN 24
#define SPI_FLASH_DOUT_DUMMY_BITLEN 8
#define SPI_FLASH_FASTRD_ADDR_BITLEN 24
#define SPI_FLASH_FASTRD_DUMMY_BITLEN 8
#define SPI_FLASH_SLOWRD_ADDR_BITLEN 24
#define SPI_FLASH_SLOWRD_DUMMY_BITLEN 0
#define SPI_FLASH_OPISTR_ADDR_BITLEN 32
#define SPI_FLASH_OPISTR_DUMMY_BITLEN 20
#define SPI_FLASH_OPIDTR_ADDR_BITLEN 32
#define SPI_FLASH_OPIDTR_DUMMY_BITLEN 40
#define SPI_FLASH_QIO_HPM_DUMMY_BITLEN 10
#define SPI_FLASH_DIO_HPM_DUMMY_BITLEN 8
/* SPI flash operation */ /* SPI flash operation */
# ifdef CONFIG_ESP32S3_SPI_FLASH_USE_32BIT_ADDRESS #ifndef CONFIG_ESP32S3_FLASH_MODE_OCT
# define ADDR_BITS(addr) (((addr) & 0xff000000) ? 32 : 24) # define CMD_OPI_FLASH_MXIC(cmd) (cmd)
# define CMD_BITLEN(cmd) (8)
# ifdef CONFIG_ESP32S3_FLASH_MODE_QIO
# define READ_DUMMY(addr) SPI_FLASH_QIO_DUMMY_BITLEN
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_FASTRD_QIO_4B : \
CMD_FASTRD_QIO)
# elif CONFIG_ESP32S3_FLASH_MODE_QOUT
# define READ_DUMMY(addr) SPI_FLASH_QOUT_DUMMY_BITLEN
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_FASTRD_QUAD_4B : \
CMD_FASTRD_QUAD)
# elif CONFIG_ESP32S3_FLASH_MODE_DIO
# define READ_DUMMY(addr) SPI_FLASH_DIO_DUMMY_BITLEN
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_FASTRD_DIO_4B : \
CMD_FASTRD_DIO)
# elif CONFIG_ESP32S3_FLASH_MODE_DOUT
# define READ_DUMMY(addr) SPI_FLASH_DOUT_DUMMY_BITLEN
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_FASTRD_DUAL_4B : \
CMD_FASTRD_DUAL)
# else /* SPI_FLASH_FASTRD */
# define READ_DUMMY(addr) SPI_FLASH_FASTRD_DUMMY_BITLEN
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_FSTRD4B : \ # define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_FSTRD4B : \
FLASH_CMD_FSTRD) FLASH_CMD_FSTRD)
# endif
# ifdef CONFIG_ESP32S3_SPI_FLASH_USE_32BIT_ADDRESS
# define ADDR_BITS(addr) (((addr) & 0xff000000) ? 32 : 24)
# define WRITE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_PP4B : \ # define WRITE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_PP4B : \
FLASH_CMD_PP) FLASH_CMD_PP)
# define ERASE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_SE4B : \ # define ERASE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_SE4B : \
FLASH_CMD_SE) FLASH_CMD_SE)
# define READ_DUMMY(addr) (8)
# else # else
# define ADDR_BITS(addr) 24 # define ADDR_BITS(addr) 24
# define READ_CMD(addr) FLASH_CMD_FSTRD
# define WRITE_CMD(addr) FLASH_CMD_PP # define WRITE_CMD(addr) FLASH_CMD_PP
# define ERASE_CMD(addr) FLASH_CMD_SE # define ERASE_CMD(addr) FLASH_CMD_SE
# define READ_DUMMY(addr) (8)
# endif # endif
# define READ_REG_DUMMY(addr) (0)
#else /* CONFIG_ESP32S3_FLASH_MODE_OCT */
# define CMD_OPI_FLASH_MXIC(cmd) ((((~(cmd) & 0xff) << 8)) | ((cmd) & 0xff))
# define CMD_OPI_FLASH_MXIC_CHIP_ERASE 0x9F60
# define CMD_OPI_FLASH_MXIC_READ_STR 0x13EC
# define CMD_OPI_FLASH_MXIC_READ_DTR 0x11EE
# define CMD_OPI_FLASH_MXIC_RDCR2 0x8E71
# define CMD_OPI_FLASH_MXIC_WRCR2 0x8D72
# define CMD_BITLEN(cmd) (cmd >= 0x100 ? 16 : 8)
# define ADDR_BITS(addr) (32)
# ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR
# define READ_CMD(addr) CMD_OPI_FLASH_MXIC_READ_STR
# else
# define READ_CMD(addr) CMD_OPI_FLASH_MXIC_READ_DTR
# endif
# define WRITE_CMD(addr) CMD_OPI_FLASH_MXIC(FLASH_CMD_PP4B)
# define ERASE_CMD(addr) CMD_OPI_FLASH_MXIC(FLASH_CMD_SE4B)
# ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR
# define READ_DUMMY(addr) SPI_FLASH_OPISTR_DUMMY_BITLEN
# define READ_REG_DUMMY(addr) 4
# else /* CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR */
# define READ_DUMMY(addr) CMD_OPI_FLASH_MXIC_READ_DTR
# define READ_REG_DUMMY(addr) 8
# endif
#endif /* !CONFIG_ESP32S3_FLASH_MODE_OCT*/
# define SEND_CMD8_TO_FLASH(cmd) \ # define SEND_CMD8_TO_FLASH(cmd) \
esp32s3_spi_trans((cmd), 8, \ esp32s3_spi_trans((cmd), CMD_BITLEN(cmd), \
0, 0, \ 0, 0, \
NULL, 0, \ NULL, 0, \
NULL, 0, \ NULL, 0, \
@ -149,15 +214,16 @@
false) false)
# define READ_SR1_FROM_FLASH(cmd, status) \ # define READ_SR1_FROM_FLASH(cmd, status) \
esp32s3_spi_trans((cmd), 8, \ esp32s3_spi_trans((cmd), CMD_BITLEN(cmd), \
0, 0, \ 0, ADDR_BITS(0), \
NULL, 0, \ NULL, 0, \
(status), 1, \ (status), 1, \
0, \ READ_REG_DUMMY(0), \
false) false)
# define ERASE_FLASH_SECTOR(addr) \ # define ERASE_FLASH_SECTOR(addr) \
esp32s3_spi_trans(ERASE_CMD(addr), 8, \ esp32s3_spi_trans(ERASE_CMD(addr), \
CMD_BITLEN(ERASE_CMD(addr)), \
(addr), ADDR_BITS(addr), \ (addr), ADDR_BITS(addr), \
NULL, 0, \ NULL, 0, \
NULL, 0, \ NULL, 0, \
@ -165,7 +231,8 @@
true) true)
# define WRITE_DATA_TO_FLASH(addr, buffer, size) \ # define WRITE_DATA_TO_FLASH(addr, buffer, size) \
esp32s3_spi_trans(WRITE_CMD(addr), 8, \ esp32s3_spi_trans(WRITE_CMD(addr), \
CMD_BITLEN(WRITE_CMD(addr)), \
(addr), ADDR_BITS(addr), \ (addr), ADDR_BITS(addr), \
buffer, size, \ buffer, size, \
NULL, 0, \ NULL, 0, \
@ -173,7 +240,8 @@
true) true)
# define READ_DATA_FROM_FLASH(addr, buffer, size) \ # define READ_DATA_FROM_FLASH(addr, buffer, size) \
esp32s3_spi_trans(READ_CMD(addr), 8, \ esp32s3_spi_trans(READ_CMD(addr), \
CMD_BITLEN(READ_CMD(addr)), \
(addr), ADDR_BITS(addr), \ (addr), ADDR_BITS(addr), \
NULL, 0, \ NULL, 0, \
buffer, size, \ buffer, size, \
@ -206,6 +274,12 @@ extern void cache_resume_dcache(uint32_t val);
extern int cache_invalidate_addr(uint32_t addr, uint32_t size); extern int cache_invalidate_addr(uint32_t addr, uint32_t size);
extern void cache_invalidate_icache_all(void); extern void cache_invalidate_icache_all(void);
#ifndef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
extern void spi_flash_mmap_os_func_set(void *(*func1)(size_t size),
void (*func2)(void *p));
extern esp_err_t spi_flash_mmap_page_num_init(uint32_t page_num);
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -223,6 +297,7 @@ static volatile bool g_flash_op_can_start = false;
static volatile bool g_flash_op_complete = false; static volatile bool g_flash_op_complete = false;
static volatile bool g_spi_flash_cache_suspended = false; static volatile bool g_spi_flash_cache_suspended = false;
static volatile bool g_sched_suspended[CONFIG_SMP_NCPUS]; static volatile bool g_sched_suspended[CONFIG_SMP_NCPUS];
static volatile bool g_flash_chip_busy = false;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static sem_t g_disable_non_iram_isr_on_core[CONFIG_SMP_NCPUS]; static sem_t g_disable_non_iram_isr_on_core[CONFIG_SMP_NCPUS];
#endif #endif
@ -402,8 +477,8 @@ static void esp32s3_spi_trans(uint32_t command,
/* Initiliaze SPI user register */ /* Initiliaze SPI user register */
user_reg &= ~(SPI_MEM_USR_ADDR_M | SPI_MEM_USR_DUMMY_M | user_reg &= ~(SPI_MEM_USR_DUMMY_M | SPI_MEM_USR_MOSI_M |
SPI_MEM_USR_MOSI_M | SPI_MEM_USR_MISO_M); SPI_MEM_USR_MISO_M | SPI_MEM_USR_ADDR_M);
user_reg |= SPI_MEM_USR_COMMAND_M; user_reg |= SPI_MEM_USR_COMMAND_M;
/* Wait until SPI is idle */ /* Wait until SPI is idle */
@ -424,15 +499,11 @@ static void esp32s3_spi_trans(uint32_t command,
/* Set address bits and value */ /* Set address bits and value */
if (address_bits)
{
user1_reg &= ~SPI_MEM_USR_ADDR_BITLEN_M; user1_reg &= ~SPI_MEM_USR_ADDR_BITLEN_M;
user1_reg |= (address_bits - 1) << SPI_MEM_USR_ADDR_BITLEN_S; user1_reg |= (address_bits - 1) << SPI_MEM_USR_ADDR_BITLEN_S;
putreg32(address, SPI_MEM_ADDR_REG(SPI_PORT)); putreg32(address, SPI_MEM_ADDR_REG(SPI_PORT));
user_reg |= SPI_MEM_USR_ADDR_M;
regval = getreg32(SPI_MEM_CACHE_FCTRL_REG(SPI_PORT)); regval = getreg32(SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
if (address_bits > 24) if (address_bits > 24)
{ {
@ -443,17 +514,25 @@ static void esp32s3_spi_trans(uint32_t command,
regval &= ~SPI_MEM_CACHE_USR_CMD_4BYTE_M; regval &= ~SPI_MEM_CACHE_USR_CMD_4BYTE_M;
} }
putreg32(regval, SPI_MEM_CACHE_FCTRL_REG(SPI_PORT)); if (address_bits)
{
user_reg |= SPI_MEM_USR_ADDR_M;
} }
putreg32(regval, SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
/* Set dummy */ /* Set dummy */
user1_reg &= ~SPI_MEM_USR_DUMMY_CYCLELEN_M;
if (dummy_bits) if (dummy_bits)
{ {
user1_reg &= ~SPI_MEM_USR_DUMMY_CYCLELEN_M;
user1_reg |= (dummy_bits - 1) << SPI_MEM_USR_DUMMY_CYCLELEN_S;
user_reg |= SPI_MEM_USR_DUMMY_M; user_reg |= SPI_MEM_USR_DUMMY_M;
user1_reg |= (dummy_bits - 1) << SPI_MEM_USR_DUMMY_CYCLELEN_S;
}
else
{
user1_reg |= SPI_MEM_USR_DUMMY_CYCLELEN_M;
} }
/* Set TX data */ /* Set TX data */
@ -474,9 +553,12 @@ static void esp32s3_spi_trans(uint32_t command,
if (rx_bytes) if (rx_bytes)
{ {
putreg32(rx_bytes * 8 - 1, SPI_MEM_MISO_DLEN_REG(SPI_PORT)); putreg32(rx_bytes * 8 - 1, SPI_MEM_MISO_DLEN_REG(SPI_PORT));
user_reg |= SPI_MEM_USR_MISO_M; user_reg |= SPI_MEM_USR_MISO_M;
} }
else
{
putreg32(0, SPI_MEM_MISO_DLEN_REG(SPI_PORT));
}
putreg32(user_reg, SPI_MEM_USER_REG(SPI_PORT)); putreg32(user_reg, SPI_MEM_USER_REG(SPI_PORT));
putreg32(user1_reg, SPI_MEM_USER1_REG(SPI_PORT)); putreg32(user1_reg, SPI_MEM_USER1_REG(SPI_PORT));
@ -490,15 +572,54 @@ static void esp32s3_spi_trans(uint32_t command,
SPI_MEM_FCMD_DUAL_M | SPI_MEM_FADDR_OCT_M | SPI_MEM_FCMD_DUAL_M | SPI_MEM_FADDR_OCT_M |
SPI_MEM_FDIN_OCT_M | SPI_MEM_FDOUT_OCT_M | SPI_MEM_FDIN_OCT_M | SPI_MEM_FDOUT_OCT_M |
SPI_MEM_FDUMMY_OUT_M | SPI_MEM_RESANDRES_M | SPI_MEM_FDUMMY_OUT_M | SPI_MEM_RESANDRES_M |
SPI_MEM_WP_REG_M | SPI_MEM_WRSR_2B_M); SPI_MEM_WP_REG_M | SPI_MEM_WRSR_2B_M |
SPI_MEM_FASTRD_MODE_M);
regval |= (SPI_MEM_Q_POL_M | SPI_MEM_D_POL_M);
#ifdef CONFIG_ESP32S3_FLASH_MODE_QIO
if (command == READ_CMD(address))
{
regval |= SPI_MEM_FREAD_QIO_M;
regval |= SPI_MEM_FASTRD_MODE_M; regval |= SPI_MEM_FASTRD_MODE_M;
regval |= SPI_MEM_FDUMMY_OUT_M;
}
#elif CONFIG_ESP32S3_FLASH_MODE_QOUT
if (command == READ_CMD(address))
{
regval |= SPI_MEM_FREAD_QUAD_M;
regval |= SPI_MEM_FASTRD_MODE_M;
}
#elif CONFIG_ESP32S3_FLASH_MODE_DIO
if (command == READ_CMD(address))
{
regval |= SPI_MEM_FREAD_DIO_M;
regval |= SPI_MEM_FASTRD_MODE_M;
regval |= SPI_MEM_FDUMMY_OUT_M;
}
#elif CONFIG_ESP32S3_FLASH_MODE_DOUT
if (command == READ_CMD(address))
{
regval |= SPI_MEM_FREAD_DUAL_M;
regval |= SPI_MEM_FASTRD_MODE_M;
}
#elif CONFIG_ESP32S3_FLASH_MODE_OCT
regval |= SPI_MEM_FASTRD_MODE_M;
# ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR
regval |= (SPI_MEM_FADDR_OCT_M | SPI_MEM_FCMD_OCT_M |
SPI_MEM_FDIN_OCT_M | SPI_MEM_FDOUT_OCT_M);
# elif CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR
# error "Not yet implemented"
# endif
#else /* SPI_FLASH_FASTRD */
if (command == READ_CMD(address))
{
regval |= SPI_MEM_FASTRD_MODE_M;
}
#endif
putreg32(regval, SPI_MEM_CTRL_REG(SPI_PORT)); putreg32(regval, SPI_MEM_CTRL_REG(SPI_PORT));
/* Set clock and delay */ /* Set clock and delay */
regval = SPI_MEM_FLASH_PES_WAIT_EN_M |
SPI_MEM_FLASH_PER_WAIT_EN_M;
putreg32(regval, SPI_MEM_FLASH_SUS_CMD_REG(SPI_PORT));
putreg32(0, SPI_MEM_CLOCK_GATE_REG(SPI_PORT)); putreg32(0, SPI_MEM_CLOCK_GATE_REG(SPI_PORT));
/* Set if this is program or erase operation */ /* Set if this is program or erase operation */
@ -548,9 +669,21 @@ static void wait_flash_idle(void)
do do
{ {
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status); READ_SR1_FROM_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_RDSR), &status);
if ((status & FLASH_SR1_BUSY) == 0) if ((status & FLASH_SR1_BUSY) == 0)
{ {
if (g_flash_chip_busy == true)
{
g_flash_chip_busy = 0;
if ((status & FLASH_SR1_WREN) != 0)
{
/* The previous command is not accepted, leaving the WEL
* bit still set.
*/
return;
}
}
break; break;
} }
} }
@ -574,8 +707,8 @@ static void enable_flash_write(void)
do do
{ {
SEND_CMD8_TO_FLASH(FLASH_CMD_WREN); SEND_CMD8_TO_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_WREN));
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status); READ_SR1_FROM_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_RDSR), &status);
if ((status & FLASH_SR1_WREN) != 0) if ((status & FLASH_SR1_WREN) != 0)
{ {
break; break;
@ -601,8 +734,8 @@ static void disable_flash_write(void)
do do
{ {
SEND_CMD8_TO_FLASH(FLASH_CMD_WRDI); SEND_CMD8_TO_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_WRDI));
READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status); READ_SR1_FROM_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_RDSR), &status);
if ((status & FLASH_SR1_WREN) == 0) if ((status & FLASH_SR1_WREN) == 0)
{ {
break; break;
@ -1103,6 +1236,7 @@ int spi_flash_erase_sector(uint32_t sector)
enable_flash_write(); enable_flash_write();
ERASE_FLASH_SECTOR(addr); ERASE_FLASH_SECTOR(addr);
g_flash_chip_busy = true;
wait_flash_idle(); wait_flash_idle();
disable_flash_write(); disable_flash_write();
@ -1144,8 +1278,10 @@ int spi_flash_erase_range(uint32_t start_address, uint32_t size)
spiflash_start(); spiflash_start();
wait_flash_idle(); wait_flash_idle();
enable_flash_write(); enable_flash_write();
wait_flash_idle();
ERASE_FLASH_SECTOR(addr); ERASE_FLASH_SECTOR(addr);
g_flash_chip_busy = true;
addr += FLASH_SECTOR_SIZE; addr += FLASH_SECTOR_SIZE;
wait_flash_idle(); wait_flash_idle();
disable_flash_write(); disable_flash_write();
@ -1219,6 +1355,7 @@ int spi_flash_write(uint32_t dest_addr, const void *buffer, uint32_t size)
enable_flash_write(); enable_flash_write();
WRITE_DATA_TO_FLASH(tx_addr, spi_buffer, n); WRITE_DATA_TO_FLASH(tx_addr, spi_buffer, n);
g_flash_chip_busy = true;
tx_bytes -= n; tx_bytes -= n;
tx_buf += n; tx_buf += n;
@ -1341,6 +1478,14 @@ int esp32s3_spiflash_init(void)
spi_flash_guard_set(&g_spi_flash_guard_funcs); spi_flash_guard_set(&g_spi_flash_guard_funcs);
#ifndef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
/* These two functions are in ROM only */
spi_flash_mmap_os_func_set(malloc, free);
spi_flash_mmap_page_num_init(128);
#endif
return ret; return ret;
} }

View file

@ -57,6 +57,7 @@
#include "hal/cache_types.h" #include "hal/cache_types.h"
#include "hal/cache_ll.h" #include "hal/cache_ll.h"
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
#include "hal/efuse_ll.h"
#include "soc/extmem_reg.h" #include "soc/extmem_reg.h"
#include "rom/cache.h" #include "rom/cache.h"
#include "spi_flash_mmap.h" #include "spi_flash_mmap.h"
@ -64,6 +65,7 @@
#ifdef CONFIG_ESPRESSIF_SIMPLE_BOOT #ifdef CONFIG_ESPRESSIF_SIMPLE_BOOT
# include "bootloader_init.h" # include "bootloader_init.h"
#endif #endif
#include "bootloader_flash_config.h"
#include "esp_clk_internal.h" #include "esp_clk_internal.h"
#include "periph_ctrl.h" #include "periph_ctrl.h"
@ -135,6 +137,7 @@ extern void cache_set_idrom_mmu_info(uint32_t instr_page_num,
#ifdef CONFIG_ESP32S3_DATA_CACHE_16KB #ifdef CONFIG_ESP32S3_DATA_CACHE_16KB
extern int cache_occupy_addr(uint32_t addr, uint32_t size); extern int cache_occupy_addr(uint32_t addr, uint32_t size);
#endif #endif
extern int ets_printf(const char *fmt, ...);
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
@ -380,12 +383,6 @@ noinstrument_function void noreturn_function IRAM_ATTR __esp32s3_start(void)
showprogress('A'); showprogress('A');
#if defined(CONFIG_ESP32S3_FLASH_MODE_OCT) || \
defined(CONFIG_ESP32S3_SPIRAM_MODE_OCT)
esp_rom_opiflash_pin_config();
esp32s3_spi_timing_set_pin_drive_strength();
#endif
/* The PLL provided by bootloader is not stable enough, do calibration /* The PLL provided by bootloader is not stable enough, do calibration
* again here so that we can use better clock for the timing tuning. * again here so that we can use better clock for the timing tuning.
*/ */
@ -509,6 +506,41 @@ noinstrument_function void IRAM_ATTR __start(void)
configure_cpu_caches(); configure_cpu_caches();
if (efuse_ll_get_flash_type())
{
#ifndef CONFIG_ESP32S3_FLASH_MODE_OCT
ets_printf("Octal Flash chip detected!\n"
"Select CONFIG_ESP32S3_FLASH_MODE_OCT on menuconfig\n");
abort();
#endif
}
else
{
#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT
ets_printf("Octal Flash option selected, but EFUSE not configured!\n");
abort();
#endif
}
esp_mspi_pin_init();
/* At this point, the Flash chip is still in one of the DOUT, DIO, QOUT
* or QIO modes. It's hard to implement a read_id function in OPI mode,
* so the Flash chip ID is read here, before entering the OPI mode (if
* applicable).
*/
bootloader_flash_update_id();
/* The following function initializes the Flash chip to the user-defined
* settings. Please note that the Flash chip is initialized with temporary
* settings during the boot phase to enable using different chips. In this
* stage, the Flash chip and the MSPI are reconfigured to the required
* final settings.
*/
spi_flash_init_chip_state();
__esp32s3_start(); __esp32s3_start();
while (true); /* Should not return */ while (true); /* Should not return */

View file

@ -73,6 +73,8 @@ ARCHSCRIPT += $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)
# Source files # Source files
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c
@ -101,6 +103,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)mspi_timing_tuning.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)mspi_timing_tuning.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_wdt.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_wdt.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_cache_esp32s2_esp32s3.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_cache_esp32s2_esp32s3.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_efuse.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)clk.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)clk.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)system_internal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)system_internal.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)$(CHIP_SERIES)$(DELIM)clk_tree_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)$(CHIP_SERIES)$(DELIM)clk_tree_hal.c
@ -129,6 +132,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)i2c_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)i2c_periph.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)mcpwm_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)mcpwm_periph.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)temperature_sensor_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)temperature_sensor_periph.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)spi_flash_wrap.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)flash_ops.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)spi_flash_hpm_enable.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)${CHIP_SERIES}$(DELIM)spi_flash_oct_flash_init.c
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y) ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)bootloader_banner_wrap.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)bootloader_banner_wrap.c
@ -138,8 +145,7 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_init.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_init.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_common.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_common.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_common_loader.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_common_loader.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)flash_qio_mode.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_clock_init.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_clock_init.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_clock_loader.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_clock_loader.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_efuse.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_efuse.c

View file

@ -39,3 +39,8 @@ PROVIDE( cache_suspend_icache = Cache_Suspend_ICache );
PROVIDE( cache_writeback_all = Cache_WriteBack_All ); PROVIDE( cache_writeback_all = Cache_WriteBack_All );
PROVIDE( cache_writeback_items = Cache_WriteBack_Items ); PROVIDE( cache_writeback_items = Cache_WriteBack_Items );
PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr ); PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr );
#ifndef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
spi_flash_guard_set = 0x40000b04;
spi_flash_guard_get = 0x40000b10;
#endif

View file

@ -236,6 +236,10 @@ SECTIONS
*libarch.a:*cpu_region_protect.*(.text .text.* .literal .literal.*) *libarch.a:*cpu_region_protect.*(.text .text.* .literal .literal.*)
*libarch.a:*mspi_timing_tuning.*(.text .text.* .literal .literal.*) *libarch.a:*mspi_timing_tuning.*(.text .text.* .literal .literal.*)
*libarch.a:*esp_rom_cache_esp32s2_esp32s3.*(.literal .text .literal.* .text.*) *libarch.a:*esp_rom_cache_esp32s2_esp32s3.*(.literal .text .literal.* .text.*)
*libarch.a:*flash_qio_mode.*(.text .text.* .literal .literal.*)
*libarch.a:*spi_flash_wrap.*(.text .text.* .literal .literal.*)
*libarch.a:*spi_flash_oct_flash_init.*(.text .text.* .literal .literal.*)
*libarch.a:*spi_flash_hpm_enable.*(.text .text.* .literal .literal.*)
*libc.a:*lib_instrument.*(.text .text.* .literal .literal.*) *libc.a:*lib_instrument.*(.text .text.* .literal .literal.*)
@ -432,6 +436,10 @@ SECTIONS
#ifdef CONFIG_ESP32S3_SPIRAM_MODE_OCT #ifdef CONFIG_ESP32S3_SPIRAM_MODE_OCT
*libarch.a:esp32s3_psram_octal.*(.rodata .rodata.*) *libarch.a:esp32s3_psram_octal.*(.rodata .rodata.*)
#endif #endif
*libarch.a:*flash_qio_mode.*(.rodata .rodata.*)
*libarch.a:*spi_flash_wrap.*(.rodata .rodata.*)
*libarch.a:*spi_flash_oct_flash_init.*(.rodata .rodata.*)
*libarch.a:*spi_flash_hpm_enable.*(.rodata .rodata.*)
. = ALIGN(4); . = ALIGN(4);
_edata = ABSOLUTE(.); _edata = ABSOLUTE(.);

View file

@ -42,6 +42,8 @@ else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_QIO),y)
FLASH_MODE := qio FLASH_MODE := qio
else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_QOUT),y) else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_QOUT),y)
FLASH_MODE := qout FLASH_MODE := qout
else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_OCT),y)
FLASH_MODE := qio
endif endif
FLASH_FREQ := $(CONFIG_ESPRESSIF_FLASH_FREQ) FLASH_FREQ := $(CONFIG_ESPRESSIF_FLASH_FREQ)