From c39a0cc0b5917cfc374eecc7459478ba64c87e97 Mon Sep 17 00:00:00 2001 From: Lou Tianhao Date: Mon, 24 Apr 2023 14:56:50 +0800 Subject: [PATCH] Power Management: fix REGDMA power issue when TOP domain powered down during light sleep for esp32h2 --- .../include/esp_private/sleep_retention.h | 10 ++++++++++ components/esp_hw_support/sleep_modes.c | 7 +++++++ components/esp_hw_support/sleep_retention.c | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index 98ed4b01c9..2c1bb7fecf 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -123,6 +123,16 @@ void sleep_retention_do_extra_retention(bool backup_or_restore); */ uint32_t sleep_retention_get_modules(void); +#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +/** + * @brief Software trigger REGDMA to do system linked list retention + * + * @param backup_or_restore true for backup register context to memory + * or false for restore to register from memory + */ +void sleep_retention_do_system_retention(bool backup_or_restore); +#endif + #endif // SOC_PAU_SUPPORTED #ifdef __cplusplus diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 6e210ba56c..2850094544 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -87,6 +87,7 @@ #include "esp_private/sleep_sys_periph.h" #include "esp_private/sleep_clock.h" #elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp_private/sleep_retention.h" #include "esp32h2/rom/rtc.h" #include "esp32h2/rom/cache.h" #include "esp32h2/rom/rtc.h" @@ -507,6 +508,9 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) #endif #if REGI2C_ANA_CALI_PD_WORKAROUND regi2c_analog_cali_reg_read(); +#endif +#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG + sleep_retention_do_system_retention(true); #endif } @@ -521,6 +525,9 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) */ inline static void IRAM_ATTR misc_modules_wake_prepare(void) { +#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG + sleep_retention_do_system_retention(false); +#endif sar_periph_ctrl_power_enable(); #if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL sleep_disable_cpu_retention(); diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 76d4327b0f..af357efb3b 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -530,3 +530,20 @@ void sleep_retention_do_extra_retention(bool backup_or_restore) assert(refs >= 0 && refs <= cnt_modules); } #endif + +#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) +{ + #define SYSTEM_LINK_NUM (0) + if (s_retention.highpri >= SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY && + s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { + // Set extra linked list head pointer to hardware + pau_regdma_set_system_link_addr(s_retention.lists[s_retention.highpri].entries[SYSTEM_LINK_NUM]); + if (backup_or_restore) { + pau_regdma_trigger_system_link_backup(); + } else { + pau_regdma_trigger_system_link_restore(); + } + } +} +#endif