Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_psram_access_faild_after_pd_cpu_wakeup_v4.4'…
Browse files Browse the repository at this point in the history
… into 'release/v4.4'

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

See merge request espressif/esp-idf!27056
  • Loading branch information
jack0c committed Nov 21, 2023
2 parents d6b9fab + 93d44d1 commit 5c2142e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 22 deletions.
24 changes: 17 additions & 7 deletions components/esp_pm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,28 @@ menu "Power Management"
select PM_POWER_DOWN_TAGMEM_IN_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.
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_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP
bool "Power down I/D-cache tag memory in 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_UPDATE_CCOMPARE_HLI_WORKAROUND
bool
Expand Down
29 changes: 15 additions & 14 deletions components/esp_pm/pm_impl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -292,21 +292,9 @@ esp_err_t esp_pm_configure(const void* vconfig)
min_freq_mhz,
config->light_sleep_enable ? "ENABLED" : "DISABLED");

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);
res = rtc_clk_cpu_freq_mhz_to_config(apb_max_freq, &s_cpu_freq_by_mode[PM_MODE_APB_MAX]);
assert(res);
res = rtc_clk_cpu_freq_mhz_to_config(min_freq_mhz, &s_cpu_freq_by_mode[PM_MODE_APB_MIN]);
assert(res);
s_cpu_freq_by_mode[PM_MODE_LIGHT_SLEEP] = s_cpu_freq_by_mode[PM_MODE_APB_MIN];
s_light_sleep_en = config->light_sleep_enable;
s_config_changed = true;
portEXIT_CRITICAL(&s_switch_lock);

#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_SUPPORT_CPU_PD
// must be initialized before s_light_sleep_en set true, to avoid entering idle and sleep in this function.
esp_err_t ret = esp_sleep_cpu_pd_low_init(config->light_sleep_enable);
if (config->light_sleep_enable && ret != ESP_OK) {
ESP_LOGW(TAG, "Failed to enable CPU power down during light sleep.");
Expand All @@ -319,6 +307,19 @@ esp_err_t esp_pm_configure(const void* vconfig)
}
#endif

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);
res = rtc_clk_cpu_freq_mhz_to_config(apb_max_freq, &s_cpu_freq_by_mode[PM_MODE_APB_MAX]);
assert(res);
res = rtc_clk_cpu_freq_mhz_to_config(min_freq_mhz, &s_cpu_freq_by_mode[PM_MODE_APB_MIN]);
assert(res);
s_cpu_freq_by_mode[PM_MODE_LIGHT_SLEEP] = s_cpu_freq_by_mode[PM_MODE_APB_MIN];
s_light_sleep_en = config->light_sleep_enable;
s_config_changed = true;
portEXIT_CRITICAL(&s_switch_lock);

return ESP_OK;
}

Expand Down
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 5c2142e

Please sign in to comment.