spi_flash: Support select flash mode automatically at run time(Quad flash or Octal flash)

This commit is contained in:
Cao Sen Miao
2022-09-23 17:32:16 +08:00
parent 542bdea689
commit 2c9bb4eb7d
12 changed files with 170 additions and 78 deletions

View File

@@ -57,6 +57,13 @@ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
*/ */
esp_err_t bootloader_flash_reset_chip(void); esp_err_t bootloader_flash_reset_chip(void);
/**
* @brief Check if octal flash mode is enabled in eFuse
*
* @return True if flash is in octal mode, false else
*/
bool bootloader_flash_is_octal_mode_enabled(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -10,6 +10,7 @@
#include <esp_flash_encrypt.h> #include <esp_flash_encrypt.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/efuse_ll.h"
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
# include "soc/spi_struct.h" # include "soc/spi_struct.h"
@@ -780,3 +781,12 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void)
return ESP_OK; return ESP_OK;
} }
bool bootloader_flash_is_octal_mode_enabled(void)
{
#if SOC_SPI_MEM_SUPPORT_OPI_MODE
return efuse_ll_get_flash_type();
#else
return false;
#endif
}

View File

@@ -17,6 +17,7 @@
#include "flash_qio_mode.h" #include "flash_qio_mode.h"
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "bootloader_common.h" #include "bootloader_common.h"
#include "bootloader_flash.h"
#define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_40M 0
#define FLASH_IO_MATRIX_DUMMY_80M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0
@@ -34,17 +35,18 @@ void bootloader_flash_update_id()
void IRAM_ATTR bootloader_flash_cs_timing_config() void IRAM_ATTR bootloader_flash_cs_timing_config()
{ {
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH, so we only need to set SPI0 related registers here //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH, so we only need to set SPI0 related registers here
#if CONFIG_ESPTOOLPY_OCT_FLASH if (bootloader_flash_is_octal_mode_enabled()) {
SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S); SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S);
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_CS_SETUP_TIME_S); SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_CS_SETUP_TIME_S);
//CS high time //CS high time
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_CS_HOLD_DELAY_S); SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_CS_HOLD_DELAY_S);
#else } else {
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S); SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S);
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S); SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
#endif }
} }
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)

View File

@@ -218,7 +218,9 @@ static esp_err_t bootloader_init_spi_flash(void)
bootloader_flash_unlock(); bootloader_flash_unlock();
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
if (!bootloader_flash_is_octal_mode_enabled()) {
bootloader_enable_qio_mode(); bootloader_enable_qio_mode();
}
#endif #endif
print_flash_info(&bootloader_image_hdr); print_flash_info(&bootloader_image_hdr);

View File

@@ -22,6 +22,7 @@
#include "esp_private/gpio.h" #include "esp_private/gpio.h"
#include "esp_private/sleep_gpio.h" #include "esp_private/sleep_gpio.h"
#include "esp_private/spi_flash_os.h" #include "esp_private/spi_flash_os.h"
#include "bootloader_flash.h"
static const char *TAG = "sleep"; static const char *TAG = "sleep";
@@ -71,13 +72,19 @@ void esp_sleep_config_gpio_isolate(void)
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D), GPIO_PULLUP_ONLY);
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_HD), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_HD), GPIO_PULLUP_ONLY);
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_WP), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_WP), GPIO_PULLUP_ONLY);
#if CONFIG_SPIRAM_MODE_OCT || CONFIG_ESPTOOLPY_FLASHMODE_OPI #if SOC_SPI_MEM_SUPPORT_OPI_MODE
bool octal_mspi_required = bootloader_flash_is_octal_mode_enabled();
#if CONFIG_SPIRAM_MODE_OCT
octal_mspi_required |= true;
#endif // CONFIG_SPIRAM_MODE_OCT
if (octal_mspi_required) {
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_DQS), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_DQS), GPIO_PULLUP_ONLY);
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D4), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D4), GPIO_PULLUP_ONLY);
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D5), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D5), GPIO_PULLUP_ONLY);
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D6), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D6), GPIO_PULLUP_ONLY);
gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D7), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_D7), GPIO_PULLUP_ONLY);
#endif // CONFIG_SPIRAM_MODE_OCT || CONFIG_ESPTOOLPY_FLASHMODE_OPI }
#endif // SOC_SPI_MEM_SUPPORT_OPI_MODE
#endif // CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU #endif // CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU
} }

View File

@@ -364,7 +364,7 @@ void IRAM_ATTR call_start_cpu0(void)
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
#endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 #endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
#if CONFIG_ESPTOOLPY_OCT_FLASH #if CONFIG_ESPTOOLPY_OCT_FLASH && !CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT
bool efuse_opflash_en = efuse_ll_get_flash_type(); bool efuse_opflash_en = efuse_ll_get_flash_type();
if (!efuse_opflash_en) { if (!efuse_opflash_en) {
ESP_EARLY_LOGE(TAG, "Octal Flash option selected, but EFUSE not configured!"); ESP_EARLY_LOGE(TAG, "Octal Flash option selected, but EFUSE not configured!");

View File

@@ -14,6 +14,25 @@ menu "Serial flasher config"
bool "Enable Octal Flash" bool "Enable Octal Flash"
default n default n
config ESPTOOLPY_FLASH_MODE_AUTO_DETECT
depends on IDF_TARGET_ESP32S3
bool "Choose flash mode automatically (please read help)"
default y
help
This config option helps decide whether flash is Quad or Octal, but please note some limitations:
1. If the flash chip is an Octal one, even if one of "QIO", "QOUT", "DIO", "DOUT" options is
selected in `ESPTOOLPY_FLASHMODE`, our code will automatically change the
mode to "OPI" and the sample mode will be STR.
2. If the flash chip is a Quad one, even if "OPI" is selected in `ESPTOOLPY_FLASHMODE`, our code will
automatically change the mode to "DIO".
3. Please do not rely on this option when you are pretty sure that you are using Octal flash,
please enable `ESPTOOLPY_OCT_FLASH` option, then you can choose `DTR` sample mode
in `ESPTOOLPY_FLASH_SAMPLE_MODE`. Otherwise, only `STR` mode is available.
4. Enabling this feature reduces available internal RAM size (around 900 bytes).
If your IRAM space is insufficient and you're aware of your flash type,
disable this option and select corresponding flash type options.
choice ESPTOOLPY_FLASHMODE choice ESPTOOLPY_FLASHMODE
prompt "Flash SPI mode" prompt "Flash SPI mode"
default ESPTOOLPY_FLASHMODE_DIO default ESPTOOLPY_FLASHMODE_DIO

View File

@@ -29,7 +29,7 @@ else()
"flash_brownout_hook.c" "flash_brownout_hook.c"
) )
if(CONFIG_ESPTOOLPY_OCT_FLASH) if(CONFIG_SOC_SPI_MEM_SUPPORT_OPI_MODE)
list(APPEND srcs "${target}/spi_flash_oct_flash_init.c") list(APPEND srcs "${target}/spi_flash_oct_flash_init.c")
endif() endif()

View File

