From fd47ea34bb42b25b159799dbcef4794c3ed461c7 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Wed, 24 Jan 2024 19:32:36 +0800 Subject: [PATCH 01/16] change(esp_hw_support): rename sleep retention module to created module --- components/esp_hw_support/sleep_retention.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 3228840e38..fddcf2e6e2 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -91,14 +91,14 @@ typedef struct { } lists[SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES]; _lock_t lock; regdma_link_priority_t highpri; - uint32_t modules; + uint32_t created_modules; #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 = { - .highpri = (uint8_t)-1, .modules = 0 + .highpri = (uint8_t)-1, .created_modules = 0 }; #define SLEEP_RETENTION_ENTRY_BITMAP_MASK (BIT(REGDMA_LINK_ENTRY_NUM) - 1) @@ -322,7 +322,7 @@ static void sleep_retention_entries_check_and_distroy_final_default(void) { _lock_acquire_recursive(&s_retention.lock); assert(s_retention.highpri == SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY); - assert(s_retention.modules == 0); + assert(s_retention.created_modules == 0); sleep_retention_entries_destroy_wrapper(&s_retention.lists[SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY].entries); _lock_release_recursive(&s_retention.lock); } @@ -348,7 +348,7 @@ static void sleep_retention_entries_all_destroy_wrapper(uint32_t module) priority++; } } while (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES); - s_retention.modules &= ~module; + s_retention.created_modules &= ~module; _lock_release_recursive(&s_retention.lock); } @@ -367,7 +367,7 @@ void sleep_retention_entries_destroy(int module) assert(module != 0); _lock_acquire_recursive(&s_retention.lock); sleep_retention_entries_do_destroy(module); - if (s_retention.modules == 0) { + if (s_retention.created_modules == 0) { sleep_retention_entries_check_and_distroy_final_default(); pmu_sleep_disable_regdma_backup(); memset((void *)s_retention.lists, 0, sizeof(s_retention.lists)); @@ -451,7 +451,7 @@ static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_en if(err) goto error; err = sleep_retention_entries_create_bonding(priority, module); if(err) goto error; - s_retention.modules |= module; + s_retention.created_modules |= module; sleep_retention_entries_join(); error: @@ -495,7 +495,7 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries) uint32_t IRAM_ATTR sleep_retention_get_modules(void) { - return s_retention.modules; + return s_retention.created_modules; } #if SOC_PM_RETENTION_HAS_CLOCK_BUG From f5c8cc2bef71637759d72967b372a60f8bdad0fb Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 25 Jan 2024 11:08:45 +0800 Subject: [PATCH 02/16] change(esp_hw_support): rename interface name of get modules bitmap to get created modules --- .../include/esp_private/sleep_retention.h | 26 +++++++++---------- components/esp_hw_support/sleep_clock.c | 4 +-- components/esp_hw_support/sleep_modem.c | 10 +++---- components/esp_hw_support/sleep_retention.c | 2 +- .../esp_hw_support/sleep_system_peripheral.c | 4 +-- 5 files changed, 23 insertions(+), 23 deletions(-) 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 7b3f400ab4..c43685a2ed 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.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 */ @@ -104,6 +104,18 @@ void * sleep_retention_find_link_by_id(int id); */ void sleep_retention_entries_get(sleep_retention_entries_t *entries); +/** + * @brief Get all created modules that require sleep retention + * + * This is an unprotected interface for getting a bitmap of all modules that + * require sleep retention. + * + * It can only be called by the sleep procedure. + * + * @return the bitmap of all modules requiring sleep retention + */ +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 @@ -114,18 +126,6 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries); void sleep_retention_do_extra_retention(bool backup_or_restore); #endif -/** - * @brief Get all registered modules that require sleep retention - * - * This is an unprotected interface for getting a bitmap of all modules that - * require sleep retention. - * - * It can only be called by the sleep procedure. - * - * @return the bitmap of all modules requiring sleep retention - */ -uint32_t sleep_retention_get_modules(void); - #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** * @brief Software trigger REGDMA to do system linked list retention diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index 384a2e3a00..04fee52992 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.c @@ -78,14 +78,14 @@ void sleep_clock_modem_retention_deinit(void) bool clock_domain_pd_allowed(void) { - const uint32_t modules = sleep_retention_get_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); const uint32_t mask = (const uint32_t) ( SLEEP_RETENTION_MODULE_CLOCK_SYSTEM #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE | SLEEP_RETENTION_MODULE_CLOCK_MODEM #endif ); - return ((modules & mask) == mask); + return ((created_modules & mask) == mask); } #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index b9a6f6c252..c4276c0e45 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -285,16 +285,16 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void bool modem_domain_pd_allowed(void) { #if SOC_PM_MODEM_RETENTION_BY_REGDMA - const uint32_t modules = sleep_retention_get_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC | SLEEP_RETENTION_MODULE_WIFI_BB); const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC | SLEEP_RETENTION_MODULE_BT_BB); const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC | SLEEP_RETENTION_MODULE_BT_BB); - return (((modules & mask_wifi) == mask_wifi) || - ((modules & mask_ble) == mask_ble) || - ((modules & mask_154) == mask_154)); + return (((created_modules & mask_wifi) == mask_wifi) || + ((created_modules & mask_ble) == mask_ble) || + ((created_modules & mask_154) == mask_154)); #else return false; /* MODEM power domain is controlled by each module (WiFi, Bluetooth or 15.4) of modem */ #endif diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index fddcf2e6e2..21da032aad 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -493,7 +493,7 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries) _lock_release_recursive(&s_retention.lock); } -uint32_t IRAM_ATTR sleep_retention_get_modules(void) +uint32_t IRAM_ATTR sleep_retention_get_created_modules(void) { return s_retention.created_modules; } diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 22d236dcd6..3893c21975 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -245,7 +245,7 @@ error: bool peripheral_domain_pd_allowed(void) { - const uint32_t modules = sleep_retention_get_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); const uint32_t mask = (const uint32_t) ( SLEEP_RETENTION_MODULE_INTR_MATRIX | \ SLEEP_RETENTION_MODULE_HP_SYSTEM | \ @@ -255,7 +255,7 @@ bool peripheral_domain_pd_allowed(void) SLEEP_RETENTION_MODULE_IOMUX | \ SLEEP_RETENTION_MODULE_SPIMEM | \ SLEEP_RETENTION_MODULE_SYSTIMER); - return ((modules & mask) == mask); + return ((created_modules & mask) == mask); } #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP From f66e3f031d83a6aac400ef0a19ed009949c9568a Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Mon, 5 Feb 2024 11:37:58 +0800 Subject: [PATCH 03/16] change(esp_hw_support): modify the style of module argument from bitmap to number --- .../include/esp_private/sleep_retention.h | 75 +++++++++++++------ components/esp_hw_support/sleep_clock.c | 4 +- components/esp_hw_support/sleep_modem.c | 15 ++-- components/esp_hw_support/sleep_retention.c | 64 +++++++++------- .../esp_hw_support/sleep_system_peripheral.c | 18 ++--- 5 files changed, 110 insertions(+), 66 deletions(-) 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 c43685a2ed..4569758f20 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -23,34 +23,63 @@ extern "C" { * includes sleep retention list creation, destruction and debugging interfaces. */ -typedef enum sleep_retention_module_bitmap { +typedef enum sleep_retention_module { + SLEEP_RETENTION_MODULE_MIN = 0, /* clock module, which includes system and modem */ - SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), - SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2), + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, + SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, /* modem module, which includes WiFi, BLE and 802.15.4 */ - SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10), - SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11), - SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), - SLEEP_RETENTION_MODULE_BT_BB = BIT(13), - SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), + SLEEP_RETENTION_MODULE_WIFI_MAC = 10, + SLEEP_RETENTION_MODULE_WIFI_BB = 11, + SLEEP_RETENTION_MODULE_BLE_MAC = 12, + SLEEP_RETENTION_MODULE_BT_BB = 13, + SLEEP_RETENTION_MODULE_802154_MAC = 14, /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16), - SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17), - SLEEP_RETENTION_MODULE_TEE_APM = BIT(18), - SLEEP_RETENTION_MODULE_UART0 = BIT(19), - SLEEP_RETENTION_MODULE_TG0 = BIT(20), - SLEEP_RETENTION_MODULE_IOMUX = BIT(21), - SLEEP_RETENTION_MODULE_SPIMEM = BIT(22), - SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23), - SLEEP_RETENTION_MODULE_GDMA_CH0 = BIT(24), - SLEEP_RETENTION_MODULE_GDMA_CH1 = BIT(25), - SLEEP_RETENTION_MODULE_GDMA_CH2 = BIT(26), + SLEEP_RETENTION_MODULE_INTR_MATRIX = 16, + SLEEP_RETENTION_MODULE_HP_SYSTEM = 17, + SLEEP_RETENTION_MODULE_TEE_APM = 18, + SLEEP_RETENTION_MODULE_UART0 = 19, + SLEEP_RETENTION_MODULE_TG0 = 20, + SLEEP_RETENTION_MODULE_IOMUX = 21, + SLEEP_RETENTION_MODULE_SPIMEM = 22, + SLEEP_RETENTION_MODULE_SYSTIMER = 23, + SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, + SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, + SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, + SLEEP_RETENTION_MODULE_MAX = 31 +} sleep_retention_module_t; - SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 +typedef enum sleep_retention_module_bitmap { + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), + SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM), + + /* modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC), + SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB), + SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), + SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), + SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC), + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_BM_INTR_MATRIX = BIT(SLEEP_RETENTION_MODULE_INTR_MATRIX), + SLEEP_RETENTION_MODULE_BM_HP_SYSTEM = BIT(SLEEP_RETENTION_MODULE_HP_SYSTEM), + SLEEP_RETENTION_MODULE_BM_TEE_APM = BIT(SLEEP_RETENTION_MODULE_TEE_APM), + SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), + SLEEP_RETENTION_MODULE_BM_TG0 = BIT(SLEEP_RETENTION_MODULE_TG0), + SLEEP_RETENTION_MODULE_BM_IOMUX = BIT(SLEEP_RETENTION_MODULE_IOMUX), + SLEEP_RETENTION_MODULE_BM_SPIMEM = BIT(SLEEP_RETENTION_MODULE_SPIMEM), + SLEEP_RETENTION_MODULE_BM_SYSTIMER = BIT(SLEEP_RETENTION_MODULE_SYSTIMER), + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + + SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 } sleep_retention_module_bitmap_t; typedef regdma_entry_buf_t sleep_retention_entries_t; @@ -67,21 +96,21 @@ typedef struct { * @param num the total number of sleep retention linked list configuration * items * @param priority the priority of the created sleep retention linked list - * @param module the bitmap of the module to which the created sleep retention + * @param module the number of the module to which the created sleep retention * linked list belongs * @return * - ESP_OK on success * - ESP_ERR_NO_MEM not enough memory for sleep retention * - ESP_ERR_INVALID_ARG if either of the arguments is out of range */ -esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module); +esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module); /** * @brief Destroy a runtime sleep retention linked list * * @param module the bitmap of the module to be destroyed */ -void sleep_retention_entries_destroy(int module); +void sleep_retention_entries_destroy(sleep_retention_module_t module); /** * @brief Print all runtime sleep retention linked lists diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index 04fee52992..271fbb7810 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.c @@ -80,9 +80,9 @@ bool clock_domain_pd_allowed(void) { const uint32_t created_modules = sleep_retention_get_created_modules(); const uint32_t mask = (const uint32_t) ( - SLEEP_RETENTION_MODULE_CLOCK_SYSTEM + BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE - | SLEEP_RETENTION_MODULE_CLOCK_MODEM + | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) #endif ); return ((created_modules & mask) == mask); diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index c4276c0e45..864c03a6af 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -286,12 +286,15 @@ bool modem_domain_pd_allowed(void) { #if SOC_PM_MODEM_RETENTION_BY_REGDMA const uint32_t created_modules = sleep_retention_get_created_modules(); - const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC | - SLEEP_RETENTION_MODULE_WIFI_BB); - const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC | - SLEEP_RETENTION_MODULE_BT_BB); - const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC | - SLEEP_RETENTION_MODULE_BT_BB); + const uint32_t mask_wifi = (const uint32_t) ( \ + BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | \ + BIT(SLEEP_RETENTION_MODULE_WIFI_BB)); + const uint32_t mask_ble = (const uint32_t) ( \ + BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | \ + BIT(SLEEP_RETENTION_MODULE_BT_BB)); + const uint32_t mask_154 = (const uint32_t) ( \ + BIT(SLEEP_RETENTION_MODULE_802154_MAC) | \ + BIT(SLEEP_RETENTION_MODULE_BT_BB)); return (((created_modules & mask_wifi) == mask_wifi) || ((created_modules & mask_ble) == mask_ble) || ((created_modules & mask_154) == mask_154)); diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 21da032aad..5a5bc7b467 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -82,6 +82,7 @@ typedef struct { #define SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES (8u) #define SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY (0) #define SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY (SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES - 1) +#define SLEEP_RETENTION_MODULE_INVALID ((sleep_retention_module_t)(-1)) /* the final node does not belong to any module */ struct { sleep_retention_entries_t entries; uint32_t entries_bitmap: REGDMA_LINK_ENTRY_NUM, @@ -104,9 +105,14 @@ static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = { #define SLEEP_RETENTION_ENTRY_BITMAP_MASK (BIT(REGDMA_LINK_ENTRY_NUM) - 1) #define SLEEP_RETENTION_ENTRY_BITMAP(bitmap) ((bitmap) & SLEEP_RETENTION_ENTRY_BITMAP_MASK) -static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module); +static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module); static void sleep_retention_entries_join(void); +static inline sleep_retention_module_bitmap_t module_num2map(sleep_retention_module_t module) +{ + return (module == SLEEP_RETENTION_MODULE_INVALID) ? 0 : BIT(module); +} + static inline bool sleep_retention_entries_require_branch(uint32_t owner, uint32_t runtime_bitmap) { bool use_new_entry = SLEEP_RETENTION_ENTRY_BITMAP(owner & ~runtime_bitmap) ? true : false; @@ -114,7 +120,7 @@ static inline bool sleep_retention_entries_require_branch(uint32_t owner, uint32 return use_new_entry && intersection_exist; } -static esp_err_t sleep_retention_entries_check_and_create_default(uint32_t owner, uint32_t runtime_bitmap, uint32_t entries_bitmap, regdma_link_priority_t priority, uint32_t module) +static esp_err_t sleep_retention_entries_check_and_create_default(uint32_t owner, uint32_t runtime_bitmap, uint32_t entries_bitmap, regdma_link_priority_t priority, sleep_retention_module_t module) { assert(sleep_retention_entries_require_branch(owner, runtime_bitmap)); @@ -133,7 +139,7 @@ static esp_err_t sleep_retention_entries_check_and_create_final_default(void) esp_err_t err = ESP_OK; _lock_acquire_recursive(&s_retention.lock); if (s_retention.lists[SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY].entries_bitmap == 0) { - err = sleep_retention_entries_create_impl(&final_dummy, 1, SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY, 0); + err = sleep_retention_entries_create_impl(&final_dummy, 1, SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY, SLEEP_RETENTION_MODULE_INVALID); } _lock_release_recursive(&s_retention.lock); return err; @@ -157,7 +163,7 @@ static void sleep_retention_entries_update(uint32_t owner, void *new_link, regdm _lock_release_recursive(&s_retention.lock); } -static void * sleep_retention_entries_try_create(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, uint32_t module) +static void * sleep_retention_entries_try_create(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, sleep_retention_module_t module) { void *link = NULL; assert(owner > 0 && owner < BIT(REGDMA_LINK_ENTRY_NUM)); @@ -165,9 +171,9 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con _lock_acquire_recursive(&s_retention.lock); if (sleep_retention_entries_require_branch(owner, s_retention.lists[priority].runtime_bitmap)) { if (sleep_retention_entries_check_and_create_default(owner, s_retention.lists[priority].runtime_bitmap, - s_retention.lists[priority].entries_bitmap, priority, module) == ESP_OK) { /* branch node can't as tail node */ + s_retention.lists[priority].entries_bitmap, priority, module_num2map(module)) == ESP_OK) { /* branch node can't as tail node */ link = regdma_link_init_safe( - config, true, module, + config, true, module_num2map(module), (owner & BIT(0)) ? s_retention.lists[priority].entries[0] : NULL, (owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL, (owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL, @@ -175,18 +181,18 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con ); } } else { - link = regdma_link_init_safe(config, false, module, s_retention.lists[priority].entries[__builtin_ffs(owner) - 1]); + link = regdma_link_init_safe(config, false, module_num2map(module), s_retention.lists[priority].entries[__builtin_ffs(owner) - 1]); } _lock_release_recursive(&s_retention.lock); return link; } -static void * sleep_retention_entries_try_create_bonding(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, uint32_t module) +static void * sleep_retention_entries_try_create_bonding(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, sleep_retention_module_t module) { assert(owner > 0 && owner < BIT(REGDMA_LINK_ENTRY_NUM)); _lock_acquire_recursive(&s_retention.lock); void *link = regdma_link_init_safe( - config, true, module, + config, true, module_num2map(module), (owner & BIT(0)) ? s_retention.lists[priority].entries[0] : NULL, (owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL, (owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL, @@ -246,7 +252,7 @@ static uint32_t sleep_retention_entries_owner_bitmap(sleep_retention_entries_t * return owner; } -static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t priority, uint32_t module, sleep_retention_entries_t *destroy_entries, void **destroy_tail, sleep_retention_entries_t *next_entries, void **prev_tail) +static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t priority, sleep_retention_module_t module, sleep_retention_entries_t *destroy_entries, void **destroy_tail, sleep_retention_entries_t *next_entries, void **prev_tail) { bool exist = false; sleep_retention_entries_t destroy_tails, prev_tails; @@ -257,13 +263,13 @@ static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t p _lock_acquire_recursive(&s_retention.lock); for (int entry = 0; entry < ARRAY_SIZE(s_retention.lists[priority].entries); entry++) { (*destroy_entries)[entry] = regdma_find_module_link_head( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); destroy_tails [entry] = regdma_find_module_link_tail( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); (*next_entries) [entry] = regdma_find_next_module_link_head( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); prev_tails [entry] = regdma_find_prev_module_link_tail( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); if ((*destroy_entries)[entry] && destroy_tails[entry]) { exist = true; } @@ -327,7 +333,7 @@ static void sleep_retention_entries_check_and_distroy_final_default(void) _lock_release_recursive(&s_retention.lock); } -static void sleep_retention_entries_all_destroy_wrapper(uint32_t module) +static void sleep_retention_entries_all_destroy_wrapper(sleep_retention_module_t module) { void *destroy_tail = NULL, *prev_tail = NULL; sleep_retention_entries_t destroy_entries, next_entries; @@ -348,13 +354,13 @@ static void sleep_retention_entries_all_destroy_wrapper(uint32_t module) priority++; } } while (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES); - s_retention.created_modules &= ~module; + s_retention.created_modules &= ~module_num2map(module); _lock_release_recursive(&s_retention.lock); } -static void sleep_retention_entries_do_destroy(int module) +static void sleep_retention_entries_do_destroy(sleep_retention_module_t module) { - assert(module != 0); + assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX); _lock_acquire_recursive(&s_retention.lock); sleep_retention_entries_join(); sleep_retention_entries_stats(); @@ -362,9 +368,9 @@ static void sleep_retention_entries_do_destroy(int module) _lock_release_recursive(&s_retention.lock); } -void sleep_retention_entries_destroy(int module) +void sleep_retention_entries_destroy(sleep_retention_module_t module) { - assert(module != 0); + assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX); _lock_acquire_recursive(&s_retention.lock); sleep_retention_entries_do_destroy(module); if (s_retention.created_modules == 0) { @@ -380,7 +386,7 @@ void sleep_retention_entries_destroy(int module) _lock_release_recursive(&s_retention.lock); } -static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module) +static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { _lock_acquire_recursive(&s_retention.lock); for (int i = num - 1; i >= 0; i--) { @@ -403,7 +409,7 @@ static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entri return ESP_OK; } -static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, uint32_t module) +static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, sleep_retention_module_t module) { static const sleep_retention_entries_config_t bonding_dummy = { REGDMA_LINK_WAIT_INIT(0xffff, 0, 0, 0, 1, 1), SLEEP_RETENTION_ENTRY_BITMAP_MASK }; @@ -442,7 +448,7 @@ static void sleep_retention_entries_join(void) _lock_release_recursive(&s_retention.lock); } -static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, uint32_t module) +static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { _lock_acquire_recursive(&s_retention.lock); esp_err_t err = sleep_retention_entries_create_bonding(priority, module); @@ -451,7 +457,7 @@ static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_en if(err) goto error; err = sleep_retention_entries_create_bonding(priority, module); if(err) goto error; - s_retention.created_modules |= module; + s_retention.created_modules |= module_num2map(module); sleep_retention_entries_join(); error: @@ -459,9 +465,15 @@ error: return err; } -esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module) +esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { - if (!(retent && num > 0 && (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) && (module != 0))) { + if (retent == NULL || num <= 0) { + return ESP_ERR_INVALID_ARG; + } + if (priority >= SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) { + return ESP_ERR_INVALID_ARG; + } + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { return ESP_ERR_INVALID_ARG; } if (s_retention.lock == NULL) { diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 3893c21975..408a95e99a 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.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 */ @@ -247,14 +247,14 @@ bool peripheral_domain_pd_allowed(void) { const uint32_t created_modules = sleep_retention_get_created_modules(); const uint32_t mask = (const uint32_t) ( - SLEEP_RETENTION_MODULE_INTR_MATRIX | \ - SLEEP_RETENTION_MODULE_HP_SYSTEM | \ - SLEEP_RETENTION_MODULE_TEE_APM | \ - SLEEP_RETENTION_MODULE_UART0 | \ - SLEEP_RETENTION_MODULE_TG0 | \ - SLEEP_RETENTION_MODULE_IOMUX | \ - SLEEP_RETENTION_MODULE_SPIMEM | \ - SLEEP_RETENTION_MODULE_SYSTIMER); + BIT(SLEEP_RETENTION_MODULE_INTR_MATRIX) | \ + BIT(SLEEP_RETENTION_MODULE_HP_SYSTEM) | \ + BIT(SLEEP_RETENTION_MODULE_TEE_APM) | \ + BIT(SLEEP_RETENTION_MODULE_UART0) | \ + BIT(SLEEP_RETENTION_MODULE_TG0) | \ + BIT(SLEEP_RETENTION_MODULE_IOMUX) | \ + BIT(SLEEP_RETENTION_MODULE_SPIMEM) | \ + BIT(SLEEP_RETENTION_MODULE_SYSTIMER)); return ((created_modules & mask) == mask); } From a2cbe3f0a385cd20013d8f638bb4c97faeda1275 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Mon, 5 Feb 2024 15:24:47 +0800 Subject: [PATCH 04/16] feat(esp_hw_support): implement of sleep retention module initialize and dependency management --- .../include/esp_private/sleep_retention.h | 96 +++++- components/esp_hw_support/sleep_retention.c | 288 +++++++++++++++++- 2 files changed, 363 insertions(+), 21 deletions(-) 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 4569758f20..589411177e 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -89,6 +89,21 @@ typedef struct { uint32_t owner; /**< Indicates which regdma entries the current node will insert into */ } sleep_retention_entries_config_t; +typedef esp_err_t (*sleep_retention_callback_t)(void *args); + +typedef struct { + sleep_retention_callback_t handle; + void *arg; +} sleep_retention_create_callback_t; + +typedef struct { + sleep_retention_create_callback_t create; /*!< A function handle is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */ +} sleep_retention_module_callbacks_t; + +typedef enum { + SLEEP_RETENTION_MODULE_ATTR_PASSIVE = 0x1 +} sleep_retention_module_attribute_t; + /** * @brief Create a runtime sleep retention linked list * @@ -105,13 +120,6 @@ typedef struct { */ esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module); -/** - * @brief Destroy a runtime sleep retention linked list - * - * @param module the bitmap of the module to be destroyed - */ -void sleep_retention_entries_destroy(sleep_retention_module_t module); - /** * @brief Print all runtime sleep retention linked lists */ @@ -133,6 +141,77 @@ void * sleep_retention_find_link_by_id(int id); */ void sleep_retention_entries_get(sleep_retention_entries_t *entries); +typedef struct sleep_retention_module_init_param { + sleep_retention_module_callbacks_t cbs; /*!< The callbacks list of the initialize module */ + sleep_retention_module_attribute_t attribute; /*!< A bitmap indicating attribute of the initialize module */ + sleep_retention_module_bitmap_t depends; /*!< A bitmap identifying all modules that the current module depends on */ +} sleep_retention_module_init_param_t; + +/** + * @brief sleep retention initialization for the module + * + * @param module the module number that needs initialization + * @param param the initialize parameters for module sleep retention initialization + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough memory for sleep retention + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the retention context of module already been allocated + */ +esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param); + +/** + * @brief sleep retention de-initialization for the module + * + * @param module the module number that needs de-initialization + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the retention context of module already been allocated + */ +esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module); + +/** + * @brief Allocate the sleep retention context for the module + * + * @param module the module number that need to allocating sleep retention context + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough memory for sleep retention + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the module is de-initialized + * - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE + */ +esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module); + +/** + * @brief Free the sleep retention context for the module + * + * @param module the module number that need to free sleep retention context + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the module is de-initialized + * - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE + */ +esp_err_t sleep_retention_module_free(sleep_retention_module_t module); + +/** + * @brief Get all initialized modules that require sleep retention + * + * This is an unprotected interface for getting a bitmap of all modules that + * require sleep retention. + * + * It can only be called by the sleep procedure. + * + * @return the bitmap for all modules that require sleep retention + */ +uint32_t sleep_retention_get_inited_modules(void); + /** * @brief Get all created modules that require sleep retention * @@ -141,7 +220,8 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries); * * It can only be called by the sleep procedure. * - * @return the bitmap of all modules requiring sleep retention + * @return the bitmap for all modules that have successfully created a sleep + * retention context */ uint32_t sleep_retention_get_created_modules(void); diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 5a5bc7b467..5966868c3a 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -23,6 +23,92 @@ static __attribute__((unused)) const char *TAG = "sleep"; +struct sleep_retention_module_object { + sleep_retention_module_callbacks_t cbs; /* A callback list that can extend more sleep retention event callbacks */ + sleep_retention_module_bitmap_t dependents; /* A bitmap identifying all modules that the current module depends on */ + sleep_retention_module_bitmap_t references; /* A bitmap indicating all other modules that depend on (or reference) the current module, + * It will update at runtime based on whether the module is referenced by other modules */ + sleep_retention_module_attribute_t attributes; /* A bitmap indicating attribute of the current module */ +}; + +static inline void sleep_retention_module_object_ctor(struct sleep_retention_module_object * const self, sleep_retention_module_callbacks_t *cbs) +{ + self->cbs = *cbs; + self->dependents = 0; + self->references = 0; + self->attributes = 0; +} + +static inline void sleep_retention_module_object_dtor(struct sleep_retention_module_object * const self) +{ + self->cbs = (sleep_retention_module_callbacks_t) { .create = { .handle = NULL, .arg = NULL } }; +} + +static inline void set_dependencies(struct sleep_retention_module_object * const self, sleep_retention_module_bitmap_t depends) +{ + self->dependents = depends; +} + +static inline void clr_dependencies(struct sleep_retention_module_object * const self) +{ + self->dependents = 0; +} + +static inline sleep_retention_module_bitmap_t get_dependencies(struct sleep_retention_module_object * const self) +{ + return self->dependents; +} + +static inline void set_reference(struct sleep_retention_module_object * const self, sleep_retention_module_t module) +{ + self->references |= BIT(module); +} + +static inline void clr_reference(struct sleep_retention_module_object * const self, sleep_retention_module_t module) +{ + self->references &= ~BIT(module); +} + +static inline sleep_retention_module_bitmap_t get_references(struct sleep_retention_module_object * const self) +{ + return self->references; +} + +static inline bool references_exist(struct sleep_retention_module_object * const self) +{ + return (get_references(self) != 0); +} + +static inline void set_attributes(struct sleep_retention_module_object * const self, sleep_retention_module_attribute_t attributes) +{ + self->attributes = attributes; +} + +static inline void clr_attributes(struct sleep_retention_module_object * const self) +{ + self->attributes = 0; +} + +static inline sleep_retention_module_attribute_t get_attributes(struct sleep_retention_module_object * const self) +{ + return self->attributes; +} + +static inline bool module_is_passive(struct sleep_retention_module_object * const self) +{ + return (get_attributes(self) & SLEEP_RETENTION_MODULE_ATTR_PASSIVE) ? true : false; +} + +static inline bool module_is_inited(sleep_retention_module_t module) +{ + return (sleep_retention_get_inited_modules() & BIT(module)) ? true : false; +} + +static inline bool module_is_created(sleep_retention_module_t module) +{ + return (sleep_retention_get_created_modules() & BIT(module)) ? true : false; +} + /** * Internal structure which holds all requested sleep retention parameters */ @@ -92,14 +178,18 @@ typedef struct { } lists[SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES]; _lock_t lock; regdma_link_priority_t highpri; + uint32_t inited_modules; uint32_t created_modules; + + 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 = { - .highpri = (uint8_t)-1, .created_modules = 0 + .highpri = (uint8_t)-1, .inited_modules = 0, .created_modules = 0 }; #define SLEEP_RETENTION_ENTRY_BITMAP_MASK (BIT(REGDMA_LINK_ENTRY_NUM) - 1) @@ -368,7 +458,7 @@ static void sleep_retention_entries_do_destroy(sleep_retention_module_t module) _lock_release_recursive(&s_retention.lock); } -void sleep_retention_entries_destroy(sleep_retention_module_t module) +static void sleep_retention_entries_destroy(sleep_retention_module_t module) { assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX); _lock_acquire_recursive(&s_retention.lock); @@ -378,10 +468,6 @@ void sleep_retention_entries_destroy(sleep_retention_module_t module) pmu_sleep_disable_regdma_backup(); memset((void *)s_retention.lists, 0, sizeof(s_retention.lists)); s_retention.highpri = (uint8_t)-1; - _lock_release_recursive(&s_retention.lock); - _lock_close_recursive(&s_retention.lock); - s_retention.lock = NULL; - return; } _lock_release_recursive(&s_retention.lock); } @@ -476,13 +562,6 @@ esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { return ESP_ERR_INVALID_ARG; } - if (s_retention.lock == NULL) { - _lock_init_recursive(&s_retention.lock); - if (s_retention.lock == NULL) { - ESP_LOGE(TAG, "Create sleep retention lock failed"); - return ESP_ERR_NO_MEM; - } - } esp_err_t err = sleep_retention_entries_check_and_create_final_default(); if (err) goto error; err = sleep_retention_entries_create_wrapper(retent, num, priority, module); @@ -505,11 +584,194 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries) _lock_release_recursive(&s_retention.lock); } +uint32_t IRAM_ATTR sleep_retention_get_inited_modules(void) +{ + return s_retention.inited_modules; +} + uint32_t IRAM_ATTR sleep_retention_get_created_modules(void) { return s_retention.created_modules; } +esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + if (param == NULL || param->cbs.create.handle == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (s_retention.lock == NULL) { + /* Passive modules will be initialized during the system startup, with the + * operating system scheduler not yet enabled. There is no risk of contention + * for lock initialization here. */ + _lock_init_recursive(&s_retention.lock); + if (s_retention.lock == NULL) { + ESP_LOGE(TAG, "Create sleep retention lock failed"); + return ESP_ERR_NO_MEM; + } + } + + esp_err_t err = ESP_OK; + _lock_acquire_recursive(&s_retention.lock); + if (module_is_created(module) || module_is_inited(module)) { + err = ESP_ERR_INVALID_STATE; + } else { + sleep_retention_module_object_ctor(&s_retention.instance[module], ¶m->cbs); + set_dependencies(&s_retention.instance[module], param->depends); + set_attributes(&s_retention.instance[module], param->attribute); + s_retention.inited_modules |= module_num2map(module); + } + _lock_release_recursive(&s_retention.lock); + return err; +} + +esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_OK; + bool do_lock_release = false; + _lock_acquire_recursive(&s_retention.lock); + if (module_is_created(module) || !module_is_inited(module)) { + err = ESP_ERR_INVALID_STATE; + } else { + clr_attributes(&s_retention.instance[module]); + clr_dependencies(&s_retention.instance[module]); + sleep_retention_module_object_dtor(&s_retention.instance[module]); + s_retention.inited_modules &= ~module_num2map(module); + do_lock_release = (sleep_retention_get_inited_modules() == 0); + } + _lock_release_recursive(&s_retention.lock); + + if (do_lock_release) { + _lock_close_recursive(&s_retention.lock); + s_retention.lock = NULL; + } + return err; +} + +static esp_err_t sleep_retention_passive_module_allocate(sleep_retention_module_t module) +{ + assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX); + + esp_err_t err = ESP_OK; + _lock_acquire_recursive(&s_retention.lock); + assert(module_is_passive(&s_retention.instance[module]) && "Illegal dependency"); + assert(module_is_inited(module) && "All passive module must be inited first!"); + if (!module_is_created(module)) { + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + set_reference(&s_retention.instance[i], module); + err = sleep_retention_passive_module_allocate(i); + } + } + if (err == ESP_OK) { + sleep_retention_callback_t fn = s_retention.instance[module].cbs.create.handle; + if (fn) { + err = (*fn)(s_retention.instance[module].cbs.create.arg); + } + } + } + _lock_release_recursive(&s_retention.lock); + return err; +} + +esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_OK; + _lock_acquire_recursive(&s_retention.lock); + if (!module_is_passive(&s_retention.instance[module])) { + if (module_is_inited(module) && !module_is_created(module)) { + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + set_reference(&s_retention.instance[i], module); + if (module_is_passive(&s_retention.instance[i])) { /* the callee ensures this module is inited */ + err = sleep_retention_passive_module_allocate(i); + } + } + } + if (err == ESP_OK) { + sleep_retention_callback_t fn = s_retention.instance[module].cbs.create.handle; + if (fn) { + err = (*fn)(s_retention.instance[module].cbs.create.arg); + } + } + } else { + err = ESP_ERR_INVALID_STATE; + } + } else { + err = ESP_ERR_NOT_ALLOWED; + } + _lock_release_recursive(&s_retention.lock); + return err; +} + +static esp_err_t sleep_retention_passive_module_free(sleep_retention_module_t module) +{ + assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX); + + esp_err_t err = ESP_OK; + _lock_acquire_recursive(&s_retention.lock); + assert(module_is_passive(&s_retention.instance[module]) && "Illegal dependency"); + assert(module_is_inited(module) && "All passive module must be inited first!"); + if (module_is_created(module)) { + if (!references_exist(&s_retention.instance[module])) { + sleep_retention_entries_destroy(module); + + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + clr_reference(&s_retention.instance[i], module); + err = sleep_retention_passive_module_free(i); + } + } + } + } + _lock_release_recursive(&s_retention.lock); + return err; +} + +esp_err_t sleep_retention_module_free(sleep_retention_module_t module) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_OK; + _lock_acquire_recursive(&s_retention.lock); + if (!module_is_passive(&s_retention.instance[module])) { + if (module_is_inited(module) && module_is_created(module)) { + sleep_retention_entries_destroy(module); + + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + clr_reference(&s_retention.instance[i], module); + if (module_is_passive(&s_retention.instance[i])) { + err = sleep_retention_passive_module_free(i); + } + } + } + } else { + err = ESP_ERR_INVALID_STATE; + } + } else { + err = ESP_ERR_NOT_ALLOWED; + } + _lock_release_recursive(&s_retention.lock); + return err; +} + #if SOC_PM_RETENTION_HAS_CLOCK_BUG void IRAM_ATTR sleep_retention_do_extra_retention(bool backup_or_restore) { From e7d6748aec7470ff2ff158368e90d2acc4a644c5 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Mon, 5 Feb 2024 20:17:54 +0800 Subject: [PATCH 05/16] change(esp_hw_support): some system peripherals to use a retention module number --- .../include/esp_private/sleep_retention.h | 20 +--- .../include/esp_private/sleep_sys_periph.h | 11 +- .../esp_hw_support/sleep_system_peripheral.c | 112 +++++++++--------- 3 files changed, 63 insertions(+), 80 deletions(-) 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 589411177e..8772263e0c 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -38,14 +38,8 @@ typedef enum sleep_retention_module { /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_INTR_MATRIX = 16, - SLEEP_RETENTION_MODULE_HP_SYSTEM = 17, - SLEEP_RETENTION_MODULE_TEE_APM = 18, - SLEEP_RETENTION_MODULE_UART0 = 19, - SLEEP_RETENTION_MODULE_TG0 = 20, - SLEEP_RETENTION_MODULE_IOMUX = 21, - SLEEP_RETENTION_MODULE_SPIMEM = 22, - SLEEP_RETENTION_MODULE_SYSTIMER = 23, + SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, @@ -67,14 +61,8 @@ typedef enum sleep_retention_module_bitmap { /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_BM_INTR_MATRIX = BIT(SLEEP_RETENTION_MODULE_INTR_MATRIX), - SLEEP_RETENTION_MODULE_BM_HP_SYSTEM = BIT(SLEEP_RETENTION_MODULE_HP_SYSTEM), - SLEEP_RETENTION_MODULE_BM_TEE_APM = BIT(SLEEP_RETENTION_MODULE_TEE_APM), - SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), - SLEEP_RETENTION_MODULE_BM_TG0 = BIT(SLEEP_RETENTION_MODULE_TG0), - SLEEP_RETENTION_MODULE_BM_IOMUX = BIT(SLEEP_RETENTION_MODULE_IOMUX), - SLEEP_RETENTION_MODULE_BM_SPIMEM = BIT(SLEEP_RETENTION_MODULE_SPIMEM), - SLEEP_RETENTION_MODULE_BM_SYSTIMER = BIT(SLEEP_RETENTION_MODULE_SYSTIMER), + SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), diff --git a/components/esp_hw_support/include/esp_private/sleep_sys_periph.h b/components/esp_hw_support/include/esp_private/sleep_sys_periph.h index ee4af519ce..b66826c099 100644 --- a/components/esp_hw_support/include/esp_private/sleep_sys_periph.h +++ b/components/esp_hw_support/include/esp_private/sleep_sys_periph.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 */ @@ -29,15 +29,6 @@ extern "C" { */ bool peripheral_domain_pd_allowed(void); -/** - * @brief Digital peripheral power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -void sleep_sys_periph_retention_init(void); - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 408a95e99a..2025e0771c 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -34,7 +34,7 @@ static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; #define SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT (REGDMA_LINK_PRI_6) -esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_intr_matrix_retention_init(void *arg) { #define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) @@ -42,13 +42,13 @@ esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ }; - esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention"); - ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Interrupt matrix"); + ESP_LOGD(TAG, "Interrupt Matrix sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_hp_system_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_init(void *arg) { #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) @@ -56,13 +56,13 @@ esp_err_t sleep_sys_periph_hp_system_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ }; - esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention"); - ESP_LOGI(TAG, "HP System sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "HP system"); + ESP_LOGD(TAG, "HP System sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_tee_apm_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg) { #define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) #define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) @@ -72,36 +72,36 @@ esp_err_t sleep_sys_periph_tee_apm_retention_init(void) [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ }; - esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_TEE_APM); + esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_SYS_PERIPH); if (err == ESP_OK) { const static sleep_retention_entries_config_t regs_highpri_retention[] = { [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } }; - err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_TEE_APM); + err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_SYS_PERIPH); } - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (TEE/APM) retention"); - ESP_LOGI(TAG, "TEE/APM sleep retention initialization"); + 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; } -esp_err_t sleep_sys_periph_uart0_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(void *arg) { #define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) const static sleep_retention_entries_config_t uart_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ /* Note: uart register should set update reg to make the configuration take effect */ [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention"); - ESP_LOGI(TAG, "UART sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "UART"); + ESP_LOGD(TAG, "UART sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_tg0_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg) { #define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) @@ -117,13 +117,13 @@ esp_err_t sleep_sys_periph_tg0_retention_init(void) [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group) retention"); - ESP_LOGI(TAG, "Timer Group sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group"); + ESP_LOGD(TAG, "Timer Group sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_iomux_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg) { #if CONFIG_IDF_TARGET_ESP32C6 #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) @@ -143,13 +143,13 @@ esp_err_t sleep_sys_periph_iomux_retention_init(void) [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention"); - ESP_LOGI(TAG, "IO Matrix sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "IO Matrix"); + ESP_LOGD(TAG, "IO Matrix sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_spimem_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_spimem_retention_init(void *arg) { #define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) #define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) @@ -175,13 +175,13 @@ esp_err_t sleep_sys_periph_spimem_retention_init(void) [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention"); - ESP_LOGI(TAG, "SPI Mem sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SPI mem"); + ESP_LOGD(TAG, "SPI Mem sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_systimer_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_init(void *arg) { #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) @@ -214,30 +214,30 @@ esp_err_t sleep_sys_periph_systimer_retention_init(void) [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ }; - esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention"); - ESP_LOGI(TAG, "SysTimer sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SysTimer"); + ESP_LOGD(TAG, "SysTimer sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *arg) { esp_err_t err; - err = sleep_sys_periph_intr_matrix_retention_init(); + err = sleep_sys_periph_intr_matrix_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_hp_system_retention_init(); + err = sleep_sys_periph_hp_system_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tee_apm_retention_init(); + err = sleep_sys_periph_tee_apm_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_uart0_retention_init(); + err = sleep_sys_periph_uart0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tg0_retention_init(); + err = sleep_sys_periph_tg0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_iomux_retention_init(); + err = sleep_sys_periph_iomux_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_spimem_retention_init(); + err = sleep_sys_periph_spimem_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_systimer_retention_init(); + err = sleep_sys_periph_systimer_retention_init(arg); error: return err; @@ -245,23 +245,27 @@ error: bool peripheral_domain_pd_allowed(void) { + const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); - const uint32_t mask = (const uint32_t) ( - BIT(SLEEP_RETENTION_MODULE_INTR_MATRIX) | \ - BIT(SLEEP_RETENTION_MODULE_HP_SYSTEM) | \ - BIT(SLEEP_RETENTION_MODULE_TEE_APM) | \ - BIT(SLEEP_RETENTION_MODULE_UART0) | \ - BIT(SLEEP_RETENTION_MODULE_TG0) | \ - BIT(SLEEP_RETENTION_MODULE_IOMUX) | \ - BIT(SLEEP_RETENTION_MODULE_SPIMEM) | \ - BIT(SLEEP_RETENTION_MODULE_SYSTIMER)); - return ((created_modules & mask) == mask); + const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + return ((inited_modules & mask) == (created_modules & mask)); } #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, BIT(0), 107) { - sleep_sys_periph_retention_init(); + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_sys_periph_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_SYS_PERIPH, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_SYS_PERIPH); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for system peripherals retention"); + } + } return ESP_OK; } #endif From 9a51752d4df48df583baea95d0bab96acf5d910f Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Mon, 5 Feb 2024 20:49:34 +0800 Subject: [PATCH 06/16] change(esp_hw_support): modify system and modem clock to support modem domain power down --- .../include/esp_private/sleep_clock.h | 30 +------- components/esp_hw_support/sleep_clock.c | 68 ++++++++++++------- components/esp_hw_support/sleep_modem.c | 25 +++---- 3 files changed, 57 insertions(+), 66 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/sleep_clock.h b/components/esp_hw_support/include/esp_private/sleep_clock.h index 5b204c1856..9cecc583b3 100644 --- a/components/esp_hw_support/include/esp_private/sleep_clock.h +++ b/components/esp_hw_support/include/esp_private/sleep_clock.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 */ @@ -31,34 +31,6 @@ extern "C" { */ bool clock_domain_pd_allowed(void); -/** - * @brief PCR module power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -esp_err_t sleep_clock_system_retention_init(void); - -/** - * @brief PCR module power down deinitialize - */ -void sleep_clock_system_retention_deinit(void); - -/** - * @brief Modem syscon module power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -esp_err_t sleep_clock_modem_retention_init(void); - -/** - * @brief Modem syscon module power down deinitialize - */ -void sleep_clock_modem_retention_deinit(void); - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index 271fbb7810..75bc0c7e62 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.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 */ @@ -29,7 +29,7 @@ static __attribute__((unused)) const char *TAG = "sleep_clock"; -esp_err_t sleep_clock_system_retention_init(void) +static esp_err_t sleep_clock_system_retention_init(void *arg) { #if CONFIG_IDF_TARGET_ESP32C6 #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) @@ -46,12 +46,8 @@ esp_err_t sleep_clock_system_retention_init(void) return ESP_OK; } -void sleep_clock_system_retention_deinit(void) -{ - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); -} - -esp_err_t sleep_clock_modem_retention_init(void) +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE +static esp_err_t sleep_clock_modem_retention_init(void *arg) { #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA @@ -70,34 +66,56 @@ esp_err_t sleep_clock_modem_retention_init(void) ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); return ESP_OK; } - -void sleep_clock_modem_retention_deinit(void) -{ - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); -} +#endif bool clock_domain_pd_allowed(void) { + const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); - const uint32_t mask = (const uint32_t) ( - BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE - | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + /* The clock and reset of MODEM (WiFi, BLE and 15.4) modules are managed + * through MODEM_SYSCON, when one or more MODEMs are initialized, it is + * necessary to check the state of CLOCK_MODEM to determine MODEM domain on + * or off. The clock and reset of digital peripherals are managed through + * PCR, with TOP domain similar to MODEM domain. */ + uint32_t modem_clk_dep_modules = 0; +#if SOC_WIFI_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB); #endif - ); - return ((created_modules & mask) == mask); +#if SOC_BT_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif +#if SOC_IEEE802154_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif + + uint32_t mask = 0; + if (inited_modules & sys_clk_dep_modules) { + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + } + if (inited_modules & modem_clk_dep_modules) { +#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +#endif + } + return ((inited_modules & mask) == (created_modules & mask)); } -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, BIT(0), 106) { -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP - sleep_clock_system_retention_init(); -#endif + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param); #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE - sleep_clock_modem_retention_init(); + init_param = (sleep_retention_module_init_param_t) { + .cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param); #endif return ESP_OK; } -#endif diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index 864c03a6af..adeddab186 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -285,19 +285,20 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void bool modem_domain_pd_allowed(void) { #if SOC_PM_MODEM_RETENTION_BY_REGDMA + const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); - const uint32_t mask_wifi = (const uint32_t) ( \ - BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | \ - BIT(SLEEP_RETENTION_MODULE_WIFI_BB)); - const uint32_t mask_ble = (const uint32_t) ( \ - BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | \ - BIT(SLEEP_RETENTION_MODULE_BT_BB)); - const uint32_t mask_154 = (const uint32_t) ( \ - BIT(SLEEP_RETENTION_MODULE_802154_MAC) | \ - BIT(SLEEP_RETENTION_MODULE_BT_BB)); - return (((created_modules & mask_wifi) == mask_wifi) || - ((created_modules & mask_ble) == mask_ble) || - ((created_modules & mask_154) == mask_154)); + + uint32_t mask = 0; +#if SOC_WIFI_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB); +#endif +#if SOC_BT_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif +#if SOC_IEEE802154_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif + return ((inited_modules & mask) == (created_modules & mask)); #else return false; /* MODEM power domain is controlled by each module (WiFi, Bluetooth or 15.4) of modem */ #endif From 4faf042c2136dda6184b00ec99dc15a22735a2c8 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 6 Feb 2024 10:45:35 +0800 Subject: [PATCH 07/16] change(wifi): use new retention api to implement wifi mac and bb retention --- components/esp_phy/src/phy_init.c | 53 +++++++++------ components/esp_wifi/esp32c6/esp_adapter.c | 20 ++++-- .../esp_wifi/include/esp_private/wifi.h | 14 +++- .../include/esp_private/wifi_os_adapter.h | 4 +- components/esp_wifi/lib | 2 +- components/esp_wifi/src/wifi_init.c | 68 +++++++++++++++++-- 6 files changed, 127 insertions(+), 34 deletions(-) diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 7f840c940b..2c3f5ff408 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -21,6 +21,7 @@ #include "esp_efuse.h" #include "esp_timer.h" #include "esp_private/esp_sleep_internal.h" +#include "esp_check.h" #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/portmacro.h" @@ -412,7 +413,20 @@ static uint8_t s_macbb_backup_mem_ref = 0; /* Reference of powering down MAC and BB */ static bool s_mac_bb_pu = true; #elif SOC_PM_MODEM_RETENTION_BY_REGDMA -static void *s_mac_bb_tx_base = NULL; +static esp_err_t sleep_retention_wifi_bb_init(void *arg) +{ + const static sleep_retention_entries_config_t bb_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */ + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */ + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */ + }; + esp_err_t err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi BB"); + ESP_LOGD(TAG, "WiFi BB sleep retention initialization"); + return ESP_OK; +} #endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA void esp_mac_bb_pd_mem_init(void) @@ -425,22 +439,18 @@ void esp_mac_bb_pd_mem_init(void) } _lock_release(&s_phy_access_lock); #elif SOC_PM_MODEM_RETENTION_BY_REGDMA - const static sleep_retention_entries_config_t bb_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */ - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */ - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_retention_wifi_bb_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) }; - esp_err_t err = ESP_OK; - _lock_acquire(&s_phy_access_lock); - s_mac_bb_tx_base = sleep_retention_find_link_by_id(0x0b01); - if (s_mac_bb_tx_base == NULL) { - err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB); - } - _lock_release(&s_phy_access_lock); + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_BB, &init_param); if (err != ESP_OK) { - ESP_LOGW(TAG, "failed to allocate memory for WiFi baseband retention"); + ESP_LOGW(TAG, "WiFi BB sleep retention init failed"); + return; + } + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi bb retention"); } #endif } @@ -456,10 +466,15 @@ void esp_mac_bb_pd_mem_deinit(void) } _lock_release(&s_phy_access_lock); #elif SOC_PM_MODEM_RETENTION_BY_REGDMA - _lock_acquire(&s_phy_access_lock); - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_WIFI_BB); - s_mac_bb_tx_base = NULL; - _lock_release(&s_phy_access_lock); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi bb retention"); + return; + } + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi BB sleep retention deinit defailed"); + } #endif } diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c index f61e946f2f..f7ae4ec3b6 100644 --- a/components/esp_wifi/esp32c6/esp_adapter.c +++ b/components/esp_wifi/esp32c6/esp_adapter.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 */ @@ -535,6 +535,18 @@ static void esp_phy_disable_wrapper(void) esp_phy_disable(PHY_MODEM_WIFI); } +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +static void regdma_link_set_write_wait_content_wrapper(void *addr, uint32_t value, uint32_t mask) +{ + regdma_link_set_write_wait_content(addr, value, mask); +} + +static void *sleep_retention_find_link_by_id_wrapper(int id) +{ + return sleep_retention_find_link_by_id(id); +} +#endif + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -650,10 +662,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, ._coex_register_start_cb = coex_register_start_cb_wrapper, #if SOC_PM_MODEM_RETENTION_BY_REGDMA - ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content, - ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id, - ._sleep_retention_entries_create = (int (*)(const void *, int, int, int))sleep_retention_entries_create, - ._sleep_retention_entries_destroy = sleep_retention_entries_destroy, + ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content_wrapper, + ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id_wrapper, #endif ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index fc7ae119b0..f7d3122dac 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -539,6 +539,18 @@ void esp_wifi_power_domain_on(void); */ void esp_wifi_power_domain_off(void); + +#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA) +/** + * @brief Get wifi mac sleep retention hardware context configuration and size + * + * @param config_size: the wifi mac hardware context configuration size + * + * @return A pointer that point to wifi mac sleep renteiton hardware context configuration table + */ +void * esp_wifi_internal_mac_retention_context_get(int *config_size); +#endif + #if CONFIG_MAC_BB_PD /** * @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping. diff --git a/components/esp_wifi/include/esp_private/wifi_os_adapter.h b/components/esp_wifi/include/esp_private/wifi_os_adapter.h index 84ace9fd1b..dcb03ab40f 100644 --- a/components/esp_wifi/include/esp_private/wifi_os_adapter.h +++ b/components/esp_wifi/include/esp_private/wifi_os_adapter.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -152,8 +152,6 @@ typedef struct { #if CONFIG_IDF_TARGET_ESP32C6 void (* _regdma_link_set_write_wait_content)(void *, uint32_t, uint32_t); void * (* _sleep_retention_find_link_by_id)(int); - int (* _sleep_retention_entries_create)(const void *, int, int, int); - void (* _sleep_retention_entries_destroy)(int); #endif int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 2c2bb53cc9..ebfe9899fd 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 2c2bb53cc9ba01b2c4f549526eab623d70c0a4a8 +Subproject commit ebfe9899fd51d35ffd1fd5a6e30b7bb9399876fc diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 4d4e741643..e70facdca0 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -12,6 +12,7 @@ #include "esp_private/sleep_modem.h" #include "esp_pm.h" #include "esp_sleep.h" +#include "esp_check.h" #include "esp_private/pm_impl.h" #include "esp_private/esp_clk.h" #include "esp_wpa.h" @@ -29,6 +30,10 @@ #include "esp_chip_info.h" #endif +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +#include "esp_private/sleep_retention.h" +#endif + static bool s_wifi_inited = false; #if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM) @@ -108,6 +113,41 @@ static void esp_wifi_set_log_level(void) esp_wifi_internal_set_log_level(wifi_log_level); } +#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA) +static esp_err_t init_wifi_mac_sleep_retention(void *arg) +{ + int config_size; + sleep_retention_entries_config_t *config = esp_wifi_internal_mac_retention_context_get(&config_size); + esp_err_t err = sleep_retention_entries_create(config, config_size, 3, SLEEP_RETENTION_MODULE_WIFI_MAC); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi MAC"); + ESP_LOGD(TAG, "WiFi MAC sleep retention initialization"); + return ESP_OK; +} +#endif + +#if CONFIG_MAC_BB_PD +static void esp_wifi_mac_pd_mem_init(void) +{ +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + esp_err_t err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi mac retention"); + } +#endif + esp_wifi_internal_set_mac_sleep(true); +} +static void esp_wifi_mac_pd_mem_deinit(void) +{ + esp_wifi_internal_set_mac_sleep(false); +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi mac retention"); + } +#endif +} +#endif + static esp_err_t wifi_deinit_internal(void) { esp_err_t err = ESP_OK; @@ -126,6 +166,11 @@ static esp_err_t wifi_deinit_internal(void) esp_nan_app_deinit(); #endif +#if CONFIG_MAC_BB_PD + esp_wifi_mac_pd_mem_deinit(); + esp_mac_bb_pd_mem_deinit(); +#endif + esp_supplicant_deinit(); err = esp_wifi_deinit_internal(); if (err != ESP_OK) { @@ -157,15 +202,17 @@ static esp_err_t wifi_deinit_internal(void) esp_sleep_disable_wifi_beacon_wakeup(); # endif #endif /* SOC_WIFI_HW_TSF */ +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi MAC sleep retention deinit failed"); + } +#endif /* SOC_PM_MODEM_RETENTION_BY_REGDMA */ #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #if CONFIG_MAC_BB_PD esp_unregister_mac_bb_pd_callback(pm_mac_sleep); esp_unregister_mac_bb_pu_callback(pm_mac_wakeup); #endif -#if CONFIG_MAC_BB_PD - esp_wifi_internal_set_mac_sleep(false); - esp_mac_bb_pd_mem_deinit(); -#endif #if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP esp_wifi_internal_modem_state_configure(false); esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); @@ -281,6 +328,17 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) #endif #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = init_wifi_mac_sleep_retention, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_WIFI_BB) | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_MAC, &init_param); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi MAC sleep retention init failed"); + } +#endif + #if CONFIG_MAC_BB_PD if (esp_register_mac_bb_pd_callback(pm_mac_sleep) != ESP_OK || esp_register_mac_bb_pu_callback(pm_mac_wakeup) != ESP_OK) { @@ -332,7 +390,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) if (result == ESP_OK) { #if CONFIG_MAC_BB_PD esp_mac_bb_pd_mem_init(); - esp_wifi_internal_set_mac_sleep(true); + esp_wifi_mac_pd_mem_init(); #endif esp_phy_modem_init(); #if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP From 9c8b54b886566208a0a1f0ca5ff730e266335d18 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 18 Apr 2024 15:13:56 +0800 Subject: [PATCH 08/16] change(esp_hw_support): use new retention api to implement gdma retention --- .../esp_hw_support/dma/gdma_sleep_retention.c | 64 +++++++++++++++---- .../sleep_gdma_retention_context.inc | 21 +++--- .../sleep_gdma_retention_context.inc | 21 +++--- components/hal/esp32c6/include/hal/gdma_ll.h | 2 + components/hal/esp32h2/include/hal/gdma_ll.h | 2 + 5 files changed, 74 insertions(+), 36 deletions(-) diff --git a/components/esp_hw_support/dma/gdma_sleep_retention.c b/components/esp_hw_support/dma/gdma_sleep_retention.c index d1b886d6d7..2b818c33ba 100644 --- a/components/esp_hw_support/dma/gdma_sleep_retention.c +++ b/components/esp_hw_support/dma/gdma_sleep_retention.c @@ -10,39 +10,75 @@ #include "soc/soc_caps.h" #include "esp_err.h" -#include "esp_check.h" +#if CONFIG_GDMA_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif #include "esp_log.h" +#include "esp_check.h" #include "esp_private/sleep_retention.h" #include "esp_private/esp_regdma.h" -#include "sleep_gdma_retention_context.inc" +#include "hal/gdma_ll.h" static const char *TAG = "gdma"; -#define SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 << (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) << pair_id) +typedef struct { + int group_id; + int pair_id; +} gdma_channel_retention_arg_t; -static esp_err_t sleep_modem_gdma_channel_retention_init(sleep_retention_module_bitmap_t module) +typedef struct gdma_chx_reg_ctx_link { + const sleep_retention_entries_config_t *link_list; + uint32_t link_num; +} gdma_chx_reg_ctx_link_t; + +#include "sleep_gdma_retention_context.inc" + +static esp_err_t sleep_gdma_channel_retention_init(void *arg) { - uint32_t id = __builtin_ctz(module / SLEEP_RETENTION_MODULE_GDMA_CH0); - esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[id].link_list, gdma_chx_regs_retention[id].link_num, REGDMA_LINK_PRI_7, module); + gdma_channel_retention_arg_t *parg = (gdma_channel_retention_arg_t *)arg; + int group_id = parg->group_id; + int pair_id = parg->pair_id; + + sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id); + esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[group_id][pair_id].link_list, gdma_chx_regs_retention[group_id][pair_id].link_num, REGDMA_LINK_PRI_7, module); if (err == ESP_OK) { - int group_id = id / SOC_GDMA_PAIRS_PER_GROUP_MAX; - int pair_id = id % SOC_GDMA_PAIRS_PER_GROUP_MAX; - ESP_LOGI(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id); + ESP_LOGD(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id); } + + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id); return err; } esp_err_t gdma_sleep_retention_init(int group_id, int pair_id) { - esp_err_t err = ESP_OK; - err = sleep_modem_gdma_channel_retention_init(SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id)); - ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id); + gdma_channel_retention_arg_t arg = { .group_id = group_id, .pair_id = pair_id }; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_gdma_channel_retention_init, .arg = &arg } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id); + esp_err_t err = sleep_retention_module_init(module, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(module); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for GDMA retention"); + } + } return err; } esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id)); - return ESP_OK;; + esp_err_t err = sleep_retention_module_free(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id)); + if (err != ESP_OK) { + ESP_LOGW(TAG, "GDMA pair (%d, %d) retention destroy failed", group_id, pair_id); + } + err = sleep_retention_module_deinit(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id)); + if (err != ESP_OK) { + ESP_LOGW(TAG, "GDMA pair (%d, %d) retention deinit failed", group_id, pair_id); + } + return err; } diff --git a/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc b/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc index 583b1168af..6528598a4a 100644 --- a/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc +++ b/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc @@ -50,32 +50,31 @@ static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = { GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG */ -#define G0P1_RETENTION_REGS_CNT_0 6 +#define G0P2_RETENTION_REGS_CNT_0 6 #define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG -#define G0P1_RETENTION_REGS_CNT_1 7 +#define G0P2_RETENTION_REGS_CNT_1 7 #define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000}; static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0}; static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \ - G0P1_RETENTION_REGS_CNT_0, 0, 0, \ + G0P2_RETENTION_REGS_CNT_0, 0, 0, \ g0p2_regs_map0[0], g0p2_regs_map0[1], \ g0p2_regs_map0[2], g0p2_regs_map0[3]), \ .owner = ENTRY(0) | ENTRY(2) }, [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ - G0P1_RETENTION_REGS_CNT_1, 0, 0, \ + G0P2_RETENTION_REGS_CNT_1, 0, 0, \ g0p2_regs_map1[0], g0p2_regs_map1[1], \ g0p2_regs_map1[2], g0p2_regs_map1[3]), \ .owner = ENTRY(0) | ENTRY(2) }, }; -static const struct { - const sleep_retention_entries_config_t *link_list; - uint32_t link_num; -} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX*SOC_GDMA_PAIRS_PER_GROUP_MAX] = { - [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, - [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, - [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} +const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = { + [0] = { + [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, + [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, + [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} + } }; diff --git a/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc b/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc index 583b1168af..6528598a4a 100644 --- a/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc +++ b/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc @@ -50,32 +50,31 @@ static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = { GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG */ -#define G0P1_RETENTION_REGS_CNT_0 6 +#define G0P2_RETENTION_REGS_CNT_0 6 #define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG -#define G0P1_RETENTION_REGS_CNT_1 7 +#define G0P2_RETENTION_REGS_CNT_1 7 #define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000}; static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0}; static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \ - G0P1_RETENTION_REGS_CNT_0, 0, 0, \ + G0P2_RETENTION_REGS_CNT_0, 0, 0, \ g0p2_regs_map0[0], g0p2_regs_map0[1], \ g0p2_regs_map0[2], g0p2_regs_map0[3]), \ .owner = ENTRY(0) | ENTRY(2) }, [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ - G0P1_RETENTION_REGS_CNT_1, 0, 0, \ + G0P2_RETENTION_REGS_CNT_1, 0, 0, \ g0p2_regs_map1[0], g0p2_regs_map1[1], \ g0p2_regs_map1[2], g0p2_regs_map1[3]), \ .owner = ENTRY(0) | ENTRY(2) }, }; -static const struct { - const sleep_retention_entries_config_t *link_list; - uint32_t link_num; -} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX*SOC_GDMA_PAIRS_PER_GROUP_MAX] = { - [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, - [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, - [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} +const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = { + [0] = { + [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, + [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, + [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} + } }; diff --git a/components/hal/esp32c6/include/hal/gdma_ll.h b/components/hal/esp32c6/include/hal/gdma_ll.h index bdccf27035..d2c2a26aab 100644 --- a/components/hal/esp32c6/include/hal/gdma_ll.h +++ b/components/hal/esp32c6/include/hal/gdma_ll.h @@ -18,6 +18,8 @@ extern "C" { #endif +#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 + (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) + pair_id) + #define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) #define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] diff --git a/components/hal/esp32h2/include/hal/gdma_ll.h b/components/hal/esp32h2/include/hal/gdma_ll.h index bdccf27035..d2c2a26aab 100644 --- a/components/hal/esp32h2/include/hal/gdma_ll.h +++ b/components/hal/esp32h2/include/hal/gdma_ll.h @@ -18,6 +18,8 @@ extern "C" { #endif +#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 + (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) + pair_id) + #define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) #define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] From 9f528096293f6a2b89e8c25e2410653232851650 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 6 Feb 2024 17:56:48 +0800 Subject: [PATCH 09/16] change(bt): use new retention api to implement BT mac and bb retention --- components/bt/controller/esp32c6/bt.c | 23 +++++++++++++++++++++-- components/bt/controller/esp32h2/bt.c | 23 +++++++++++++++++++++-- components/esp_phy/src/btbb_init.c | 27 +++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 1ee667b297..a9f9a3ba5b 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -512,9 +512,10 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; + int extra = *(int *)arg; const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { @@ -523,9 +524,27 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) return err; } +static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +{ + int retention_args = extra; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, + .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); + } + return err; +} + static void sleep_modem_ble_mac_modem_state_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); + if (err == ESP_OK) { + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); + assert(err == ESP_OK); + } } void sleep_modem_light_sleep_overhead_set(uint32_t overhead) diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 81b9cb1867..aecc3b2ab8 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -501,9 +501,10 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) } #ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE -static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; + int extra = *(int *)arg; const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { @@ -512,9 +513,27 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) return err; } +static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +{ + int retention_args = extra; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, + .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); + } + return err; +} + static void sleep_modem_ble_mac_modem_state_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); + if (err == ESP_OK) { + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); + assert(err == ESP_OK); + } } void sleep_modem_light_sleep_overhead_set(uint32_t overhead) diff --git a/components/esp_phy/src/btbb_init.c b/components/esp_phy/src/btbb_init.c index 4a1841cfda..24adfdd618 100644 --- a/components/esp_phy/src/btbb_init.c +++ b/components/esp_phy/src/btbb_init.c @@ -28,7 +28,7 @@ static const char* TAG = "btbb_init"; #define BTBB_LINK_OWNER ENTRY(0) | ENTRY(2) #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG -static esp_err_t btbb_sleep_retention_init(void) +static esp_err_t btbb_sleep_retention_init(void *arg) { const static sleep_retention_entries_config_t btbb_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x00), BB_PART_0_ADDR, BB_PART_0_ADDR, BB_PART_0_SIZE, 0, 0), .owner = BTBB_LINK_OWNER }, @@ -37,13 +37,20 @@ static esp_err_t btbb_sleep_retention_init(void) }; esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BT_BB); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for btbb retention"); - ESP_LOGI(TAG, "btbb sleep retention initialization"); + ESP_LOGD(TAG, "btbb sleep retention initialization"); return ESP_OK; } static void btbb_sleep_retention_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BT_BB); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BT_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to destroy sleep retention linked list for btbb retention"); + } + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BT_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Modem BT BB retention callback unregister failed"); + } } #endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE @@ -54,7 +61,19 @@ void esp_btbb_enable(void) if (s_btbb_access_ref == 0) { bt_bb_v2_init_cmplx(BTBB_ENABLE_VERSION_PRINT); #if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE - btbb_sleep_retention_init(); + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = btbb_sleep_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BT_BB, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BT_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for btbb retention"); + } + } else { + ESP_LOGW(TAG, "Modem BT BB retention callback register failed"); + } #endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE } s_btbb_access_ref++; From 376b2f74ed2580f1537a7ef487baae7ec82a7b8f Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 6 Feb 2024 18:04:36 +0800 Subject: [PATCH 10/16] change(ieee802154): use new sleep retention api to implement ieee802154 mac retention --- .../ieee802154/driver/esp_ieee802154_dev.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 803d387246..0b7b6aa85e 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -915,18 +915,33 @@ esp_err_t ieee802154_receive_at(uint32_t time) return ESP_OK; } -static esp_err_t ieee802154_sleep_init(void) -{ - esp_err_t err = ESP_OK; #if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +static esp_err_t ieee802154_sleep_retention_init(void *arg) +{ #define N_REGS_IEEE802154() (((IEEE802154_MAC_DATE_REG - IEEE802154_REG_BASE) / 4) + 1) const static sleep_retention_entries_config_t ieee802154_mac_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_IEEE802154_LINK(0x00), IEEE802154_REG_BASE, IEEE802154_REG_BASE, N_REGS_IEEE802154(), 0, 0), .owner = IEEE802154_LINK_OWNER }, }; - err = sleep_retention_entries_create(ieee802154_mac_regs_retention, ARRAY_SIZE(ieee802154_mac_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_802154_MAC); + esp_err_t err = sleep_retention_entries_create(ieee802154_mac_regs_retention, ARRAY_SIZE(ieee802154_mac_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_802154_MAC); ESP_RETURN_ON_ERROR(err, IEEE802154_TAG, "failed to allocate memory for ieee802154 mac retention"); - ESP_LOGI(IEEE802154_TAG, "ieee802154 mac sleep retention initialization"); + ESP_LOGD(IEEE802154_TAG, "ieee802154 mac sleep retention initialization"); + return err; +} +#endif +static esp_err_t ieee802154_sleep_init(void) +{ + esp_err_t err = ESP_OK; +#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = ieee802154_sleep_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + }; + err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_802154_MAC, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_802154_MAC); + } + ESP_RETURN_ON_ERROR(err, IEEE802154_TAG, "failed to create sleep retention linked list for ieee802154 mac retention"); #if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD sleep_modem_register_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); From 0e2806329153423ffd63eae9849d527ec5aa8ce4 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Fri, 10 Nov 2023 16:03:21 +0800 Subject: [PATCH 11/16] change(esp_hw_support): dump sleep retention context to io stream --- .../include/esp_private/esp_regdma.h | 4 +- .../include/esp_private/sleep_retention.h | 4 +- components/esp_hw_support/port/regdma_link.c | 70 +++++++++++-------- components/esp_hw_support/sleep_retention.c | 6 +- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 5f0a62eaab..a888c998f9 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -578,11 +578,11 @@ void regdma_link_stats(void *link, int entry); void regdma_link_set_write_wait_content(void *link, uint32_t value, uint32_t mask); /** - * @brief Print all node information of the REGDMA linked list indicated by the entry argument + * @brief Dump all node information of the REGDMA linked list indicated by the entry argument * @param link The REGDMA linkded list head pointer * @param entry For nodes that support branching, use the branch specified by entry argument recursively */ -void regdma_link_show_memories(void *link, int entry); +void regdma_link_dump(FILE *out, void *link, int entry); /** * @brief Update REGDMA linked list node next pointers 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 8772263e0c..e09aadc5e5 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -109,9 +109,9 @@ typedef enum { esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module); /** - * @brief Print all runtime sleep retention linked lists + * @brief Dump all runtime sleep retention linked lists */ -void sleep_retention_entries_show_memories(void); +void sleep_retention_dump_entries(FILE *out); /** * @brief Find the linked list node with the unique id diff --git a/components/esp_hw_support/port/regdma_link.c b/components/esp_hw_support/port/regdma_link.c index a51fb03d43..6ef401c5c3 100644 --- a/components/esp_hw_support/port/regdma_link.c +++ b/components/esp_hw_support/port/regdma_link.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 */ @@ -698,71 +698,81 @@ void * regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint } #if REGDMA_LINK_DBG -static const char *TAG = "regdma_link"; +static __attribute__((unused)) const char *TAG = "regdma_link"; -static void print_info_continuous_wrapper(void *link) +static void print_info_link_data(FILE *out, const uint32_t buf[], int len) +{ + for (int i = 0; i < len; i++) { + fprintf(out, ((i + 1) % 8) ? "%08lx " : "%08lx\n", buf[i]); + } + if (len % 8) { + fprintf(out, "\n"); + } +} + +static void print_info_continuous_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_continuous_t *cons = __containerof(link, regdma_link_continuous_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, restore:%x, buff:%x", - cons->stat.module, cons->stat.id, link, cons->head, cons->body.next, + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p\n", + cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next, cons->body.backup, cons->body.restore, cons->body.mem); - ESP_LOG_BUFFER_HEX(TAG, (const void *)cons->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); } -static void print_info_addr_map_wrapper(void *link) +static void print_info_addr_map_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_addr_map_t *map = __containerof(link, regdma_link_addr_map_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, restore:%x, buff:%x, map:{%x,%x,%x,%x}", - map->stat.module, map->stat.id, link, map->head, map->body.next, map->body.backup, + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n", + map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next, map->body.backup, map->body.restore, map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); - ESP_LOG_BUFFER_HEX(TAG, (const void *)map->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); } -static void print_info_write_wait_wrapper(void *link) +static void print_info_write_wait_wrapper(FILE *out, void *link) { regdma_link_write_wait_t *ww = __containerof(link, regdma_link_write_wait_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, value:%x, mask:%x", - ww->stat.module, ww->stat.id, link, ww->head, ww->body.next, + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, value:%lx, mask:%lx\n", + ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next, ww->body.backup, ww->body.value, ww->body.mask); } -static void print_info_branch_continuous_wrapper(void *link) +static void print_info_branch_continuous_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_continuous_t *cons = __containerof(link, regdma_link_branch_continuous_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, restore:%x, buff:%x", - cons->stat.module, cons->stat.id, link, cons->head, cons->body.next[0], cons->body.next[1], + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p\n", + cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next[0], cons->body.next[1], cons->body.next[2], cons->body.next[3], cons->body.backup, cons->body.restore, cons->body.mem); - ESP_LOG_BUFFER_HEX(TAG, (const void *)cons->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); } -static void print_info_branch_addr_map_wrapper(void *link) +static void print_info_branch_addr_map_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_addr_map_t *map = __containerof(link, regdma_link_branch_addr_map_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, restore:%x, buff:%x, map:{%x,%x,%x,%x}", - map->stat.module, map->stat.id, link, map->head, map->body.next[0], map->body.next[1], map->body.next[2], + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n", + map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next[0], map->body.next[1], map->body.next[2], map->body.next[3], map->body.backup, map->body.restore, map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); - ESP_LOG_BUFFER_HEX(TAG, (const void *)map->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); } -static void print_info_branch_write_wait_wrapper(void *link) +static void print_info_branch_write_wait_wrapper(FILE *out, void *link) { regdma_link_branch_write_wait_t *ww = __containerof(link, regdma_link_branch_write_wait_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, value:%x, mask:%x", - ww->stat.module, ww->stat.id, link, ww->head, ww->body.next[0], ww->body.next[1], + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, value:%lx, mask:%lx\n", + ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next[0], ww->body.next[1], ww->body.next[2], ww->body.next[3], ww->body.backup, ww->body.value, ww->body.mask); } -static void print_link_info(void *args, int entry, int depth) +static void print_link_info(FILE *out, void *args, int entry, int depth) { - typedef void (*prinf_fn_t)(void *); + typedef void (*prinf_fn_t)(FILE *, void *); const static prinf_fn_t prinf_fn[] = { [0] = (prinf_fn_t)print_info_continuous_wrapper, @@ -779,20 +789,20 @@ static void print_link_info(void *args, int entry, int depth) int it = (head.branch << 2) | head.mode; assert(it < ARRAY_SIZE(prinf_fn)); - (*prinf_fn[it])(args); + (*prinf_fn[it])(out, args); } -void regdma_link_show_memories(void *link, int entry) +void regdma_link_dump(FILE *out, void *link, int entry) { assert(entry < REGDMA_LINK_ENTRY_NUM); void *next = link; if (link) { do { - print_link_info(next, entry, 0); + print_link_info(out, next, entry, 0); } while ((next = regdma_link_get_next(next, entry)) != NULL); } else { - ESP_EARLY_LOGW(TAG, "This REGDMA linked list is empty!\n"); + fprintf(out, "This REGDMA linked list is empty!\n"); } } #endif diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 5966868c3a..9fea734f5c 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -304,13 +304,13 @@ static void sleep_retention_entries_stats(void) } #if REGDMA_LINK_DBG -void sleep_retention_entries_show_memories(void) +void sleep_retention_dump_entries(FILE *out) { _lock_acquire_recursive(&s_retention.lock); if (s_retention.highpri >= SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY && s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { for (int entry = 0; entry < ARRAY_SIZE(s_retention.lists[s_retention.highpri].entries); entry++) { - ESP_LOGW(TAG, "Print sleep retention entries[%d] memories:", entry); - regdma_link_show_memories(s_retention.lists[s_retention.highpri].entries[entry], entry); + fprintf(out, "\nsleep retention entries[%d] context:\n", entry); + regdma_link_dump(out, s_retention.lists[s_retention.highpri].entries[entry], entry); } } _lock_release_recursive(&s_retention.lock); From 8f9090b35146b9e1412c477495edcef819e540ce Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 30 Nov 2023 19:26:41 +0800 Subject: [PATCH 12/16] change(esp_hw_support): add adc retention module and it is dependencies on the clock modem --- .../esp_hw_support/include/esp_private/sleep_retention.h | 4 ++++ components/esp_hw_support/sleep_modes.c | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) 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 e09aadc5e5..14a058b451 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -40,6 +40,8 @@ typedef enum sleep_retention_module { * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + SLEEP_RETENTION_MODULE_ADC = 17, + SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, @@ -63,6 +65,8 @@ typedef enum sleep_retention_module_bitmap { * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index bdea40d337..a579a9f729 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2084,7 +2084,11 @@ static uint32_t get_power_down_flags(void) #endif #if SOC_PM_SUPPORT_MODEM_PD - if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed()) { + if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed() +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + && clock_domain_pd_allowed() +#endif + ) { pd_flags |= RTC_SLEEP_PD_MODEM; } #endif From 71d37432da3e4e4e78bcfe33a115f7a490350c72 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 29 Feb 2024 11:25:46 +0800 Subject: [PATCH 13/16] change(esp_hw_support): use power down peripheral in light sleep option to determine TOP to off --- components/esp_hw_support/sleep_system_peripheral.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 2025e0771c..8cad2cfbb2 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -245,11 +245,15 @@ error: bool peripheral_domain_pd_allowed(void) { +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); return ((inited_modules & mask) == (created_modules & mask)); +#else + return false; +#endif } #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP From ea3094a9a62fbf040aea6a97d16ccbc1e39b0de4 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Mon, 4 Mar 2024 17:13:29 +0800 Subject: [PATCH 14/16] change(ieee802154): add sleep deinit API --- .../ieee802154/driver/esp_ieee802154_dev.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 0b7b6aa85e..71e6355120 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -69,6 +69,7 @@ static portMUX_TYPE s_ieee802154_spinlock = portMUX_INITIALIZER_UNLOCKED; static intr_handle_t s_ieee802154_isr_handle = NULL; static esp_err_t ieee802154_sleep_init(void); +static esp_err_t ieee802154_sleep_deinit(void); static void next_operation(void); static esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool cca); @@ -710,12 +711,6 @@ void ieee802154_enable(void) void ieee802154_disable(void) { modem_clock_module_disable(ieee802154_periph.module); -#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE -#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD - sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, - sleep_modem_mac_bb_power_up_prepare); -#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD -#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE ieee802154_set_state(IEEE802154_STATE_DISABLE); } @@ -768,6 +763,7 @@ esp_err_t ieee802154_mac_deinit(void) ret = esp_intr_free(s_ieee802154_isr_handle); s_ieee802154_isr_handle = NULL; } + ret = ieee802154_sleep_deinit(); return ret; } @@ -950,6 +946,22 @@ static esp_err_t ieee802154_sleep_init(void) return err; } +static esp_err_t ieee802154_sleep_deinit(void) +{ + esp_err_t err = ESP_OK; +#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE + err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_802154_MAC); + if (err == ESP_OK) { + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_802154_MAC); + } +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD + sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, + sleep_modem_mac_bb_power_up_prepare); +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD +#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE + return err; +} + IRAM_ATTR void ieee802154_rf_disable(void) { if (s_rf_closed == false) { From 4066844908a8c76d985faf19e6ca9d3198990ce3 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Mon, 25 Mar 2024 16:06:03 +0800 Subject: [PATCH 15/16] fix(example): fixed app partition is too small for binary size --- examples/bluetooth/esp_hid_device/sdkconfig.defaults | 1 + examples/bluetooth/esp_hid_host/sdkconfig.defaults | 1 + examples/mesh/ip_internal_network/sdkconfig.defaults | 1 + 3 files changed, 3 insertions(+) diff --git a/examples/bluetooth/esp_hid_device/sdkconfig.defaults b/examples/bluetooth/esp_hid_device/sdkconfig.defaults index 644f74599d..b3baa94595 100644 --- a/examples/bluetooth/esp_hid_device/sdkconfig.defaults +++ b/examples/bluetooth/esp_hid_device/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BT_BLE_ENABLED=y CONFIG_BT_HID_ENABLED=y CONFIG_BT_HID_DEVICE_ENABLED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/bluetooth/esp_hid_host/sdkconfig.defaults b/examples/bluetooth/esp_hid_host/sdkconfig.defaults index 1c2104eacc..4ec0671c16 100644 --- a/examples/bluetooth/esp_hid_host/sdkconfig.defaults +++ b/examples/bluetooth/esp_hid_host/sdkconfig.defaults @@ -8,3 +8,4 @@ CONFIG_BT_HID_ENABLED=y CONFIG_BT_HID_HOST_ENABLED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y CONFIG_BT_GATTC_NOTIF_REG_MAX=16 +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/mesh/ip_internal_network/sdkconfig.defaults b/examples/mesh/ip_internal_network/sdkconfig.defaults index 95bb5df832..81c7be5f66 100644 --- a/examples/mesh/ip_internal_network/sdkconfig.defaults +++ b/examples/mesh/ip_internal_network/sdkconfig.defaults @@ -9,3 +9,4 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y From f20186fe02771e84e7f66483ae9d4d271762af53 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 28 Mar 2024 21:14:07 +0800 Subject: [PATCH 16/16] fix: modify some typos to ensure CI pipeline run pass --- .../esp_hw_support/include/esp_private/esp_regdma.h | 4 ++-- components/esp_hw_support/sleep_retention.c | 2 +- components/esp_phy/src/phy_init.c | 6 +++--- components/esp_wifi/include/esp_private/wifi.h | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index a888c998f9..5ad9b74497 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -625,7 +625,7 @@ void *regdma_find_module_link_tail(void *link, void *tail, int entry, uint32_t m /** * @brief Find the tail node of the previous module of the specified module in the REGDMA linked list - * indicated by the entry argument starting from the link argment to the end of the tail argument + * indicated by the entry argument starting from the link argument to the end of the tail argument * @param link The REGDMA linkded list head pointer * @param tail The REGDMA linkded list tail pointer * @param entry For nodes that support branching, use the branch specified by entry argument recursively @@ -636,7 +636,7 @@ void *regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint3 /** * @brief Find the head node of the next module of the specified module in the REGDMA linked list - * indicated by the entry argument starting from the link argment to the end of the tail argument + * indicated by the entry argument starting from the link argument to the end of the tail argument * @param link The REGDMA linkded list head pointer * @param tail The REGDMA linkded list tail pointer * @param entry For nodes that support branching, use the branch specified by entry argument recursively diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 9fea734f5c..c7b88c648a 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -124,7 +124,7 @@ typedef struct { * information according to the configuration information of the linked list * nodes. * The PMU module triggers REGDMA to use the corresponding linked list when - * swtiching between different power states. For example: + * switching between different power states. For example: * * +---------------+---------------+-------------------+-----------+ * | Current | The next | The entry will be | Retention | diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 2c3f5ff408..74fde92b8f 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -314,7 +314,7 @@ void esp_phy_disable(esp_phy_modem_t modem) #endif } #if CONFIG_IDF_TARGET_ESP32 - // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock + // Update WiFi MAC time before disable WiFi/BT common peripheral clock phy_update_wifi_mac_time(true, esp_timer_get_time()); #endif // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG @@ -473,7 +473,7 @@ void esp_mac_bb_pd_mem_deinit(void) } err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_BB); if (err != ESP_OK) { - ESP_LOGW(TAG, "WiFi BB sleep retention deinit defailed"); + ESP_LOGW(TAG, "WiFi BB sleep retention deinit failed"); } #endif } @@ -918,7 +918,7 @@ static uint8_t phy_find_bin_type_according_country(const char* country) if (i == sizeof(s_country_code_map_type_table)/sizeof(phy_country_to_bin_type_t)) { phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT; - ESP_LOGW(TAG, "Use the default certification code beacuse %c%c doesn't have a certificate", country[0], country[1]); + ESP_LOGW(TAG, "Use the default certification code because %c%c doesn't have a certificate", country[0], country[1]); } return phy_init_data_type; diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index f7d3122dac..12c4122f94 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -72,7 +72,7 @@ typedef enum { #define WIFI_LOG_SUBMODULE_INIT (1) /*logs related to initialization*/ #define WIFI_LOG_SUBMODULE_IOCTL (1<<1) /*logs related to API calling*/ #define WIFI_LOG_SUBMODULE_CONN (1<<2) /*logs related to connecting*/ -#define WIFI_LOG_SUBMODULE_SCAN (1<<3) /*logs related to scaning*/ +#define WIFI_LOG_SUBMODULE_SCAN (1<<3) /*logs related to scanning*/ /** @@ -164,9 +164,9 @@ typedef void (*wifi_netstack_buf_free_cb_t)(void *netstack_buf); * supports reference counter. * * @param wifi_if : wifi interface id - * @param buffer : the buffer to be tansmit + * @param buffer : the buffer to be transmit * @param len : the length of buffer - * @param netstack_buf : the netstack buffer related to bufffer + * @param netstack_buf : the netstack buffer related to buffer * * @return * - ESP_OK : Successfully transmit the buffer to wifi driver @@ -574,12 +574,12 @@ void pm_mac_wakeup(void); #endif /** - * @breif TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb() + * @brief TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb() * * @param ifidx The interface id that the tx callback has been triggered from * @param data Pointer to the data transmitted * @param data_len Length of the data transmitted - * @param txStatus True:if the data was transmitted sucessfully False: if data transmission failed + * @param txStatus True:if the data was transmitted successfully False: if data transmission failed */ typedef void (* wifi_tx_done_cb_t)(uint8_t ifidx, uint8_t *data, uint16_t *data_len, bool txStatus);