diff --git a/components/esp_hw_support/include/esp_private/esp_pau.h b/components/esp_hw_support/include/esp_private/esp_pau.h index 7fdbaaa98d..ba975b7b8d 100644 --- a/components/esp_hw_support/include/esp_private/esp_pau.h +++ b/components/esp_hw_support/include/esp_private/esp_pau.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -77,6 +77,16 @@ void pau_regdma_trigger_extra_link_backup(void); */ void pau_regdma_trigger_extra_link_restore(void); +#if SOC_PAU_IN_TOP_DOMAIN +/** + * @brief Rentention link entry selection, enable or disable the retention + * link entry configuration in always-on domain + * + * @param enable Set true to use always-on domain link configuration instead + */ +void pau_regdma_enable_aon_link_entry(bool enable); +#endif + #ifdef __cplusplus } #endif 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 85f96f7c51..076373c8f4 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -164,7 +164,6 @@ uint32_t sleep_retention_get_inited_modules(void); */ uint32_t sleep_retention_get_created_modules(void); -#if SOC_PM_RETENTION_HAS_CLOCK_BUG /** * @brief Software trigger REGDMA to do extra linked list retention * @@ -172,7 +171,6 @@ uint32_t sleep_retention_get_created_modules(void); * or false for restore to register from memory */ void sleep_retention_do_extra_retention(bool backup_or_restore); -#endif #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index 2850d9dfb4..e914bfb96e 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -15,6 +15,10 @@ #include "esp_private/esp_pau.h" #include "esp_private/periph_ctrl.h" +#if SOC_PAU_IN_TOP_DOMAIN +#include "hal/lp_sys_ll.h" +#endif + static __attribute__((unused)) const char *TAG = "pau_regdma"; typedef struct { @@ -107,3 +111,10 @@ void IRAM_ATTR pau_regdma_trigger_extra_link_restore(void) pau_hal_start_regdma_extra_link(PAU_instance()->hal, false); pau_hal_stop_regdma_extra_link(PAU_instance()->hal); } + +#if SOC_PAU_IN_TOP_DOMAIN +void pau_regdma_enable_aon_link_entry(bool enable) +{ + lp_sys_ll_set_pau_aon_bypass(enable); +} +#endif diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 8f7a73bf69..66fc643914 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -21,6 +21,10 @@ #include "sdkconfig.h" #include "esp_pmu.h" +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#include "hal/cache_ll.h" +#endif + static __attribute__((unused)) const char *TAG = "sleep"; struct sleep_retention_module_object { @@ -183,9 +187,7 @@ typedef struct { struct sleep_retention_module_object instance[32]; -#if SOC_PM_RETENTION_HAS_CLOCK_BUG #define EXTRA_LINK_NUM (REGDMA_LINK_ENTRY_NUM - 1) -#endif } sleep_retention_t; static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = { @@ -312,6 +314,7 @@ void sleep_retention_dump_entries(FILE *out) regdma_link_dump(out, s_retention.lists[s_retention.highpri].entries[entry], entry); } } + fflush(out); _lock_release_recursive(&s_retention.lock); } @@ -770,22 +773,28 @@ esp_err_t sleep_retention_module_free(sleep_retention_module_t module) return err; } -#if SOC_PM_RETENTION_HAS_CLOCK_BUG void IRAM_ATTR sleep_retention_do_extra_retention(bool backup_or_restore) { if (s_retention.highpri < SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY || s_retention.highpri > SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { return; } +#if SOC_PAU_IN_TOP_DOMAIN + pau_regdma_enable_aon_link_entry(false); +#endif // Set extra linked list head pointer to hardware pau_regdma_set_extra_link_addr(s_retention.lists[s_retention.highpri].entries[EXTRA_LINK_NUM]); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + /* Data of retention link may be temporarily stored in L1 DCache, which is not accessible by + REGDMA, write it back to L2MEM before starting REGDMA. */ + cache_ll_writeback_all(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA, CACHE_LL_ID_ALL); +#endif if (backup_or_restore) { pau_regdma_trigger_extra_link_backup(); } else { pau_regdma_trigger_extra_link_restore(); } } -#endif #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) diff --git a/components/hal/esp32c5/pau_hal.c b/components/hal/esp32c5/pau_hal.c index 000a958b32..58d5552c82 100644 --- a/components/hal/esp32c5/pau_hal.c +++ b/components/hal/esp32c5/pau_hal.c @@ -40,7 +40,10 @@ void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_rest pau_ll_clear_regdma_backup_done_intr_state(hal->dev); /* The link 3 of REGDMA is reserved, we use it as an extra linked list to * provide backup and restore services for BLE, IEEE802.15.4 and possibly - * other modules */ + * other modules. + * It is also used as software trigger REGDMA to backup and restore, and is + * used by the UT to test module driver retention function. + */ pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); diff --git a/components/hal/esp32c6/pau_hal.c b/components/hal/esp32c6/pau_hal.c index cc39004bae..1baff61487 100644 --- a/components/hal/esp32c6/pau_hal.c +++ b/components/hal/esp32c6/pau_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,7 +40,10 @@ void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool back pau_ll_clear_regdma_backup_done_intr_state(hal->dev); /* The link 3 of REGDMA is reserved, we use it as an extra linked list to * provide backup and restore services for BLE, IEEE802.15.4 and possibly - * other modules */ + * other modules. + * It is also used as software trigger REGDMA to backup and restore, and is + * used by the UT to test module driver retention function. + */ pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); diff --git a/components/hal/esp32c61/pau_hal.c b/components/hal/esp32c61/pau_hal.c index 6b5d4f631c..21a393a634 100644 --- a/components/hal/esp32c61/pau_hal.c +++ b/components/hal/esp32c61/pau_hal.c @@ -42,7 +42,10 @@ void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool back pau_ll_clear_regdma_backup_done_intr_state(hal->dev); /* The link 3 of REGDMA is reserved, we use it as an extra linked list to * provide backup and restore services for BLE, IEEE802.15.4 and possibly - * other modules */ + * other modules. + * It is also used as software trigger REGDMA to backup and restore, and is + * used by the UT to test module driver retention function. + */ pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); diff --git a/components/hal/esp32h2/pau_hal.c b/components/hal/esp32h2/pau_hal.c index 6eeaaef002..4426cdbc9f 100644 --- a/components/hal/esp32h2/pau_hal.c +++ b/components/hal/esp32h2/pau_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,3 +41,26 @@ void IRAM_ATTR pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enabl HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_rst_en, !enable); HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_clk_en, enable); } + +void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) +{ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); + /* The link 3 of REGDMA is reserved, we use it as an extra linked list to + * provide backup and restore services for BLE, IEEE802.15.4 and possibly + * other modules. + * It is also used as software trigger REGDMA to backup and restore, and is + * used by the UT to test module driver retention function. + */ + pau_ll_select_regdma_entry_link(hal->dev, 3); + pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); + pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); + + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) +{ + pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); + pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); +} diff --git a/components/hal/esp32p4/pau_hal.c b/components/hal/esp32p4/pau_hal.c index 2852d99a92..08c6adaf08 100644 --- a/components/hal/esp32p4/pau_hal.c +++ b/components/hal/esp32p4/pau_hal.c @@ -46,9 +46,9 @@ void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); - /* The link 3 of REGDMA is reserved, we use it as an extra linked list to - * provide backup and restore services for BLE, IEEE802.15.4 and possibly - * other modules */ + /* The link 3 of REGDMA is reserved, it is used as software trigger REGDMA to backup and + * restore, and is used by the UT to test module driver retention function. + */ pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); diff --git a/components/soc/include/soc/regdma.h b/components/soc/include/soc/regdma.h index 59897b1ebf..b392238aa2 100644 --- a/components/soc/include/soc/regdma.h +++ b/components/soc/include/soc/regdma.h @@ -26,6 +26,9 @@ extern "C" { #define ENTRY(n) (BIT(n)) +// Only used for driver retention function testing when lightsleep is not supported +#define REGDMA_SW_TRIGGER_ENTRY (ENTRY(3)) + #define REGDMA_PHY_LINK(_pri) ((0x00 << 8) | _pri) #define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri) #define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri)