Power Management: fix REGDMA power issue when TOP domain powered down during light sleep for esp32h2

This commit is contained in:
Lou Tianhao 2023-04-24 14:56:50 +08:00
parent b4210682c8
commit 8457998505
3 changed files with 34 additions and 0 deletions

View File

@ -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

View File

@ -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"
@ -509,6 +510,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
}
@ -523,6 +527,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();

View File

@ -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