spi_flash: Add several flash chips HPM(120M) support

This commit is contained in:
Cao Sen Miao
2022-08-23 18:53:37 +08:00
parent b0c38d5392
commit f28f75a46b
11 changed files with 146 additions and 39 deletions

View File

@@ -26,6 +26,7 @@
#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 */

View File

@@ -128,6 +128,7 @@ menu "Serial flasher config"
config ESPTOOLPY_FLASHFREQ_120M config ESPTOOLPY_FLASHFREQ_120M
depends on IDF_TARGET_ESP32S3 && ESPTOOLPY_FLASH_SAMPLE_MODE_STR depends on IDF_TARGET_ESP32S3 && ESPTOOLPY_FLASH_SAMPLE_MODE_STR
bool "120 MHz" bool "120 MHz"
select SPI_FLASH_HPM_ENABLE
config ESPTOOLPY_FLASHFREQ_80M config ESPTOOLPY_FLASHFREQ_80M
bool "80 MHz" bool "80 MHz"
config ESPTOOLPY_FLASHFREQ_40M config ESPTOOLPY_FLASHFREQ_40M

View File

@@ -279,4 +279,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,8 @@
#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"
#include "spi_flash_override.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

View File

@@ -331,6 +331,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

@@ -103,7 +103,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

@@ -151,9 +151,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);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -65,3 +65,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,9 @@ 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_WRITE_SR_NEEDED, // Means that in the certain condition, flash needs to enter the high performance mode by writing status register.
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;
@@ -40,7 +42,7 @@ typedef spi_flash_requirement_t (*spi_flash_hpm_chip_requirement_check_t)(uint32
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
const char *manufacturer; /* Flash vendor */ const char *method; /* Flash HPM method */
spi_flash_hpm_probe_fn_t probe; spi_flash_hpm_probe_fn_t probe;
spi_flash_hpm_chip_requirement_check_t chip_hpm_requirement_check; spi_flash_hpm_chip_requirement_check_t chip_hpm_requirement_check;
spi_flash_hpm_enable_fn_t flash_hpm_enable; spi_flash_hpm_enable_fn_t flash_hpm_enable;

View File

@@ -40,6 +40,16 @@ 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,
};
// 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,
@@ -52,6 +62,8 @@ DRAM_ATTR static spi_flash_encryption_t esp_flash_encryption_default __attribute
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 = (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;
#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
@@ -462,35 +474,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

@@ -49,6 +49,8 @@ extern uint32_t bootloader_flash_execute_command_common(
extern unsigned bootloader_read_status_8b_rdsr3(void); extern unsigned bootloader_read_status_8b_rdsr3(void);
extern void bootloader_write_status_8b_wrsr3(unsigned new_status); extern void bootloader_write_status_8b_wrsr3(unsigned new_status);
extern uint32_t IRAM_ATTR bootloader_flash_read_sfdp(uint32_t sfdp_addr, unsigned int miso_byte_num);
//-----------------For flash chips which enter HPM via command-----------------------// //-----------------For flash chips which enter HPM via command-----------------------//
/** /**
@@ -58,11 +60,19 @@ extern void bootloader_write_status_8b_wrsr3(unsigned new_status);
static esp_err_t spi_flash_hpm_probe_chip_with_cmd(uint32_t flash_id) static esp_err_t spi_flash_hpm_probe_chip_with_cmd(uint32_t flash_id)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
uint32_t gd_sfdp = 0;
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 0xC84016: case 0xC84016:
case 0xC84017: case 0xC84017:
// Read BYTE4 in SFDP, 0 means C series, 6 means E series
gd_sfdp = bootloader_flash_read_sfdp(0x4, 1);
if (gd_sfdp == 0x0) {
break; break;
} else {
ret = ESP_ERR_NOT_FOUND;
break;
}
default: default:
ret = ESP_ERR_NOT_FOUND; ret = ESP_ERR_NOT_FOUND;
break; break;
@@ -76,18 +86,10 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_cmd
(void)voltage_mv; (void)voltage_mv;
(void)temperautre; (void)temperautre;
spi_flash_requirement_t chip_cap = SPI_FLASH_HPM_UNNEEDED; spi_flash_requirement_t chip_cap = SPI_FLASH_HPM_UNNEEDED;
switch (flash_id) {
/* The flash listed here should enter the HPM with command 0xA3 */
case 0xC84016:
case 0xC84017:
if (freq_mhz > 80) { if (freq_mhz > 80) {
chip_cap = SPI_FLASH_HPM_NEEDED; chip_cap = SPI_FLASH_HPM_CMD_NEEDED;
}
break;
default:
chip_cap = SPI_FLASH_HPM_UNNEEDED;
break;
} }
ESP_EARLY_LOGD(HPM_TAG, "HPM with command, status is %d", chip_cap);
return chip_cap; return chip_cap;
} }
@@ -125,8 +127,20 @@ static esp_err_t spi_flash_high_performance_check_hpf_bit_5(void)
static esp_err_t spi_flash_hpm_probe_chip_with_dummy(uint32_t flash_id) 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;
uint32_t gd_sfdp = 0;
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 */
// GD chips.
case 0xC84017:
case 0xC84018:
// Read BYTE4 in SFDP, 0 means C series, 6 means E series
gd_sfdp = bootloader_flash_read_sfdp(0x4, 1);
if (gd_sfdp == 0x6) {
break;
} else {
ret = ESP_ERR_NOT_FOUND;
break;
}
default: default:
ret = ESP_ERR_NOT_FOUND; ret = ESP_ERR_NOT_FOUND;
break; break;
@@ -140,17 +154,11 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_dum
(void)voltage_mv; (void)voltage_mv;
(void)temperautre; (void)temperautre;
spi_flash_requirement_t chip_cap = SPI_FLASH_HPM_UNNEEDED; spi_flash_requirement_t chip_cap = SPI_FLASH_HPM_UNNEEDED;
switch (flash_id) {
/* The flash listed here should enter the HPM with command 0xA3 */
case 0x204017:
if (freq_mhz >= 104) { if (freq_mhz >= 104) {
chip_cap = SPI_FLASH_HPM_NEEDED; chip_cap = SPI_FLASH_HPM_DUMMY_NEEDED;
}
break;
default:
chip_cap = SPI_FLASH_HPM_UNNEEDED;
break;
} }
ESP_EARLY_LOGD(HPM_TAG, "HPM with dummy, status is %d", chip_cap);
return chip_cap; return chip_cap;
} }
@@ -165,7 +173,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);
} }
@@ -190,6 +198,53 @@ static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf)
dummy_conf->fastrd_dummy = 8; dummy_conf->fastrd_dummy = 8;
} }
//-----------------For flash chips which enter HPM via write status register-----------------------//
/**
* @brief Probe the chip whether to write status register to enable HPM mode. Take ZB as an example:
* Write status register bits to enable HPM mode of the flash. If ZB works under 80MHz, the register value
* would be 0, but when works under 120MHz, the register value would be 1.
*/
static esp_err_t spi_flash_hpm_probe_chip_with_write_hpf_bit_5(uint32_t flash_id)
{
esp_err_t ret = ESP_OK;
switch (flash_id) {
/* The flash listed here should enter the HPM by adjusting dummy cycles */
// ZB chips.
case 0x5E4016:
break;
default:
ret = ESP_ERR_NOT_FOUND;
break;
}
return ret;
}
static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_write_hpf_bit_5(uint32_t flash_id, uint32_t freq_mhz, int voltage_mv, int temperautre)
{
// voltage and temperature are not been used now, to be completed in the future.
(void)voltage_mv;
(void)temperautre;
spi_flash_requirement_t chip_cap = SPI_FLASH_HPM_UNNEEDED;
if (freq_mhz >= 104) {
chip_cap = SPI_FLASH_HPM_WRITE_SR_NEEDED;
}
ESP_EARLY_LOGD(HPM_TAG, "HPM with dummy, status is %d", chip_cap);
return chip_cap;
}
/**
* @brief Write bit 5 in status 3
*/
static void spi_flash_turn_high_performance_write_hpf_bit_5(void)
{
uint8_t old_status_3 = bootloader_read_status_8b_rdsr3();
uint8_t new_status = (old_status_3 | 0x10);
bootloader_execute_flash_command(CMD_WRENVSR, 0, 0, 0);
bootloader_write_status_8b_wrsr3(new_status);
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
}
//-----------------------generic functions-------------------------------------// //-----------------------generic functions-------------------------------------//
@@ -208,19 +263,22 @@ void __attribute__((weak)) spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_c
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[] = {
/* vendor, chip_id, freq_threshold, temperature threshold, operation for setting high performance, reading HPF status, get dummy */ /* vendor, chip_id, freq_threshold, temperature threshold, operation for setting high performance, reading HPF status, get dummy */
{ "GD", spi_flash_hpm_probe_chip_with_cmd, spi_flash_hpm_chip_hpm_requirement_check_with_cmd, spi_flash_enable_high_performance_send_cmd, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic }, { "command", spi_flash_hpm_probe_chip_with_cmd, spi_flash_hpm_chip_hpm_requirement_check_with_cmd, spi_flash_enable_high_performance_send_cmd, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic },
{ "XMC", spi_flash_hpm_probe_chip_with_dummy, spi_flash_hpm_chip_hpm_requirement_check_with_dummy, spi_flash_turn_high_performance_reconfig_dummy, spi_flash_high_performance_check_dummy_sr, spi_flash_hpm_get_dummy_xmc}, { "dummy", spi_flash_hpm_probe_chip_with_dummy, spi_flash_hpm_chip_hpm_requirement_check_with_dummy, spi_flash_turn_high_performance_reconfig_dummy, spi_flash_high_performance_check_dummy_sr, spi_flash_hpm_get_dummy_xmc},
{ "write sr3-bit5", spi_flash_hpm_probe_chip_with_write_hpf_bit_5, spi_flash_hpm_chip_hpm_requirement_check_with_write_hpf_bit_5, spi_flash_turn_high_performance_write_hpf_bit_5, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic},
// default: do nothing, but keep the dummy get function. The first item with NULL as its probe will be the fallback. // default: do nothing, but keep the dummy get function. The first item with NULL as its probe will be the fallback.
{ "NULL", NULL, NULL, NULL, NULL, spi_flash_hpm_get_dummy_generic}, { "NULL", NULL, NULL, NULL, NULL, spi_flash_hpm_get_dummy_generic},
}; };
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;
@@ -243,8 +301,9 @@ 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);
ESP_EARLY_LOGI(HPM_TAG, "Enabling high speed mode for chip %s", chip_hpm->manufacturer); if ((hpm_requirement_check == SPI_FLASH_HPM_CMD_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_WRITE_SR_NEEDED)) {
ESP_EARLY_LOGI(HPM_TAG, "Enabling flash high speed mode by %s", chip_hpm->method);
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");
@@ -252,7 +311,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;
} }
@@ -264,3 +324,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;
}