Merge branch 'feature/support_xmc_HPM' into 'master'

spi_flash: Re-enable HPM mode for several XMC chips.

Closes IDF-5362

See merge request espressif/esp-idf!18648
This commit is contained in:
Simon
2022-07-22 10:47:37 +08:00
14 changed files with 121 additions and 33 deletions

View File

@@ -42,6 +42,7 @@ extern "C" {
#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */ #define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */
#define CMD_WRSR3 0x11 /* Not all SPI flash uses this command */ #define CMD_WRSR3 0x11 /* Not all SPI flash uses this command */
#define CMD_WREN 0x06 #define CMD_WREN 0x06
#define CMD_WRENVSR 0x50 /* Flash write enable for volatile SR bits */
#define CMD_WRDI 0x04 #define CMD_WRDI 0x04
#define CMD_RDSR 0x05 #define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */ #define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
@@ -50,6 +51,8 @@ extern "C" {
#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ #define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */
#define CMD_WRAP 0x77 /* Set burst with wrap command */ #define CMD_WRAP 0x77 /* Set burst with wrap command */
#define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */ #define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */
#define CMD_RESETEN 0x66
#define CMD_RESET 0x99
/* Provide a Flash API for bootloader_support code, /* Provide a Flash API for bootloader_support code,
@@ -172,6 +175,14 @@ uint32_t bootloader_flash_read_sfdp(uint32_t sfdp_addr, unsigned int miso_byte_n
*/ */
void bootloader_enable_wp(void); void bootloader_enable_wp(void);
/**
* @brief Once this function is called,
* any on-going internal operations will be terminated and the device will return to its default power-on
* state and lose all the current volatile settings, such as Volatile Status Register bits, Write Enable Latch
* (WEL) status, Program/Erase Suspend status, etc.
*/
void bootloader_spi_flash_reset(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -603,6 +603,12 @@ uint32_t IRAM_ATTR bootloader_read_flash_id(void)
return id; return id;
} }
void bootloader_spi_flash_reset(void)
{
bootloader_execute_flash_command(CMD_RESETEN, 0, 0, 0);
bootloader_execute_flash_command(CMD_RESET, 0, 0, 0);
}
#if SOC_CACHE_SUPPORT_WRAP #if SOC_CACHE_SUPPORT_WRAP
esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode) esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode)
{ {

View File

@@ -210,6 +210,11 @@ static esp_err_t bootloader_init_spi_flash(void)
} }
#endif #endif
#if CONFIG_SPI_FLASH_HPM_ENABLE
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
bootloader_spi_flash_reset();
#endif
bootloader_flash_unlock(); bootloader_flash_unlock();
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT

View File

@@ -74,6 +74,7 @@ menu "Serial flasher config"
default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H2 default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H2
config ESPTOOLPY_FLASHFREQ_120M config ESPTOOLPY_FLASHFREQ_120M
bool "120 MHz" bool "120 MHz"
select SPI_FLASH_HPM_ENABLE
depends on SOC_MEMSPI_SRC_FREQ_120M && ESPTOOLPY_FLASH_SAMPLE_MODE_STR depends on SOC_MEMSPI_SRC_FREQ_120M && ESPTOOLPY_FLASH_SAMPLE_MODE_STR
config ESPTOOLPY_FLASHFREQ_80M config ESPTOOLPY_FLASHFREQ_80M
bool "80 MHz" bool "80 MHz"

View File

@@ -20,7 +20,17 @@ set(ESPSECUREPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py")
set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py") set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py")
set(ESPMONITOR ${python} "${idf_path}/tools/idf_monitor.py") set(ESPMONITOR ${python} "${idf_path}/tools/idf_monitor.py")
set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE}) if(CONFIG_SPI_FLASH_HPM_ENABLE)
# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode
# because on some flash chips, 120M will modify the status register,
# which will make ROM won't work.
# This change intends to be for esptool only and the bootloader should keep use
# ``DOUT`` mode.
set(ESPFLASHMODE "dout")
message("Note: HPM is enabled for the flash, force the ROM bootloader into DOUT mode for stable boot on")
else()
set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE})
endif()
set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ}) set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ})
set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE}) set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE})

View File

@@ -300,4 +300,11 @@ menu "SPI Flash driver"
application is not using flash encryption feature and is in need of some additional application is not using flash encryption feature and is in need of some additional
memory from IRAM region (~1KB) then this config can be disabled. memory from IRAM region (~1KB) then this config can be disabled.
config SPI_FLASH_HPM_ENABLE
bool
default n
help
This option is invisible, and will be selected automatically
when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.
endmenu endmenu

View File

@@ -13,6 +13,7 @@
#include "esp_log.h" #include "esp_log.h"
#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"
#define OPI_PSRAM_SYNC_READ 0x0000 #define OPI_PSRAM_SYNC_READ 0x0000
#define OPI_PSRAM_SYNC_WRITE 0x8080 #define OPI_PSRAM_SYNC_WRITE 0x8080
@@ -164,21 +165,24 @@ void spi_timing_config_flash_set_extra_dummy(uint8_t spi_num, uint8_t extra_dumm
if (ctrl_reg & MULTI_LINE_MASK_OCT_FLASH) { if (ctrl_reg & MULTI_LINE_MASK_OCT_FLASH) {
abort(); abort();
} }
// Only Quad Flash will run into this branch.
// So simply get the hpm dummy here by calling `spi_flash_hpm_get_dummy()`
const spi_flash_hpm_dummy_conf_t *dummy_cycle = spi_flash_hpm_get_dummy();
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) { switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
case SPI_FLASH_QIO_MODE: case SPI_FLASH_QIO_MODE:
dummy = SPI1_R_QIO_DUMMY_CYCLELEN; dummy = dummy_cycle->qio_dummy - 1;
break; break;
case SPI_FLASH_QUAD_MODE: case SPI_FLASH_QUAD_MODE:
dummy = SPI1_R_FAST_DUMMY_CYCLELEN; dummy = dummy_cycle->qout_dummy - 1;
break; break;
case SPI_FLASH_DIO_MODE: case SPI_FLASH_DIO_MODE:
dummy = SPI1_R_DIO_DUMMY_CYCLELEN; dummy = dummy_cycle->dio_dummy - 1;
break; break;
case SPI_FLASH_DUAL_MODE: case SPI_FLASH_DUAL_MODE:
dummy = SPI1_R_FAST_DUMMY_CYCLELEN; dummy = dummy_cycle->dout_dummy - 1;
break; break;
case SPI_FLASH_FAST_MODE: case SPI_FLASH_FAST_MODE:
dummy = SPI1_R_FAST_DUMMY_CYCLELEN; dummy = dummy_cycle->fastrd_dummy - 1;
break; break;
case SPI_FLASH_SLOW_MODE: case SPI_FLASH_SLOW_MODE:
dummy = 0; dummy = 0;

View File

@@ -381,6 +381,13 @@ esp_err_t esp_flash_init_default_chip(void)
return err; return err;
} }
#endif #endif
#if CONFIG_SPI_FLASH_HPM_ENABLE
if (spi_flash_hpm_dummy_adjust()) {
default_chip.hpm_dummy_ena = 1;
}
#endif
return ESP_OK; return ESP_OK;
} }

View File

@@ -100,7 +100,8 @@ struct esp_flash_t {
uint32_t size; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation. uint32_t size; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation.
uint32_t chip_id; ///< Detected chip id. uint32_t chip_id; ///< Detected chip id.
uint32_t busy :1; ///< This flag is used to verify chip's status. uint32_t busy :1; ///< This flag is used to verify chip's status.
uint32_t reserved_flags :31; ///< reserved. uint32_t hpm_dummy_ena :1; ///< This flag is used to verify whether flash works under HPM status.
uint32_t reserved_flags :30; ///< reserved.
}; };

View File

