fix(spi_flash): Fix esp32p4 120m flash suspend failed

This commit is contained in:
C.S.M
2026-04-07 18:06:40 +08:00
parent e46782886f
commit a033efcb3d
18 changed files with 228 additions and 21 deletions
+68 -2
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -221,6 +221,71 @@ static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf)
dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
}
/**
* @brief Probe the chip whether adjust dummy (bit3,4) to enable HPM mode. Take XMC as an example:
* Adjust dummy bits to enable HPM mode of the flash. If XMC works under 80MHz, the dummy bits
* might be 6, but when works under 120MHz, the dummy bits might be 10.
*/
static esp_err_t spi_flash_hpm_probe_chip_with_dummy_bit3_4(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 */
// XMC chips.
case 0x204019:
case 0x204020:
break;
default:
ret = ESP_ERR_NOT_FOUND;
break;
}
return ret;
}
static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_dummy_bit3_4(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_DUMMY_NEEDED;
}
ESP_EARLY_LOGD(HPM_TAG, "HPM with dummy bit3,4, status is %d", chip_cap);
return chip_cap;
}
/**
* @brief Adjust dummy cycles. This function modifies the Dummy Cycle Bits in SR3.
* Usually, the bits are at bit-0, bit-1, sr-3 and set DC[1:0]=[1,1].
*
* @note Don't forget to adjust dummy configurations for MSPI, you can get the
* correct dummy from interface `spi_flash_hpm_get_dummy`.
*/
static void spi_flash_turn_high_performance_dummy_bit3_4(void)
{
uint8_t old_status_3 = bootloader_read_status_8b_rdsr3();
uint8_t new_status = (old_status_3 | 0x18);
bootloader_execute_flash_command(CMD_WRENVSR, 0, 0, 0);
bootloader_write_status_8b_wrsr3(new_status);
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
}
/**
* @brief Check whether HPM has been enabled. This function checks the DC bits
*/
static esp_err_t spi_flash_high_performance_check_dummy_bit3_4(void)
{
if((bootloader_read_status_8b_rdsr3() & 0x18) == 0) {
return ESP_FAIL;
}
return ESP_OK;
}
#elif !CONFIG_SPI_FLASH_HPM_DC_DISABLE
//This is because bootloader doesn't support this
@@ -316,9 +381,10 @@ 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 */
{ "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 },
#if CONFIG_SPI_FLASH_HPM_DC_ON
{ "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},
{ "dummy sr3-bit01", 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},
#endif //CONFIG_SPI_FLASH_HPM_DC_ON
{ "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},
{ "dummy sr3-bit3_4", spi_flash_hpm_probe_chip_with_dummy_bit3_4, spi_flash_hpm_chip_hpm_requirement_check_with_dummy_bit3_4, spi_flash_turn_high_performance_dummy_bit3_4, spi_flash_high_performance_check_dummy_bit3_4, spi_flash_hpm_get_dummy_xmc},
{ "noting-to-do", spi_flash_hpm_probe_chip_with_doing_nothing, spi_flash_hpm_chip_hpm_requirement_check_with_doing_nothing, NULL, NULL, 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},
@@ -1,5 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs, data, nvs, 0x9000, 0x6000,
factory, 0, 0, 0x10000, 1M
nvs, data, nvs, 0xb000, 0x6000,
factory, 0, 0, , 1M
flash_test, data, fat, , 700K
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3 nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, 0xb000, 0x6000,
4 factory, 0, 0, 0x10000, 1M factory, 0, 0, , 1M
5 flash_test, data, fat, , 700K
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut
@@ -62,3 +62,19 @@ def test_esp_flash_multi(dut: Dut) -> None:
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
def test_esp_flash_26mhz_c2(dut: Dut) -> None:
dut.run_all_single_board_cases(group='esp_flash')
@pytest.mark.flash_32m
@pytest.mark.parametrize(
'config',
[
'p4_32m_120m_qio_map',
'p4_32m_120m_dio_map',
'p4_32m_120m_qio',
'p4_32m_120m_dio',
],
indirect=True,
)
@idf_parametrize('target', ['esp32p4'], indirect=['target'])
def test_esp_flash_32m_p4(dut: Dut) -> None:
dut.run_all_single_board_cases(group='esp_flash')
@@ -0,0 +1,12 @@
CONFIG_IDF_TARGET="esp32p4"
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_SPI_FLASH_HPM_DC_AUTO=y
CONFIG_SPI_FLASH_HPM_DC_ON=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
CONFIG_PARTITION_TABLE_OFFSET=0xa000
@@ -0,0 +1,13 @@
CONFIG_IDF_TARGET="esp32p4"
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_SPI_FLASH_HPM_DC_AUTO=y
CONFIG_SPI_FLASH_HPM_DC_ON=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
CONFIG_PARTITION_TABLE_OFFSET=0xa000
CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH=y
@@ -0,0 +1,12 @@
CONFIG_IDF_TARGET="esp32p4"
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_SPI_FLASH_HPM_DC_AUTO=y
CONFIG_SPI_FLASH_HPM_DC_ON=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_PARTITION_TABLE_OFFSET=0xa000
@@ -0,0 +1,13 @@
CONFIG_IDF_TARGET="esp32p4"
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_SPI_FLASH_HPM_DC_AUTO=y
CONFIG_SPI_FLASH_HPM_DC_ON=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_PARTITION_TABLE_OFFSET=0xa000
CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH=y