Merge branch 'bugfix/wait_tvsl_after_non_pd_top_lightsleep_for_esp32c6' into 'master'

fix(esp_hw_support/sleep): wait flash ready after non-pd_top lightsleep for esp32c6

Closes IDF-6930

See merge request espressif/esp-idf!27726
This commit is contained in:
Jiang Jiang Jian 2023-12-19 14:01:45 +08:00
commit 73de93d55e
10 changed files with 70 additions and 34 deletions

View File

@ -141,24 +141,34 @@ menu "Hardware Settings"
This option provides a software workaround for this issue. Configure to isolate all This option provides a software workaround for this issue. Configure to isolate all
GPIO pins in sleep state. GPIO pins in sleep state.
config ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY config ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
int "Extra delay in deep sleep wake stub (in us)" int "Extra delay (in us) after flash powerdown sleep wakeup to wait flash ready"
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 default 2000 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
default 2000 default 0
range 0 5000 range 0 5000
help help
When the chip exits deep sleep, the CPU and the flash chip are powered on When the chip exits sleep, the CPU and the flash chip are powered on at the same time.
at the same time. CPU will run deep sleep stub first, and then CPU will run rom code (deepsleep) or ram code (lightsleep) first, and then load or execute
proceed to load code from flash. Some flash chips need sufficient code from flash.
time to pass between power on and first read operation. By default,
without any extra delay, this time is approximately 900us, although Some flash chips need sufficient time to pass between power on and first read operation.
By default, without any extra delay, this time is approximately 900us, although
some flash chip types need more than that. some flash chip types need more than that.
By default extra delay is set to 2000us. When optimizing startup time (!!! Please adjust this value according to the Data Sheet of SPI Flash used in your project.)
In Flash Data Sheet, the parameters that define the Flash ready timing after power-up (minimum
time from Vcc(min) to CS activeare) usually named tVSL in ELECTRICAL CHARACTERISTICS chapter,
and the configuration value here should be:
ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY = tVSL - 900
For esp32 and esp32s3, the default extra delay is set to 2000us. When optimizing startup time
for applications which require it, this value may be reduced. for applications which require it, this value may be reduced.
If you are seeing "flash read err, 1000" message printed to the If you are seeing "flash read err, 1000" message printed to the console after deep sleep reset
console after deep sleep reset, try increasing this value. on esp32, or triggered RTC_WDT/LP_WDT after lightsleep wakeup, try increasing this value.
(For esp32, the delay will be executed in both deep sleep and light sleep wake up flow.
For chips after esp32, the delay will be executed only in light sleep flow, the delay
controlled by the EFUSE_FLASH_TPUW in ROM will be executed in deepsleep wake up flow.)
config ESP_SLEEP_CACHE_SAFE_ASSERTION config ESP_SLEEP_CACHE_SAFE_ASSERTION
bool "Check the cache safety of the sleep wakeup code in sleep process" bool "Check the cache safety of the sleep wakeup code in sleep process"

View File

@ -291,6 +291,11 @@ void pmu_init(void);
*/ */
void pmu_sleep_enable_hp_sleep_sysclk(bool enable); void pmu_sleep_enable_hp_sleep_sysclk(bool enable);
/**
* Get the time overhead used by regdma to work on the retention link during the hardware wake-up process
* @return regdma time cost during hardware wake-up stage in microseconds
*/
uint32_t pmu_sleep_get_wakup_retention_cost(void);
#endif //#if SOC_PMU_SUPPORTED #endif //#if SOC_PMU_SUPPORTED

View File

@ -286,3 +286,8 @@ void pmu_sleep_enable_hp_sleep_sysclk(bool enable)
{ {
pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable); pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable);
} }
uint32_t pmu_sleep_get_wakup_retention_cost(void)
{
return PMU_REGDMA_S2A_WORK_TIME_US;
}

View File