@@ -165,9 +165,16 @@ esp_err_t spi_flash_enable_high_performance_mode(void);
* This can be used when one flash has several dummy configurations to enable the high performance mode. * This can be used when one flash has several dummy configurations to enable the high performance mode.
* @note Don't forget to subtract one when assign to the register of mspi e.g. if the value you get is 4, (4-1=3) should be assigned to the register. * @note Don't forget to subtract one when assign to the register of mspi e.g. if the value you get is 4, (4-1=3) should be assigned to the register.
* *
* @return Pointer to bootlaoder_flash_dummy_conf_t. * @return Pointer to spi_flash_hpm_dummy_conf_t.
*/ */
const spi_flash_hpm_dummy_conf_t *spi_flash_get_dummy(void); const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void);
/**
* @brief Used to judge whether flash works under HPM mode with dummy adjustment.
*
* @return true Yes, and work under HPM with adjusting dummy. Otherwise, false.
*/
bool spi_flash_hpm_dummy_adjust(void);
typedef enum { typedef enum {
FLASH_WRAP_MODE_8B = 0, FLASH_WRAP_MODE_8B = 0,

View File

@@ -67,3 +67,5 @@
#define SPI_FLASH_OPISTR_DUMMY_BITLEN 20 #define SPI_FLASH_OPISTR_DUMMY_BITLEN 20
#define SPI_FLASH_OPIDTR_ADDR_BITLEN 32 #define SPI_FLASH_OPIDTR_ADDR_BITLEN 32
#define SPI_FLASH_OPIDTR_DUMMY_BITLEN 40 #define SPI_FLASH_OPIDTR_DUMMY_BITLEN 40
#define SPI_FLASH_QIO_HPM_DUMMY_BITLEN 10
#define SPI_FLASH_DIO_HPM_DUMMY_BITLEN 8

View File

@@ -27,7 +27,8 @@ typedef struct {
} spi_flash_hpm_dummy_conf_t; } spi_flash_hpm_dummy_conf_t;
typedef enum { typedef enum {
SPI_FLASH_HPM_NEEDED, // Means that in the certain condition, flash needs to enter the high performance mode. SPI_FLASH_HPM_CMD_NEEDED, // Means that in the certain condition, flash needs to enter the high performance mode by command.
SPI_FLASH_HPM_DUMMY_NEEDED, // Means that in the certain condition, flash needs to enter the high performance mode by adjusting dummy.
SPI_FLASH_HPM_UNNEEDED, // Means that flash doesn't need to enter the high performance mode. SPI_FLASH_HPM_UNNEEDED, // Means that flash doesn't need to enter the high performance mode.
SPI_FLASH_HPM_BEYOND_LIMIT, // Means that flash has no capability to meet that condition. SPI_FLASH_HPM_BEYOND_LIMIT, // Means that flash has no capability to meet that condition.
} spi_flash_requirement_t; } spi_flash_requirement_t;

View File

@@ -33,6 +33,20 @@ DRAM_ATTR const static flash_chip_dummy_t default_flash_chip_dummy = {
.slowrd_dummy_bitlen = SPI_FLASH_SLOWRD_DUMMY_BITLEN, .slowrd_dummy_bitlen = SPI_FLASH_SLOWRD_DUMMY_BITLEN,
}; };
DRAM_ATTR const static flash_chip_dummy_t hpm_flash_chip_dummy = {
.dio_dummy_bitlen = SPI_FLASH_DIO_HPM_DUMMY_BITLEN,
.qio_dummy_bitlen = SPI_FLASH_QIO_HPM_DUMMY_BITLEN,
.qout_dummy_bitlen = SPI_FLASH_QOUT_DUMMY_BITLEN,
.dout_dummy_bitlen = SPI_FLASH_DOUT_DUMMY_BITLEN,
.fastrd_dummy_bitlen = SPI_FLASH_FASTRD_DUMMY_BITLEN,
.slowrd_dummy_bitlen = SPI_FLASH_SLOWRD_DUMMY_BITLEN,
};
DRAM_ATTR flash_chip_dummy_t *rom_flash_chip_dummy = (flash_chip_dummy_t *)&default_flash_chip_dummy;
DRAM_ATTR flash_chip_dummy_t *rom_flash_chip_dummy_hpm = (flash_chip_dummy_t *)&hpm_flash_chip_dummy;
// These are the pointer to HW flash encryption. Default using hardware encryption. // These are the pointer to HW flash encryption. Default using hardware encryption.
DRAM_ATTR static spi_flash_encryption_t esp_flash_encryption_default __attribute__((__unused__)) = { DRAM_ATTR static spi_flash_encryption_t esp_flash_encryption_default __attribute__((__unused__)) = {
.flash_encryption_enable = spi_flash_encryption_hal_enable, .flash_encryption_enable = spi_flash_encryption_hal_enable,
@@ -43,8 +57,6 @@ DRAM_ATTR static spi_flash_encryption_t esp_flash_encryption_default __attribute
.flash_encryption_check = spi_flash_encryption_hal_check, .flash_encryption_check = spi_flash_encryption_hal_check,
}; };
DRAM_ATTR flash_chip_dummy_t *rom_flash_chip_dummy = (flash_chip_dummy_t *)&default_flash_chip_dummy;
#define SPI_FLASH_DEFAULT_IDLE_TIMEOUT_MS 200 #define SPI_FLASH_DEFAULT_IDLE_TIMEOUT_MS 200
#define SPI_FLASH_GENERIC_CHIP_ERASE_TIMEOUT_MS 4000 #define SPI_FLASH_GENERIC_CHIP_ERASE_TIMEOUT_MS 4000
#define SPI_FLASH_GENERIC_SECTOR_ERASE_TIMEOUT_MS 600 //according to GD25Q127(125°) + 100ms #define SPI_FLASH_GENERIC_SECTOR_ERASE_TIMEOUT_MS 600 //according to GD25Q127(125°) + 100ms
@@ -467,35 +479,35 @@ esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t
case SPI_FLASH_QIO: case SPI_FLASH_QIO:
//for QIO mode, the 4 bit right after the address are used for continuous mode, should be set to 0 to avoid that. //for QIO mode, the 4 bit right after the address are used for continuous mode, should be set to 0 to avoid that.
addr_bitlen = SPI_FLASH_QIO_ADDR_BITLEN; addr_bitlen = SPI_FLASH_QIO_ADDR_BITLEN;
dummy_cyclelen_base = rom_flash_chip_dummy->qio_dummy_bitlen; dummy_cyclelen_base = (chip->hpm_dummy_ena ? rom_flash_chip_dummy_hpm->qio_dummy_bitlen : rom_flash_chip_dummy->qio_dummy_bitlen);
read_command = (addr_32bit? CMD_FASTRD_QIO_4B: CMD_FASTRD_QIO); read_command = (addr_32bit? CMD_FASTRD_QIO_4B: CMD_FASTRD_QIO);
conf_required = true; conf_required = true;
break; break;
case SPI_FLASH_QOUT: case SPI_FLASH_QOUT:
addr_bitlen = SPI_FLASH_QOUT_ADDR_BITLEN; addr_bitlen = SPI_FLASH_QOUT_ADDR_BITLEN;
dummy_cyclelen_base = rom_flash_chip_dummy->qout_dummy_bitlen; dummy_cyclelen_base = (chip->hpm_dummy_ena ? rom_flash_chip_dummy_hpm->qout_dummy_bitlen : rom_flash_chip_dummy->qout_dummy_bitlen);
read_command = (addr_32bit? CMD_FASTRD_QUAD_4B: CMD_FASTRD_QUAD); read_command = (addr_32bit? CMD_FASTRD_QUAD_4B: CMD_FASTRD_QUAD);
break; break;
case SPI_FLASH_DIO: case SPI_FLASH_DIO:
//for DIO mode, the 4 bit right after the address are used for continuous mode, should be set to 0 to avoid that. //for DIO mode, the 4 bit right after the address are used for continuous mode, should be set to 0 to avoid that.
addr_bitlen = SPI_FLASH_DIO_ADDR_BITLEN; addr_bitlen = SPI_FLASH_DIO_ADDR_BITLEN;
dummy_cyclelen_base = rom_flash_chip_dummy->dio_dummy_bitlen; dummy_cyclelen_base = (chip->hpm_dummy_ena ? rom_flash_chip_dummy_hpm->dio_dummy_bitlen : rom_flash_chip_dummy->dio_dummy_bitlen);
read_command = (addr_32bit? CMD_FASTRD_DIO_4B: CMD_FASTRD_DIO); read_command = (addr_32bit? CMD_FASTRD_DIO_4B: CMD_FASTRD_DIO);
conf_required = true; conf_required = true;
break; break;
case SPI_FLASH_DOUT: case SPI_FLASH_DOUT:
addr_bitlen = SPI_FLASH_DOUT_ADDR_BITLEN; addr_bitlen = SPI_FLASH_DOUT_ADDR_BITLEN;
dummy_cyclelen_base = rom_flash_chip_dummy->dout_dummy_bitlen; dummy_cyclelen_base = (chip->hpm_dummy_ena ? rom_flash_chip_dummy_hpm->dout_dummy_bitlen : rom_flash_chip_dummy->dout_dummy_bitlen);
read_command = (addr_32bit? CMD_FASTRD_DUAL_4B: CMD_FASTRD_DUAL); read_command = (addr_32bit? CMD_FASTRD_DUAL_4B: CMD_FASTRD_DUAL);
break; break;
case SPI_FLASH_FASTRD: case SPI_FLASH_FASTRD:
addr_bitlen = SPI_FLASH_FASTRD_ADDR_BITLEN; addr_bitlen = SPI_FLASH_FASTRD_ADDR_BITLEN;
dummy_cyclelen_base = rom_flash_chip_dummy->fastrd_dummy_bitlen; dummy_cyclelen_base = (chip->hpm_dummy_ena ? rom_flash_chip_dummy_hpm->fastrd_dummy_bitlen : rom_flash_chip_dummy->fastrd_dummy_bitlen);
read_command = (addr_32bit? CMD_FASTRD_4B: CMD_FASTRD); read_command = (addr_32bit? CMD_FASTRD_4B: CMD_FASTRD);
break; break;
case SPI_FLASH_SLOWRD: case SPI_FLASH_SLOWRD:
addr_bitlen = SPI_FLASH_SLOWRD_ADDR_BITLEN; addr_bitlen = SPI_FLASH_SLOWRD_ADDR_BITLEN;
dummy_cyclelen_base = rom_flash_chip_dummy->slowrd_dummy_bitlen; dummy_cyclelen_base = (chip->hpm_dummy_ena ? rom_flash_chip_dummy_hpm->slowrd_dummy_bitlen : rom_flash_chip_dummy->slowrd_dummy_bitlen);
read_command = (addr_32bit? CMD_READ_4B: CMD_READ); read_command = (addr_32bit? CMD_READ_4B: CMD_READ);
break; break;
default: default:

