diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 0a76f5550a2..4ba97729ad9 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -45,6 +45,16 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init #endif return ESP_OK; } +#elif CONFIG_IDF_TARGET_ESP32S31 +/* Workaround (IDF-14620): full TEE/APM retention is not supported yet on ESP32S31, only disable all + * APM control filters at the retention backup/restore stages here. */ +static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg) +{ + esp_err_t err = sleep_retention_entries_create(tee_apm_filter_disable_regs_retention, ARRAY_SIZE(tee_apm_filter_disable_regs_retention), REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "TEE/APM"); + ESP_LOGD(TAG, "TEE/APM sleep retention initialization"); + return ESP_OK; +} #endif #if CONFIG_ESP_CONSOLE_UART @@ -136,7 +146,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a err = sleep_sys_periph_cache_retention_init(); if(err) goto error; #endif -#if SOC_APM_SUPPORTED +#if SOC_APM_SUPPORTED || CONFIG_IDF_TARGET_ESP32S31 err = sleep_sys_periph_tee_apm_retention_init(arg); if(err) goto error; #endif diff --git a/components/soc/esp32s31/include/soc/system_periph_retention.h b/components/soc/esp32s31/include/soc/system_periph_retention.h index 50d3028e3d2..aab9a5ae082 100644 --- a/components/soc/esp32s31/include/soc/system_periph_retention.h +++ b/components/soc/esp32s31/include/soc/system_periph_retention.h @@ -45,6 +45,20 @@ extern const regdma_entries_config_t cache_regs_retention[CACHE_RETENTION_LINK_L #define TEE_APM_RETENTION_LINK_LEN 14 extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN]; +#if !SOC_APM_SUPPORTED +/** + * @brief Provide access to the APM control filter disable retention context. + * + * Workaround (IDF-14620): until full TEE/APM retention is supported, this only disables all APM + * control filters at the retention backup/restore stages. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TEE_APM_FILTER_DISABLE_RETENTION_LINK_LEN 3 +extern const regdma_entries_config_t tee_apm_filter_disable_regs_retention[TEE_APM_FILTER_DISABLE_RETENTION_LINK_LEN]; +#endif // !SOC_APM_SUPPORTED + /** * @brief Provide access to hp_system configuration registers retention * context definition. diff --git a/components/soc/esp32s31/system_retention_periph.c b/components/soc/esp32s31/system_retention_periph.c index 57ac5b638de..a518b940d26 100644 --- a/components/soc/esp32s31/system_retention_periph.c +++ b/components/soc/esp32s31/system_retention_periph.c @@ -21,6 +21,7 @@ #include "soc/timer_group_reg.h" #include "soc/uart_reg.h" #include "esp32s31/rom/cache.h" +#include "soc/lp_apm_reg.h" #include "soc/hp_apm_reg.h" #include "soc/cpu_apm_reg.h" #include "soc/hp_mem_apm_reg.h" @@ -86,6 +87,18 @@ const regdma_entries_config_t tee_apm_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions"); +#if !SOC_APM_SUPPORTED +/* Workaround (IDF-14620): until full TEE/APM retention is supported, just disable all APM control + * filters (equivalent to apm_hal_enable_ctrl_filter_all(false)) by writing 0 to the APM control + * registers at the retention backup/restore stages. */ +const regdma_entries_config_t tee_apm_filter_disable_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(0x0e), LP_APM_FUNC_CTRL_REG, 0, 0xFFFFFFFF, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(0x0f), HP_APM_FUNC_CTRL_REG, 0, 0xFFFFFFFF, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(0x10), HP_MEM_APM_FUNC_CTRL_REG, 0, 0xFFFFFFFF, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; +_Static_assert(ARRAY_SIZE(tee_apm_filter_disable_regs_retention) == TEE_APM_FILTER_DISABLE_RETENTION_LINK_LEN, "Inconsistent TEE_APM filter disable retention link length definitions"); +#endif // !SOC_APM_SUPPORTED + /* HP System Registers Context */ #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_GMAC1_PAD_BIST_INT_ENA_REG - DR_REG_HP_SYS_BASE) / 4) + 1) const regdma_entries_config_t hp_system_regs_retention[] = {