@ -44,6 +44,8 @@ extern "C" {
#define PMU_HP_XPD_DEEPSLEEP 0 #define PMU_HP_XPD_DEEPSLEEP 0
#define PMU_LP_DRVB_DEEPSLEEP 0 #define PMU_LP_DRVB_DEEPSLEEP 0
#define PMU_REGDMA_S2A_WORK_TIME_US 480
#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 #define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12
#define PMU_LP_DBIAS_DEEPSLEEP_0V7 23 #define PMU_LP_DBIAS_DEEPSLEEP_0V7 23
@ -456,7 +458,7 @@ typedef struct pmu_sleep_machine_constant {
.power_supply_wait_time_us = 2, \ .power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \ .power_up_wait_time_us = 2, \
.regdma_s2m_work_time_us = 172, \ .regdma_s2m_work_time_us = 172, \
.regdma_s2a_work_time_us = 480, \ .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
.regdma_m2a_work_time_us = 278, \ .regdma_m2a_work_time_us = 278, \
.regdma_a2s_work_time_us = 382, \ .regdma_a2s_work_time_us = 382, \
.regdma_rf_on_work_time_us = 70, \ .regdma_rf_on_work_time_us = 70, \

View File

@ -228,3 +228,8 @@ bool pmu_sleep_finish(void)
{ {
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
} }
uint32_t pmu_sleep_get_wakup_retention_cost(void)
{
return PMU_REGDMA_S2A_WORK_TIME_US;
}

View File

@ -41,6 +41,8 @@ extern "C" {
#define PMU_HP_DBIAS_LIGHTSLEEP_0V6 1 #define PMU_HP_DBIAS_LIGHTSLEEP_0V6 1
#define PMU_LP_DBIAS_LIGHTSLEEP_0V7 6 #define PMU_LP_DBIAS_LIGHTSLEEP_0V7 6
#define PMU_REGDMA_S2A_WORK_TIME_US 0
// FOR DEEPSLEEP // FOR DEEPSLEEP
#define PMU_HP_XPD_DEEPSLEEP 0 #define PMU_HP_XPD_DEEPSLEEP 0
#define PMU_LP_DRVB_DEEPSLEEP 7 #define PMU_LP_DRVB_DEEPSLEEP 7
@ -438,7 +440,7 @@ typedef struct pmu_sleep_machine_constant {
.analog_wait_time_us = 154, \ .analog_wait_time_us = 154, \
.power_supply_wait_time_us = 2, \ .power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \ .power_up_wait_time_us = 2, \
.regdma_s2a_work_time_us = 0, \ .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
.regdma_a2s_work_time_us = 0, \ .regdma_a2s_work_time_us = 0, \
.xtal_wait_stable_time_us = 250, \ .xtal_wait_stable_time_us = 250, \
.pll_wait_stable_time_us = 1 \ .pll_wait_stable_time_us = 1 \

View File

@ -21,7 +21,8 @@ CONFIG_SPIRAM_SUPPORT CONFIG_SPIRAM
CONFIG_ESP32_SPIRAM_SUPPORT CONFIG_SPIRAM CONFIG_ESP32_SPIRAM_SUPPORT CONFIG_SPIRAM
CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP
CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
CONFIG_ESP32_XTAL_FREQ_26 CONFIG_XTAL_FREQ_26 CONFIG_ESP32_XTAL_FREQ_26 CONFIG_XTAL_FREQ_26
CONFIG_ESP32_XTAL_FREQ_40 CONFIG_XTAL_FREQ_40 CONFIG_ESP32_XTAL_FREQ_40 CONFIG_XTAL_FREQ_40

View File

@ -10,4 +10,5 @@ CONFIG_ESP32S3_RTC_XTAL_CAL_RETRY CONFIG_RTC_XTAL_CAL_RE
CONFIG_ESP32S3_SPIRAM_SUPPORT CONFIG_SPIRAM CONFIG_ESP32S3_SPIRAM_SUPPORT CONFIG_SPIRAM
CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY

View File

@ -106,8 +106,8 @@
// If light sleep time is less than that, don't power down flash // If light sleep time is less than that, don't power down flash
#define FLASH_PD_MIN_SLEEP_TIME_US 2000 #define FLASH_PD_MIN_SLEEP_TIME_US 2000
// Time from VDD_SDIO power up to first flash read in ROM code // Default waiting time for the software to wait for Flash ready after waking up from sleep
#define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700 #define ESP_SLEEP_WAIT_FLASH_READY_DEFAULT_DELAY_US 700
// Cycles for RTC Timer clock source (internal oscillator) calibrate // Cycles for RTC Timer clock source (internal oscillator) calibrate
#define RTC_CLK_SRC_CAL_CYCLES (10) #define RTC_CLK_SRC_CAL_CYCLES (10)
@ -156,12 +156,6 @@
#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ)
#endif #endif
#if CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
#define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
#else
#define DEEP_SLEEP_WAKEUP_DELAY 0
#endif
// Minimal amount of time we can sleep for // Minimal amount of time we can sleep for
#define LIGHT_SLEEP_MIN_TIME_US 200 #define LIGHT_SLEEP_MIN_TIME_US 200
@ -358,13 +352,16 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
_DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR); _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR);
_DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG,
_DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR)); _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR));
#if DEEP_SLEEP_WAKEUP_DELAY > 0 #if CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY > 0
// ROM code has not started yet, so we need to set delay factor // ROM code has not started yet, so we need to set delay factor
// used by esp_rom_delay_us first. // used by esp_rom_delay_us first.
ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000); ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000);
// This delay is configured in menuconfig, it can be used to give // Time from VDD_SDIO power up to first flash read in ROM code is 700 us,
// the flash chip some time to become ready. // for some flash chips is not sufficient, this delay is configured in menuconfig,
esp_rom_delay_us(DEEP_SLEEP_WAKEUP_DELAY); // it can be used to give the flash chip some extra time to become ready.
// For later chips, we have EFUSE_FLASH_TPUW field to configure it and do
// this delay in the ROM.
esp_rom_delay_us(CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY);
#endif #endif
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN); REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN);
@ -1043,6 +1040,18 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
// If SPI flash was powered down, wait for it to become ready // If SPI flash was powered down, wait for it to become ready
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
#if SOC_PM_SUPPORT_TOP_PD
if (pd_flags & PMU_SLEEP_PD_TOP) {
uint32_t flash_ready_hw_waited_time_us = pmu_sleep_get_wakup_retention_cost();
uint32_t flash_ready_sw_waited_time_us = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / MHZ);
uint32_t flash_ready_waited_time_us = flash_ready_hw_waited_time_us + flash_ready_sw_waited_time_us;
if (flash_enable_time_us > flash_ready_waited_time_us){
flash_enable_time_us -= flash_ready_waited_time_us;
} else {
flash_enable_time_us = 0;
}
}
#endif
// Wait for the flash chip to start up // Wait for the flash chip to start up
esp_rom_delay_us(flash_enable_time_us); esp_rom_delay_us(flash_enable_time_us);
} }
@ -1155,12 +1164,9 @@ esp_err_t esp_light_sleep_start(void)
+ rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period); + rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period);
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-6930
const uint32_t flash_enable_time_us = 0;
#else
// Decide if VDD_SDIO needs to be powered down; // Decide if VDD_SDIO needs to be powered down;
// If it needs to be powered down, adjust sleep time. // If it needs to be powered down, adjust sleep time.
const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY; const uint32_t flash_enable_time_us = ESP_SLEEP_WAIT_FLASH_READY_DEFAULT_DELAY_US + CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY;
/** /**
* If VDD_SDIO power domain is requested to be turned off, bit `RTC_SLEEP_PD_VDDSDIO` * If VDD_SDIO power domain is requested to be turned off, bit `RTC_SLEEP_PD_VDDSDIO`
@ -1199,7 +1205,6 @@ esp_err_t esp_light_sleep_start(void)
} }
} }
} }
#endif
periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in); periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in);

View File

@ -184,7 +184,7 @@ CONFIG_RTC_CLK_SRC_INT_RC=y
CONFIG_RTC_CLK_SRC_EXT_CRYS= CONFIG_RTC_CLK_SRC_EXT_CRYS=
CONFIG_RTC_CLK_CAL_CYCLES=1024 CONFIG_RTC_CLK_CAL_CYCLES=1024
CONFIG_RTC_XTAL_BOOTSTRAP_CYCLES=100 CONFIG_RTC_XTAL_BOOTSTRAP_CYCLES=100
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000
CONFIG_XTAL_FREQ_40=y CONFIG_XTAL_FREQ_40=y
CONFIG_XTAL_FREQ_26= CONFIG_XTAL_FREQ_26=
CONFIG_XTAL_FREQ_AUTO= CONFIG_XTAL_FREQ_AUTO=