View File

@@ -80,7 +80,7 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_cmd
case 0xC84016: case 0xC84016:
case 0xC84017: case 0xC84017:
if (freq_mhz > 80) { if (freq_mhz > 80) {
chip_cap = SPI_FLASH_HPM_NEEDED; chip_cap = SPI_FLASH_HPM_CMD_NEEDED;
} }
break; break;
default: default:
@@ -126,6 +126,10 @@ static esp_err_t spi_flash_hpm_probe_chip_with_dummy(uint32_t flash_id)
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
switch (flash_id) { switch (flash_id) {
/* The flash listed here should enter the HPM by adjusting dummy cycles */ /* The flash listed here should enter the HPM by adjusting dummy cycles */
// XMC chips.
case 0x204017:
case 0x204018:
break;
default: default:
ret = ESP_ERR_NOT_FOUND; ret = ESP_ERR_NOT_FOUND;
break; break;
@@ -142,8 +146,9 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_dum
switch (flash_id) { switch (flash_id) {
/* The flash listed here should enter the HPM with command 0xA3 */ /* The flash listed here should enter the HPM with command 0xA3 */
case 0x204017: case 0x204017:
case 0x204018:
if (freq_mhz >= 104) { if (freq_mhz >= 104) {
chip_cap = SPI_FLASH_HPM_NEEDED; chip_cap = SPI_FLASH_HPM_DUMMY_NEEDED;
} }
break; break;
default: default:
@@ -164,7 +169,7 @@ static void spi_flash_turn_high_performance_reconfig_dummy(void)
{ {
uint8_t old_status_3 = bootloader_read_status_8b_rdsr3(); uint8_t old_status_3 = bootloader_read_status_8b_rdsr3();
uint8_t new_status = (old_status_3 | 0x03); uint8_t new_status = (old_status_3 | 0x03);
bootloader_execute_flash_command(CMD_WREN, 0, 0, 0); bootloader_execute_flash_command(CMD_WRENVSR, 0, 0, 0);
bootloader_write_status_8b_wrsr3(new_status); bootloader_write_status_8b_wrsr3(new_status);
esp_rom_spiflash_wait_idle(&g_rom_flashchip); esp_rom_spiflash_wait_idle(&g_rom_flashchip);
} }
@@ -182,11 +187,11 @@ static esp_err_t spi_flash_high_performance_check_dummy_sr(void)
static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf) static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf)
{ {
dummy_conf->dio_dummy = 8; dummy_conf->dio_dummy = SPI_FLASH_DIO_HPM_DUMMY_BITLEN;
dummy_conf->dout_dummy = 8; dummy_conf->dout_dummy = SPI_FLASH_DOUT_DUMMY_BITLEN;
dummy_conf->qio_dummy = 10; dummy_conf->qio_dummy = SPI_FLASH_QIO_HPM_DUMMY_BITLEN;
dummy_conf->qout_dummy = 8; dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
dummy_conf->fastrd_dummy = 8; dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
} }
@@ -198,11 +203,11 @@ static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf)
*/ */
void __attribute__((weak)) spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_conf_t *dummy_conf) void __attribute__((weak)) spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_conf_t *dummy_conf)
{ {
dummy_conf->dio_dummy = 4; dummy_conf->dio_dummy = SPI_FLASH_DIO_DUMMY_BITLEN;
dummy_conf->dout_dummy = 8; dummy_conf->dout_dummy = SPI_FLASH_DOUT_DUMMY_BITLEN;
dummy_conf->qio_dummy = 6; dummy_conf->qio_dummy = SPI_FLASH_QIO_DUMMY_BITLEN;
dummy_conf->qout_dummy = 8; dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
dummy_conf->fastrd_dummy = 8; dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
} }
const spi_flash_hpm_info_t __attribute__((weak)) spi_flash_hpm_enable_list[] = { const spi_flash_hpm_info_t __attribute__((weak)) spi_flash_hpm_enable_list[] = {
@@ -215,11 +220,13 @@ const spi_flash_hpm_info_t __attribute__((weak)) spi_flash_hpm_enable_list[] = {
static const spi_flash_hpm_info_t *chip_hpm = NULL; static const spi_flash_hpm_info_t *chip_hpm = NULL;
static spi_flash_hpm_dummy_conf_t dummy_conf; static spi_flash_hpm_dummy_conf_t dummy_conf;
static bool hpm_dummy_changed = false;
esp_err_t spi_flash_enable_high_performance_mode(void) esp_err_t spi_flash_enable_high_performance_mode(void)
{ {
uint32_t flash_chip_id = g_rom_flashchip.device_id; uint32_t flash_chip_id = g_rom_flashchip.device_id;
uint32_t flash_freq = FLASH_FREQUENCY; uint32_t flash_freq = FLASH_FREQUENCY;
spi_flash_requirement_t hpm_requirement_check;
// voltage and temperature has not been implemented, just leave an interface here. Complete in the future. // voltage and temperature has not been implemented, just leave an interface here. Complete in the future.
int voltage = 0; int voltage = 0;
int temperature = 0; int temperature = 0;
@@ -242,7 +249,8 @@ esp_err_t spi_flash_enable_high_performance_mode(void)
return ret; return ret;
} }
if (chip_hpm->chip_hpm_requirement_check(flash_chip_id, flash_freq, voltage, temperature) == SPI_FLASH_HPM_NEEDED) { hpm_requirement_check = chip_hpm->chip_hpm_requirement_check(flash_chip_id, flash_freq, voltage, temperature);
if ((hpm_requirement_check == SPI_FLASH_HPM_CMD_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED)) {
ESP_EARLY_LOGI(HPM_TAG, "Enabling high speed mode for chip %s", chip_hpm->manufacturer); ESP_EARLY_LOGI(HPM_TAG, "Enabling high speed mode for chip %s", chip_hpm->manufacturer);
chip_hpm->flash_hpm_enable(); chip_hpm->flash_hpm_enable();
ESP_EARLY_LOGD(HPM_TAG, "Checking whether HPM has been executed"); ESP_EARLY_LOGD(HPM_TAG, "Checking whether HPM has been executed");
@@ -251,7 +259,8 @@ esp_err_t spi_flash_enable_high_performance_mode(void)
ESP_EARLY_LOGE(HPM_TAG, "Flash high performance mode hasn't been executed successfully"); ESP_EARLY_LOGE(HPM_TAG, "Flash high performance mode hasn't been executed successfully");
return ESP_FAIL; return ESP_FAIL;
} }
} else if (chip_hpm->chip_hpm_requirement_check(flash_chip_id, flash_freq, voltage, temperature) == SPI_FLASH_HPM_BEYOND_LIMIT) { hpm_dummy_changed = (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) ? true : false;
} else if (hpm_requirement_check == SPI_FLASH_HPM_BEYOND_LIMIT) {
ESP_EARLY_LOGE(HPM_TAG, "Flash does not have the ability to raise to that frequency"); ESP_EARLY_LOGE(HPM_TAG, "Flash does not have the ability to raise to that frequency");
return ESP_FAIL; return ESP_FAIL;
} }
@@ -263,3 +272,8 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void)
chip_hpm->flash_get_dummy(&dummy_conf); chip_hpm->flash_get_dummy(&dummy_conf);
return &dummy_conf; return &dummy_conf;
} }
bool spi_flash_hpm_dummy_adjust(void)
{
return hpm_dummy_changed;
}