From f28f75a46bc14c0e88b394a2625871fba4ae3292 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 23 Aug 2022 18:53:37 +0800 Subject: [PATCH] spi_flash: Add several flash chips HPM(120M) support --- .../bootloader_flash_priv.h | 1 + components/esptool_py/Kconfig.projbuild | 1 + components/spi_flash/Kconfig | 7 + .../spi_flash/esp32s3/spi_timing_config.c | 2 + components/spi_flash/esp_flash_spi_init.c | 7 + components/spi_flash/include/esp_flash.h | 3 +- .../include/esp_private/spi_flash_os.h | 11 +- .../include/spi_flash/spi_flash_defs.h | 2 + .../spi_flash/include/spi_flash_override.h | 6 +- components/spi_flash/spi_flash_chip_generic.c | 24 +++- components/spi_flash/spi_flash_hpm_enable.c | 121 ++++++++++++++---- 11 files changed, 146 insertions(+), 39 deletions(-) diff --git a/components/bootloader_support/include_bootloader/bootloader_flash_priv.h b/components/bootloader_support/include_bootloader/bootloader_flash_priv.h index b83e945ca0..5639da4050 100644 --- a/components/bootloader_support/include_bootloader/bootloader_flash_priv.h +++ b/components/bootloader_support/include_bootloader/bootloader_flash_priv.h @@ -26,6 +26,7 @@ #define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */ #define CMD_WRSR3 0x11 /* Not all SPI flash uses this command */ #define CMD_WREN 0x06 +#define CMD_WRENVSR 0x50 /* Flash write enable for volatile SR bits */ #define CMD_WRDI 0x04 #define CMD_RDSR 0x05 #define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */ diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 3c54a1f534..dad043f7fd 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -128,6 +128,7 @@ menu "Serial flasher config" config ESPTOOLPY_FLASHFREQ_120M depends on IDF_TARGET_ESP32S3 && ESPTOOLPY_FLASH_SAMPLE_MODE_STR bool "120 MHz" + select SPI_FLASH_HPM_ENABLE config ESPTOOLPY_FLASHFREQ_80M bool "80 MHz" config ESPTOOLPY_FLASHFREQ_40M diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 9a56da7604..89410b4acb 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -279,4 +279,11 @@ menu "SPI Flash driver" 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. + 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 diff --git a/components/spi_flash/esp32s3/spi_timing_config.c b/components/spi_flash/esp32s3/spi_timing_config.c index 6dabaffc62..978f4ebcb3 100644 --- a/components/spi_flash/esp32s3/spi_timing_config.c +++ b/components/spi_flash/esp32s3/spi_timing_config.c @@ -13,6 +13,8 @@ #include "esp_log.h" #include "soc/spi_mem_reg.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_WRITE 0x8080 diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 8fce5a47de..aaac870284 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -331,6 +331,13 @@ esp_err_t esp_flash_init_default_chip(void) return err; } #endif + +#if CONFIG_SPI_FLASH_HPM_ENABLE + if (spi_flash_hpm_dummy_adjust()) { + default_chip.hpm_dummy_ena = 1; + } +#endif + return ESP_OK; } diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index c5adb279dc..3529898bce 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -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 chip_id; ///< Detected chip id. 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. }; diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/spi_flash/include/esp_private/spi_flash_os.h index ed8adba74d..f2a89112eb 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -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. * @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 } diff --git a/components/spi_flash/include/spi_flash/spi_flash_defs.h b/components/spi_flash/include/spi_flash/spi_flash_defs.h index 2f4984207d..b248b24dcd 100644 --- a/components/spi_flash/include/spi_flash/spi_flash_defs.h +++ b/components/spi_flash/include/spi_flash/spi_flash_defs.h @@ -65,3 +65,5 @@ #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 diff --git a/components/spi_flash/include/spi_flash_override.h b/components/spi_flash/include/spi_flash_override.h index 1ca92d5cdf..7f01576dee 100644 --- a/components/spi_flash/include/spi_flash_override.h +++ b/components/spi_flash/include/spi_flash_override.h @@ -27,7 +27,9 @@ typedef struct { } spi_flash_hpm_dummy_conf_t; 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_BEYOND_LIMIT, // Means that flash has no capability to meet that condition. } 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)) { - const char *manufacturer; /* Flash vendor */ + const char *method; /* Flash HPM method */ spi_flash_hpm_probe_fn_t probe; spi_flash_hpm_chip_requirement_check_t chip_hpm_requirement_check; spi_flash_hpm_enable_fn_t flash_hpm_enable; diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index c1173c9b83..ea7d766937 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -40,6 +40,16 @@ DRAM_ATTR const static flash_chip_dummy_t default_flash_chip_dummy = { .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. DRAM_ATTR static spi_flash_encryption_t esp_flash_encryption_default __attribute__((__unused__)) = { .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_hpm = (flash_chip_dummy_t *)&hpm_flash_chip_dummy; + #define SPI_FLASH_DEFAULT_IDLE_TIMEOUT_MS 200 #define SPI_FLASH_GENERIC_CHIP_ERASE_TIMEOUT_MS 4000 #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: //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; - 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); conf_required = true; break; case SPI_FLASH_QOUT: 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); break; 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. 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); conf_required = true; break; case SPI_FLASH_DOUT: 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); break; case SPI_FLASH_FASTRD: 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); break; case SPI_FLASH_SLOWRD: 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); break; default: diff --git a/components/spi_flash/spi_flash_hpm_enable.c b/components/spi_flash/spi_flash_hpm_enable.c index 47235a5c19..5d11f532b7 100644 --- a/components/spi_flash/spi_flash_hpm_enable.c +++ b/components/spi_flash/spi_flash_hpm_enable.c @@ -49,6 +49,8 @@ extern uint32_t bootloader_flash_execute_command_common( extern unsigned bootloader_read_status_8b_rdsr3(void); 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-----------------------// /** @@ -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) { esp_err_t ret = ESP_OK; + uint32_t gd_sfdp = 0; switch (flash_id) { /* The flash listed here should enter the HPM with command 0xA3 */ case 0xC84016: case 0xC84017: - break; + // 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; + } else { + ret = ESP_ERR_NOT_FOUND; + break; + } default: ret = ESP_ERR_NOT_FOUND; break; @@ -76,18 +86,10 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_cmd (void)voltage_mv; (void)temperautre; 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) { - chip_cap = SPI_FLASH_HPM_NEEDED; - } - break; - default: - chip_cap = SPI_FLASH_HPM_UNNEEDED; - break; + if (freq_mhz > 80) { + chip_cap = SPI_FLASH_HPM_CMD_NEEDED; } + ESP_EARLY_LOGD(HPM_TAG, "HPM with command, status is %d", 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) { esp_err_t ret = ESP_OK; + uint32_t gd_sfdp = 0; switch (flash_id) { /* 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: ret = ESP_ERR_NOT_FOUND; break; @@ -140,17 +154,11 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_dum (void)voltage_mv; (void)temperautre; 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) { - chip_cap = SPI_FLASH_HPM_NEEDED; - } - break; - default: - chip_cap = SPI_FLASH_HPM_UNNEEDED; - break; + + if (freq_mhz >= 104) { + chip_cap = SPI_FLASH_HPM_DUMMY_NEEDED; } + ESP_EARLY_LOGD(HPM_TAG, "HPM with dummy, status is %d", 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 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); 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; } +//-----------------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-------------------------------------// @@ -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[] = { /* 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 }, - { "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}, + { "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 }, + { "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. { "NULL", NULL, NULL, NULL, NULL, spi_flash_hpm_get_dummy_generic}, }; static const spi_flash_hpm_info_t *chip_hpm = NULL; 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) { uint32_t flash_chip_id = g_rom_flashchip.device_id; 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. int voltage = 0; int temperature = 0; @@ -243,8 +301,9 @@ esp_err_t spi_flash_enable_high_performance_mode(void) return ret; } - if (chip_hpm->chip_hpm_requirement_check(flash_chip_id, flash_freq, voltage, temperature) == SPI_FLASH_HPM_NEEDED) { - ESP_EARLY_LOGI(HPM_TAG, "Enabling high speed mode for chip %s", chip_hpm->manufacturer); + 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) || (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(); 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"); 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"); 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); return &dummy_conf; } + +bool spi_flash_hpm_dummy_adjust(void) +{ + return hpm_dummy_changed; +}