@@ -14,6 +14,7 @@
#include "soc/spi_mem_reg.h" #include "soc/spi_mem_reg.h"
#include "spi_timing_config.h" #include "spi_timing_config.h"
#include "esp_private/spi_flash_os.h" #include "esp_private/spi_flash_os.h"
#include "bootloader_flash.h"
#define OPI_PSRAM_SYNC_READ 0x0000 #define OPI_PSRAM_SYNC_READ 0x0000
#define OPI_PSRAM_SYNC_WRITE 0x8080 #define OPI_PSRAM_SYNC_WRITE 0x8080
@@ -106,9 +107,7 @@ typedef enum {
PSRAM_CMD_SPI, PSRAM_CMD_SPI,
} psram_cmd_mode_t; } psram_cmd_mode_t;
#if !CONFIG_ESPTOOLPY_OCT_FLASH
static uint8_t s_rom_flash_extra_dummy[2] = {NOT_INIT_INT, NOT_INIT_INT}; static uint8_t s_rom_flash_extra_dummy[2] = {NOT_INIT_INT, NOT_INIT_INT};
#endif
#if CONFIG_SPIRAM_MODE_QUAD #if CONFIG_SPIRAM_MODE_QUAD
static uint8_t s_psram_extra_dummy; static uint8_t s_psram_extra_dummy;
@@ -137,7 +136,6 @@ void spi_timing_config_flash_set_din_mode_num(uint8_t spi_num, uint8_t din_mode,
REG_WRITE(SPI_MEM_DIN_NUM_REG(spi_num), reg_val); REG_WRITE(SPI_MEM_DIN_NUM_REG(spi_num), reg_val);
} }
#ifndef CONFIG_ESPTOOLPY_OCT_FLASH
static uint32_t spi_timing_config_get_dummy(void) static uint32_t spi_timing_config_get_dummy(void)
{ {
uint32_t ctrl_reg = READ_PERI_REG(SPI_MEM_CTRL_REG(0)); uint32_t ctrl_reg = READ_PERI_REG(SPI_MEM_CTRL_REG(0));
@@ -185,11 +183,10 @@ static uint32_t spi_timing_config_get_dummy(void)
} }
} }
} }
#endif
void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dummy) void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dummy)
{ {
#if CONFIG_ESPTOOLPY_OCT_FLASH if (bootloader_flash_is_octal_mode_enabled()) {
if (extra_dummy > 0) { if (extra_dummy > 0) {
SET_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M); SET_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M);
SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy, SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy,
@@ -199,7 +196,8 @@ void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dumm
SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, 0, SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, 0,
SPI_MEM_EXTRA_DUMMY_CYCLELEN_S); SPI_MEM_EXTRA_DUMMY_CYCLELEN_S);
} }
#else return;
}
/** /**
* The `SPI_MEM_TIMING_CALI_REG` register is only used for OPI on 728 * The `SPI_MEM_TIMING_CALI_REG` register is only used for OPI on 728
* Here we only need to update this global variable for extra dummy. Since we use the ROM Flash API, which will set the dummy based on this. * Here we only need to update this global variable for extra dummy. Since we use the ROM Flash API, which will set the dummy based on this.
@@ -213,7 +211,6 @@ void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dumm
// Only Quad Flash will run into this branch. // Only Quad Flash will run into this branch.
uint32_t dummy = spi_timing_config_get_dummy(); uint32_t dummy = spi_timing_config_get_dummy();
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, dummy + g_rom_spiflash_dummy_len_plus[spi_num], SPI_MEM_USR_DUMMY_CYCLELEN_S); SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, dummy + g_rom_spiflash_dummy_len_plus[spi_num], SPI_MEM_USR_DUMMY_CYCLELEN_S);
#endif
} }
//-------------------------------------PSRAM timing tuning register config-------------------------------------// //-------------------------------------PSRAM timing tuning register config-------------------------------------//
@@ -252,7 +249,7 @@ void spi_timing_config_psram_set_extra_dummy(uint8_t spi_num, uint8_t extra_dumm
//-------------------------------------------FLASH/PSRAM Read/Write------------------------------------------// //-------------------------------------------FLASH/PSRAM Read/Write------------------------------------------//
void spi_timing_config_flash_read_data(uint8_t spi_num, uint8_t *buf, uint32_t addr, uint32_t len) void spi_timing_config_flash_read_data(uint8_t spi_num, uint8_t *buf, uint32_t addr, uint32_t len)
{ {
#if CONFIG_ESPTOOLPY_OCT_FLASH if (bootloader_flash_is_octal_mode_enabled()) {
// note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state. // note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state.
// but after we change the timing settings, we might not read correct idle status via RDSR. // but after we change the timing settings, we might not read correct idle status via RDSR.
// so, here we should use a read API that won't check idle status. // so, here we should use a read API that won't check idle status.
@@ -260,9 +257,9 @@ void spi_timing_config_flash_read_data(uint8_t spi_num, uint8_t *buf, uint32_t a
REG_WRITE(SPI_MEM_W0_REG(1) + i*4, 0); REG_WRITE(SPI_MEM_W0_REG(1) + i*4, 0);
} }
esp_rom_opiflash_read_raw(addr, buf, len); esp_rom_opiflash_read_raw(addr, buf, len);
#else } else {
esp_rom_spiflash_read(addr, (uint32_t *)buf, len); esp_rom_spiflash_read(addr, (uint32_t *)buf, len);
#endif }
} }
static void s_psram_write_data(uint8_t spi_num, uint8_t *buf, uint32_t addr, uint32_t len) static void s_psram_write_data(uint8_t spi_num, uint8_t *buf, uint32_t addr, uint32_t len)

View File

@@ -23,6 +23,7 @@
#include "esp_private/cache_utils.h" #include "esp_private/cache_utils.h"
#include "esp_spi_flash_counters.h" #include "esp_spi_flash_counters.h"
#include "esp_rom_spiflash.h" #include "esp_rom_spiflash.h"
#include "bootloader_flash.h"
__attribute__((unused)) static const char TAG[] = "spi_flash"; __attribute__((unused)) static const char TAG[] = "spi_flash";
@@ -61,18 +62,25 @@ esp_flash_t *esp_flash_default_chip = NULL;
#if defined(CONFIG_ESPTOOLPY_FLASHMODE_QIO) #if defined(CONFIG_ESPTOOLPY_FLASHMODE_QIO)
#define DEFAULT_FLASH_MODE SPI_FLASH_QIO #define DEFAULT_FLASH_MODE SPI_FLASH_QIO
#define FLASH_MODE_STRING "qio"
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_QOUT) #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_QOUT)
#define DEFAULT_FLASH_MODE SPI_FLASH_QOUT #define DEFAULT_FLASH_MODE SPI_FLASH_QOUT
#define FLASH_MODE_STRING "qout"
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DIO) #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DIO)
#define DEFAULT_FLASH_MODE SPI_FLASH_DIO #define DEFAULT_FLASH_MODE SPI_FLASH_DIO
#define FLASH_MODE_STRING "dio"
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DOUT) #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DOUT)
#define DEFAULT_FLASH_MODE SPI_FLASH_DOUT #define DEFAULT_FLASH_MODE SPI_FLASH_DOUT
#define FLASH_MODE_STRING "dout"
#elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR) #elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR)
#define DEFAULT_FLASH_MODE SPI_FLASH_OPI_STR #define DEFAULT_FLASH_MODE SPI_FLASH_OPI_STR
#define FLASH_MODE_STRING "opi_str"
#elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR) #elif defined(CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR)
#define DEFAULT_FLASH_MODE SPI_FLASH_OPI_DTR #define DEFAULT_FLASH_MODE SPI_FLASH_OPI_DTR
#define FLASH_MODE_STRING "opi_dtr"
#else #else
#define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD #define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD
#define FLASH_MODE_STRING "fast_rd"
#endif #endif
//TODO: modify cs hold to meet requirements of all chips!!! //TODO: modify cs hold to meet requirements of all chips!!!
@@ -326,6 +334,29 @@ static DRAM_ATTR esp_flash_t default_chip = {
.os_func = &esp_flash_noos_functions, .os_func = &esp_flash_noos_functions,
}; };
#if CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT
/* This function is used to correct flash mode if config option is not consistent with efuse information */
static void s_esp_flash_choose_correct_mode(memspi_host_config_t *cfg)
{
static const char *mode = FLASH_MODE_STRING;
if (bootloader_flash_is_octal_mode_enabled()) {
#if !CONFIG_ESPTOOLPY_FLASHMODE_OPI
ESP_EARLY_LOGW(TAG, "Octal flash chip is using but %s mode is selected, will automatically swich to Octal mode", mode);
cfg->octal_mode_en = 1;
cfg->default_io_mode = SPI_FLASH_OPI_STR;
default_chip.read_mode = SPI_FLASH_OPI_STR;
#endif
} else {
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI
ESP_EARLY_LOGW(TAG, "Quad flash chip is using but %s flash mode is selected, will automatically swich to DIO mode", mode);
cfg->octal_mode_en = 0;
cfg->default_io_mode = SPI_FLASH_DIO;
default_chip.read_mode = SPI_FLASH_DIO;
#endif
}
}
#endif // CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT
extern esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip); extern esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip);
esp_err_t esp_flash_init_default_chip(void) esp_err_t esp_flash_init_default_chip(void)
{ {
@@ -342,6 +373,12 @@ esp_err_t esp_flash_init_default_chip(void)
cfg.default_io_mode = DEFAULT_FLASH_MODE; cfg.default_io_mode = DEFAULT_FLASH_MODE;
#endif #endif
#if CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT
// Automatically detect flash mode in run time
s_esp_flash_choose_correct_mode(&cfg);
#endif
// For chips need time tuning, get value directely from system here. // For chips need time tuning, get value directely from system here.
#if SOC_SPI_MEM_SUPPORT_TIME_TUNING #if SOC_SPI_MEM_SUPPORT_TIME_TUNING
if (spi_timing_is_tuned()) { if (spi_timing_is_tuned()) {

View File

@@ -155,27 +155,36 @@ void IRAM_ATTR spi_flash_rom_impl_init(void)
void IRAM_ATTR esp_mspi_pin_init(void) void IRAM_ATTR esp_mspi_pin_init(void)
{ {
#if CONFIG_ESPTOOLPY_OCT_FLASH || CONFIG_SPIRAM_MODE_OCT #if SOC_SPI_MEM_SUPPORT_OPI_MODE
bool octal_mspi_required = bootloader_flash_is_octal_mode_enabled();
#if CONFIG_SPIRAM_MODE_OCT
octal_mspi_required |= true;
#endif
if (octal_mspi_required) {
esp_rom_opiflash_pin_config(); esp_rom_opiflash_pin_config();
extern void spi_timing_set_pin_drive_strength(void); extern void spi_timing_set_pin_drive_strength(void);
spi_timing_set_pin_drive_strength(); spi_timing_set_pin_drive_strength();
#else }
//Set F4R4 board pin drive strength. TODO: IDF-3663 //Set F4R4 board pin drive strength. TODO: IDF-3663
#endif #endif
} }
esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) esp_err_t IRAM_ATTR spi_flash_init_chip_state(void)
{ {
#if CONFIG_ESPTOOLPY_OCT_FLASH #if SOC_SPI_MEM_SUPPORT_OPI_MODE
if (bootloader_flash_is_octal_mode_enabled()) {
return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id); return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id);
#else } else
#if CONFIG_IDF_TARGET_ESP32S3 #endif
{
#if CONFIG_IDF_TARGET_ESP32S3
// Currently, only esp32s3 allows high performance mode. // Currently, only esp32s3 allows high performance mode.
return spi_flash_enable_high_performance_mode(); return spi_flash_enable_high_performance_mode();
#else #else
return ESP_OK; return ESP_OK;
#endif // CONFIG_IDF_TARGET_ESP32S3 #endif // CONFIG_IDF_TARGET_ESP32S3
#endif // CONFIG_ESPTOOLPY_OCT_FLASH }
} }
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS #if CONFIG_SPI_FLASH_ENABLE_COUNTERS
@@ -207,7 +216,8 @@ void spi_flash_dump_counters(void)
void IRAM_ATTR spi_flash_set_rom_required_regs(void) void IRAM_ATTR spi_flash_set_rom_required_regs(void)
{ {
#if CONFIG_ESPTOOLPY_OCT_FLASH #if SOC_SPI_MEM_SUPPORT_OPI_MODE
if (bootloader_flash_is_octal_mode_enabled()) {
//Disable the variable dummy mode when doing timing tuning //Disable the variable dummy mode when doing timing tuning
CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY);
/** /**
@@ -215,6 +225,7 @@ void IRAM_ATTR spi_flash_set_rom_required_regs(void)
* *
* Add any registers that are not set in ROM SPI flash functions here in the future * Add any registers that are not set in ROM SPI flash functions here in the future
*/ */
}
#endif #endif
} }
@@ -222,14 +233,14 @@ void IRAM_ATTR spi_flash_set_rom_required_regs(void)
// This function will only be called when Octal PSRAM enabled. // This function will only be called when Octal PSRAM enabled.
void IRAM_ATTR spi_flash_set_vendor_required_regs(void) void IRAM_ATTR spi_flash_set_vendor_required_regs(void)
{ {
#if CONFIG_ESPTOOLPY_OCT_FLASH if (bootloader_flash_is_octal_mode_enabled()) {
//Flash chip requires MSPI specifically, call this function to set them
esp_opiflash_set_required_regs(); esp_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); 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 } else {
//Flash chip requires MSPI specifically, call this function to set them
// Set back MSPI registers after Octal PSRAM initialization. // Set back 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); 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 // CONFIG_ESPTOOLPY_OCT_FLASH }
} }
#endif #endif

View File

@@ -17,5 +17,5 @@ entries:
spi_flash_chip_mxic_opi (noflash) spi_flash_chip_mxic_opi (noflash)
spi_flash_hpm_enable (noflash) spi_flash_hpm_enable (noflash)
if IDF_TARGET_ESP32S3 = y && ESPTOOLPY_OCT_FLASH = y: if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y:
spi_flash_oct_flash_init (noflash) spi_flash_oct_flash_init (noflash)