Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_psram_access_faild_after_pd_cpu_wakeup' into…
Browse files Browse the repository at this point in the history
… 'master'

fix(esp_pm): fix psram access failed after pd_cpu wakeup if uart driver driven console is used

Closes WIFIBUG-238

See merge request espressif/esp-idf!27020
  • Loading branch information
esp-wzh committed Nov 14, 2023
2 parents 97e33fb + 59ad88d commit bb95f9b
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 20 deletions.
10 changes: 5 additions & 5 deletions components/esp_hw_support/sleep_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention;

#if SOC_PM_SUPPORT_TAGMEM_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL

#if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
#if CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP
static uint32_t cache_tagmem_retention_setup(uint32_t code_seg_vaddr, uint32_t code_seg_size, uint32_t data_seg_vaddr, uint32_t data_seg_size)
{
uint32_t sets; /* i/d-cache total set counts */
Expand Down Expand Up @@ -153,11 +153,11 @@ static uint32_t cache_tagmem_retention_setup(uint32_t code_seg_vaddr, uint32_t c
* i/d-cache tagmem blocks (128 bits * 3 = 96 bits * 4) */
return (((icache_tagmem_blk_gs + dcache_tagmem_blk_gs) << 2) * 3);
}
#endif // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
#endif // CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP

static esp_err_t esp_sleep_tagmem_pd_low_init(void)
{
#if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
#if CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP
if (s_cpu_retention.retent.tagmem.link_addr == NULL) {
extern char _stext[], _etext[];
uint32_t code_start = (uint32_t)_stext;
Expand Down Expand Up @@ -186,11 +186,11 @@ static esp_err_t esp_sleep_tagmem_pd_low_init(void)
return ESP_ERR_NO_MEM;
}
}
#else // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
#else // CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP
s_cpu_retention.retent.tagmem.icache.enable = 0;
s_cpu_retention.retent.tagmem.dcache.enable = 0;
s_cpu_retention.retent.tagmem.link_addr = NULL;
#endif // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
#endif // CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP
return ESP_OK;
}

Expand Down
30 changes: 20 additions & 10 deletions components/esp_pm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,31 @@ menu "Power Management"
config PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
bool "Power down CPU in light sleep"
depends on SOC_PM_SUPPORT_CPU_PD
select PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP if ESP32S3_DATA_CACHE_16KB
select PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP if ESP32S3_DATA_CACHE_16KB
default y
help
If enabled, the CPU will be powered down in light sleep. On esp32c3 soc, enabling this
option will consume 1.68 KB of internal RAM and will reduce sleep current consumption
by about 100 uA. On esp32s3 soc, enabling this option will consume 8.58 KB of internal
RAM and will reduce sleep current consumption by about 650 uA.

config PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
bool "Power down I/D-cache tag memory in light sleep"
If enabled, the CPU will be powered down in light sleep, ESP chips supports saving and restoring CPU's running
context before and after light sleep, the feature provides applications with seamless CPU powerdowned lightsleep
without user awareness.
But this will takes up some internal memory. On esp32c3 soc, enabling this option will consume 1.68 KB of internal
RAM and will reduce sleep current consumption by about 100 uA. On esp32s3 soc, enabling this option will consume
8.58 KB of internal RAM and will reduce sleep current consumption by about 650 uA.

config PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP
bool "Restore I/D-cache tag memory after power down CPU light sleep"
depends on IDF_TARGET_ESP32S3 && PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
default y
help
If enabled, the I/D-cache tag memory will be retained in light sleep. Depending on the the
cache configuration, if this option is enabled, it will consume up to 9 KB of internal RAM.
Cache tag memory and CPU both belong to the CPU power domain. ESP chips supports saving and restoring Cache tag memory
before and after sleep, this feature supports accesses to the external memory that was cached before sleep still
be cached when the CPU wakes up from a powerdowned CPU lightsleep. This option controls the restore method for Cache
tag memory in lightsleep.
If this option is enabled, the I/D-cache tag memory will be backuped to the internal RAM before sleep and restored
upon wakeup. Depending on the the cache configuration, if this option is enabled, it will consume up to 9 KB
of internal RAM.
If this option is disabled, all cached data won't be kept after sleep, the DCache will be writeback before
sleep and invalid all cached data after sleep, all accesses to external memory(Flash/PSRAM) will be cache
missed after waking up, resulting in performance degradation due to increased memory accesses latency.

config PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
bool "Power down Digital Peripheral in light sleep (EXPERIMENTAL)"
Expand Down
2 changes: 1 addition & 1 deletion components/esp_pm/linker.lf
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,5 @@ entries:
if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y:
if PM_SLP_IRAM_OPT = y && PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y:
rtc_cntl_hal:rtc_cntl_hal_enable_cpu_retention (noflash)
if PM_SLP_IRAM_OPT = y && PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP = y:
if PM_SLP_IRAM_OPT = y && PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP = y:
rtc_cntl_hal:rtc_cntl_hal_enable_tagmem_retention (noflash)
7 changes: 4 additions & 3 deletions components/esp_pm/pm_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,11 @@ esp_err_t esp_pm_configure(const void* vconfig)
min_freq_mhz,
config->light_sleep_enable ? "ENABLED" : "DISABLED");

portENTER_CRITICAL(&s_switch_lock);
// CPU & Modem power down initialization, which must be initialized before s_light_sleep_en set true,
// to avoid entering idle and sleep in this function.
esp_pm_sleep_configure(config);

portENTER_CRITICAL(&s_switch_lock);
bool res __attribute__((unused));
res = rtc_clk_cpu_freq_mhz_to_config(max_freq_mhz, &s_cpu_freq_by_mode[PM_MODE_CPU_MAX]);
assert(res);
Expand All @@ -460,8 +463,6 @@ esp_err_t esp_pm_configure(const void* vconfig)
s_config_changed = true;
portEXIT_CRITICAL(&s_switch_lock);

esp_pm_sleep_configure(config);

return ESP_OK;
}

Expand Down
1 change: 1 addition & 0 deletions components/esp_pm/sdkconfig.rename
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# sdkconfig replacement configurations for deprecated options formatted as
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP
10 changes: 9 additions & 1 deletion components/hal/esp32s3/rtc_cntl_hal.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -68,6 +68,14 @@ void rtc_cntl_hal_enable_cpu_retention(void *addr)
);
rtc_cntl_ll_enable_cpu_retention_clock();
rtc_cntl_ll_enable_cpu_retention();
#if SOC_PM_SUPPORT_TAGMEM_PD
if (!retent->tagmem.dcache.enable) {
// Here we only need to care for the safety of the PSRAM data in the DCache.
// Since only rodata, bss, heap data may be placed in PSRAM, and these data won't be
// modified in the sleep process code after now, so it is safe to writeback here.
Cache_WriteBack_All();
}
#endif
}
}
}
Expand Down

0 comments on commit bb95f9b

Please sign in to comment.