Merge branch 'feat/sleep_retention_depends_power_state_management' into 'master'

sleep retention multiple modules initialization and dependency management

Closes WIFI-5252 and IDFGH-11302

See merge request espressif/esp-idf!28941
pull/13550/head
Jiang Jiang Jian 2024-04-01 09:28:42 +08:00
commit 0c68b9b06c
38 zmienionych plików z 1123 dodań i 443 usunięć

Wyświetl plik

@ -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_BT_MAC_BB, 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)

Wyświetl plik

@ -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_BT_MAC_BB, 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)

Wyświetl plik

@ -276,6 +276,16 @@ static void i2c_hw_enable(i2c_port_t i2c_num)
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
static esp_err_t i2c_sleep_retention_init(void *arg)
{
i2c_port_t i2c_num = *(i2c_port_t *)arg;
esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(i2c_num));
ESP_RETURN_ON_ERROR(ret, I2C_TAG, "failed to allocate mem for sleep retention");
return ret;
}
#endif
/*
For i2c master mode, we don't need to use a buffer for the data, the APIs will execute the master commands
and return after all of the commands have been sent out or when error occurs. So when we send master commands,
@ -415,8 +425,13 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_
#endif // SOC_I2C_SUPPORT_SLAVE
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353
ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(i2c_num));
ESP_GOTO_ON_ERROR(ret, err, I2C_TAG, "failed to allocate mem for sleep retention");
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = i2c_sleep_retention_init, .arg = &i2c_num } }
};
ret = sleep_retention_module_init(I2C_SLEEP_RETENTION_MODULE(i2c_num), &init_param);
if (ret == ESP_OK) {
sleep_retention_module_allocate(I2C_SLEEP_RETENTION_MODULE(i2c_num));
}
#endif
return ESP_OK;
@ -471,7 +486,10 @@ esp_err_t i2c_driver_delete(i2c_port_t i2c_num)
p_i2c->intr_handle = NULL;
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353
sleep_retention_entries_destroy(I2C_SLEEP_RETENTION_MODULE(i2c_num));
esp_err_t err = sleep_retention_module_free(I2C_SLEEP_RETENTION_MODULE(i2c_num));
if (err == ESP_OK) {
err = sleep_retention_module_deinit(I2C_SLEEP_RETENTION_MODULE(i2c_num));
}
#endif
if (p_i2c->cmd_mux) {

Wyświetl plik

@ -41,6 +41,17 @@ typedef struct i2c_platform_t {
static i2c_platform_t s_i2c_platform = {}; // singleton platform
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
static esp_err_t s_i2c_sleep_retention_init(void *arg)
{
i2c_bus_t *bus = (i2c_bus_t *)arg;
i2c_port_num_t port_num = bus->port_num;
esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(port_num));
ESP_RETURN_ON_ERROR(ret, TAG, "failed to allocate mem for sleep retention");
return ret;
}
#endif
static esp_err_t s_i2c_bus_handle_acquire(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode)
{
#if CONFIG_I2C_ENABLE_DEBUG_LOG
@ -60,8 +71,13 @@ static esp_err_t s_i2c_bus_handle_acquire(i2c_port_num_t port_num, i2c_bus_handl
bus->bus_mode = mode;
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353
ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(port_num));
ESP_RETURN_ON_ERROR(ret, TAG, "failed to allocate mem for sleep retention");
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = s_i2c_sleep_retention_init, .arg = (void *)bus } }
};
ret = sleep_retention_module_init(I2C_SLEEP_RETENTION_MODULE(port_num), &init_param);
if (ret == ESP_OK) {
sleep_retention_module_allocate(I2C_SLEEP_RETENTION_MODULE(port_num));
}
#endif
// Enable the I2C module
@ -138,7 +154,10 @@ esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus)
do_deinitialize = true;
s_i2c_platform.buses[port_num] = NULL;
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353
sleep_retention_entries_destroy(I2C_SLEEP_RETENTION_MODULE(port_num));
esp_err_t err = sleep_retention_module_free(I2C_SLEEP_RETENTION_MODULE(port_num));
if (err == ESP_OK) {
err = sleep_retention_module_deinit(I2C_SLEEP_RETENTION_MODULE(port_num));
}
#endif
if (i2c_bus->intr_handle) {
ESP_RETURN_ON_ERROR(esp_intr_free(i2c_bus->intr_handle), TAG, "delete interrupt service failed");

Wyświetl plik

@ -18,7 +18,6 @@
#include "test_board.h"
#include "esp_sleep.h"
#include "esp_private/sleep_cpu.h"
#include "esp_ieee802154.h"
#include "esp_pm.h"
#define DATA_LENGTH 100
@ -69,7 +68,6 @@ static void i2c_master_write_sleep_retention_test(void)
TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1));
unity_wait_for_signal("i2c slave receive once, master to sleep");
TEST_ESP_OK(esp_ieee802154_enable());
TEST_ESP_OK(sleep_cpu_configure(true));
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(3 * 1000 * 1000));
TEST_ESP_OK(esp_light_sleep_start());
@ -87,7 +85,6 @@ static void i2c_master_write_sleep_retention_test(void)
unity_wait_for_signal("ready to delete");
TEST_ESP_OK(sleep_cpu_configure(false));
TEST_ESP_OK(esp_ieee802154_disable());
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
@ -131,7 +128,6 @@ static void i2c_slave_read_sleep_retention_test(void)
unity_send_signal("i2c slave receive once, master to sleep");
// Slave sleep as well..
TEST_ESP_OK(esp_ieee802154_enable());
TEST_ESP_OK(sleep_cpu_configure(true));
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(1 * 1000 * 1000));
TEST_ESP_OK(esp_light_sleep_start());
@ -152,7 +148,6 @@ static void i2c_slave_read_sleep_retention_test(void)
vQueueDelete(s_receive_queue);
unity_send_signal("ready to delete");
TEST_ESP_OK(sleep_cpu_configure(false));
TEST_ESP_OK(esp_ieee802154_disable());
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
}

Wyświetl plik

@ -11,8 +11,13 @@
#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"
@ -20,21 +25,54 @@
static const char *TAG = "gdma";
esp_err_t gdma_sleep_retention_init(int group_id, int pair_id)
typedef struct {
int group_id;
int pair_id;
} gdma_channel_retention_arg_t;
static esp_err_t sleep_gdma_channel_retention_init(void *arg)
{
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_GDMA, module);
if (err == ESP_OK) {
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_deinit(int group_id, int pair_id)
esp_err_t gdma_sleep_retention_init(int group_id, int pair_id)
{
esp_err_t err = ESP_OK;
sleep_retention_entries_destroy(GDMA_CH_RETENTION_GET_MODULE_ID(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)
{
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;
}

Wyświetl plik

@ -324,11 +324,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
@ -371,7 +371,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
@ -382,7 +382,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

Wyświetl plik

@ -42,32 +42,26 @@ extern "C" {
bool clock_domain_pd_allowed(void);
/**
* @brief PCR module power down initialize
* @brief SoC system clock retention initialize.
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args
* No memory for the retention link
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM not enough memory for system clock retention
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
*/
esp_err_t sleep_clock_system_retention_init(void);
esp_err_t sleep_clock_system_retention_init(void *arg);
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
/**
* @brief PCR module power down deinitialize
*/
void sleep_clock_system_retention_deinit(void);
/**
* @brief Modem syscon module power down initialize
* @brief Modem system clock retention initialize.
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args
* No memory for the retention link
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM not enough memory for modem clock retention
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
*/
esp_err_t sleep_clock_modem_retention_init(void);
/**
* @brief Modem syscon module power down deinitialize
*/
void sleep_clock_modem_retention_deinit(void);
esp_err_t sleep_clock_modem_retention_init(void *arg);
#endif
#ifdef __cplusplus
}

Wyświetl plik

@ -23,10 +23,26 @@ extern "C" {
* This file contains declarations of sleep retention related functions, it
* includes sleep retention list creation, destruction and debugging interfaces.
*/
typedef periph_retention_module_t sleep_retention_module_t;
typedef periph_retention_module_bitmap_t sleep_retention_module_bitmap_t;
typedef regdma_entry_buf_t sleep_retention_entries_t;
typedef regdma_entries_config_t 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
*
@ -34,26 +50,19 @@ typedef regdma_entries_config_t sleep_retention_entries_config_t;
* @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
* @brief Dump all runtime sleep retention linked lists
*/
void sleep_retention_entries_destroy(int module);
/**
* @brief Print 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
@ -71,6 +80,90 @@ 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
*
* 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 have successfully created a sleep
* retention context
*/
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
@ -81,18 +174,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

Wyświetl plik

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

Wyświetl plik

@ -10,7 +10,7 @@
static __attribute__((unused)) const char *TAG = "sleep_clock";
esp_err_t sleep_clock_system_retention_init(void)
esp_err_t sleep_clock_system_retention_init(void *arg)
{
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
#define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_1_REG - DR_REG_PCR_BASE) / 4) + 1)
@ -28,13 +28,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);
}
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
esp_err_t sleep_clock_modem_retention_init(void)
esp_err_t sleep_clock_modem_retention_init(void *arg)
{
#if CONFIG_IDF_TARGET_ESP32C5
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
@ -54,9 +49,4 @@ 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

Wyświetl plik

@ -10,7 +10,7 @@
static __attribute__((unused)) const char *TAG = "sleep_clock";
esp_err_t sleep_clock_system_retention_init(void)
esp_err_t sleep_clock_system_retention_init(void *arg)
{
#define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1)
@ -24,13 +24,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);
}
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
esp_err_t sleep_clock_modem_retention_init(void)
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)
@ -46,9 +41,4 @@ 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

Wyświetl plik

@ -12,7 +12,7 @@
static __attribute__((unused)) const char *TAG = "sleep_clock";
esp_err_t sleep_clock_system_retention_init(void)
esp_err_t sleep_clock_system_retention_init(void *arg)
{
#define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1)
@ -26,13 +26,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);
}
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
esp_err_t sleep_clock_modem_retention_init(void)
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)
#define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1)
@ -47,9 +42,4 @@ 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

Wyświetl plik

@ -9,7 +9,7 @@
static __attribute__((unused)) const char *TAG = "sleep_clock";
esp_err_t sleep_clock_system_retention_init(void)
esp_err_t sleep_clock_system_retention_init(void *arg)
{
#define N_REGS_PCR() (((HP_SYS_CLKRST_HPCORE_WDT_RESET_SOURCE0_REG - DR_REG_HP_SYS_CLKRST_BASE) / 4) + 1)
@ -26,8 +26,3 @@ esp_err_t sleep_clock_system_retention_init(void)
ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization");
return ESP_OK;
}
void sleep_clock_system_retention_deinit(void)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
}

Wyświetl plik

@ -701,71 +701,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,
@ -782,20 +792,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!");
fprintf(out, "This REGDMA linked list is empty!\n");
}
}
#endif

Wyświetl plik

@ -8,26 +8,52 @@
bool clock_domain_pd_allowed(void)
{
const uint32_t modules = sleep_retention_get_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
const uint32_t inited_modules = sleep_retention_get_inited_modules();
const uint32_t created_modules = sleep_retention_get_created_modules();
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 ((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 |= SLEEP_RETENTION_MODULE_CLOCK_SYSTEM;
}
if (inited_modules & modem_clk_dep_modules) {
#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED
mask |= 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, SECONDARY, 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

Wyświetl plik

@ -285,24 +285,21 @@ 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
bool modem_domain_pd_allowed = false;
const uint32_t modules = sleep_retention_get_modules();
const uint32_t inited_modules = sleep_retention_get_inited_modules();
const uint32_t created_modules = sleep_retention_get_created_modules();
uint32_t mask = 0;
#if SOC_WIFI_SUPPORTED
const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC |
SLEEP_RETENTION_MODULE_WIFI_BB);
modem_domain_pd_allowed |= ((modules & mask_wifi) == mask_wifi);
mask |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB);
#endif
#if SOC_BT_SUPPORTED
const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC |
SLEEP_RETENTION_MODULE_BT_BB);
modem_domain_pd_allowed |= ((modules & mask_ble) == mask_ble);
mask |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
#endif
#if SOC_IEEE802154_SUPPORTED
const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC |
SLEEP_RETENTION_MODULE_BT_BB);
modem_domain_pd_allowed |= ((modules & mask_154) == mask_154);
mask |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
#endif
return modem_domain_pd_allowed;
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

Wyświetl plik

@ -2136,7 +2136,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

Wyświetl plik

@ -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
*/
@ -38,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 |
@ -82,6 +168,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,
@ -91,22 +178,31 @@ typedef struct {
} lists[SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES];
_lock_t lock;
regdma_link_priority_t highpri;
uint32_t modules;
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, .modules = 0
.highpri = (uint8_t)-1, .inited_modules = 0, .created_modules = 0
};
#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 +210,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 +229,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 +253,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 +261,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 +271,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,
@ -208,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);
@ -246,7 +342,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 +353,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;
}
@ -322,12 +418,12 @@ 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);
}
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 +444,13 @@ 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_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,25 +458,21 @@ static void sleep_retention_entries_do_destroy(int module)
_lock_release_recursive(&s_retention.lock);
}
void sleep_retention_entries_destroy(int module)
static 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.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));
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);
}
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 +495,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 +534,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 +543,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_num2map(module);
sleep_retention_entries_join();
error:
@ -459,17 +551,16 @@ 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 (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;
}
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;
}
esp_err_t err = sleep_retention_entries_check_and_create_final_default();
if (err) goto error;
@ -493,9 +584,192 @@ 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_inited_modules(void)
{
return s_retention.modules;
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], &param->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

Wyświetl plik

@ -20,80 +20,79 @@
static __attribute__((unused)) const char *TAG = "sleep_sys_periph";
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)
{
esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, 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_SYS_PERIPH_HIGH, 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)
{
esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, 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_SYS_PERIPH_HIGH, 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;
}
#if SOC_APM_SUPPORTED
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)
{
esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM, 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_NON_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH);
if (err == ESP_OK) {
err = sleep_retention_entries_create(tee_apm_highpri_regs_retention, ARRAY_SIZE(tee_apm_highpri_regs_retention), REGDMA_LINK_PRI_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_TEE_APM);
err = sleep_retention_entries_create(tee_apm_highpri_regs_retention, ARRAY_SIZE(tee_apm_highpri_regs_retention), REGDMA_LINK_PRI_CRITICAL_TEE_APM, 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;
}
#endif
esp_err_t sleep_sys_periph_uart0_retention_init(void)
static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, 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_SYS_PERIPH_HIGH, 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)
{
esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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)
{
esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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)
{
esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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)
{
esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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), REGDMA_LINK_PRI_SYS_PERIPH_LOW, 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;
}
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_err_t sleep_sys_periph_l2_cache_retention_init(void)
{
esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_L2_CACHE);
esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (L2 Cache) retention");
ESP_LOGI(TAG, "L2 Cache sleep retention initialization");
return ESP_OK;
@ -103,39 +102,39 @@ esp_err_t sleep_sys_periph_l2_cache_retention_init(void)
#if SOC_PAU_IN_TOP_DOMAIN
esp_err_t sleep_pau_retention_init(void)
{
esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_REGDMA_SYSTEM);
esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention");
ESP_LOGI(TAG, "PAU sleep retention initialization");
return ESP_OK;
}
#endif
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;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
err = sleep_sys_periph_l2_cache_retention_init();
if(err) goto error;
#endif
#if SOC_APM_SUPPORTED
err = sleep_sys_periph_tee_apm_retention_init();
err = sleep_sys_periph_tee_apm_retention_init(arg);
if(err) goto error;
#endif
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(arg);
if(err) goto error;
err = sleep_sys_periph_systimer_retention_init();
#if SOC_PAU_IN_TOP_DOMAIN
if(err) goto error;
err = sleep_pau_retention_init();
#endif
@ -145,33 +144,31 @@ error:
bool peripheral_domain_pd_allowed(void)
{
const uint32_t modules = sleep_retention_get_modules();
uint32_t mask = 0;
#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));
mask |= SLEEP_RETENTION_MODULE_INTR_MATRIX;
mask |= SLEEP_RETENTION_MODULE_HP_SYSTEM;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
mask |= SLEEP_RETENTION_MODULE_L2_CACHE;
return ((inited_modules & mask) == (created_modules & mask));
#else
return false;
#endif
#if SOC_APM_SUPPORTED
mask |= SLEEP_RETENTION_MODULE_TEE_APM;
#endif
mask |= SLEEP_RETENTION_MODULE_UART0;
mask |= SLEEP_RETENTION_MODULE_TG0;
mask |= SLEEP_RETENTION_MODULE_IOMUX;
mask |= SLEEP_RETENTION_MODULE_SPIMEM;
mask |= SLEEP_RETENTION_MODULE_SYSTIMER;
#if SOC_PAU_IN_TOP_DOMAIN
mask |= SLEEP_RETENTION_MODULE_REGDMA_SYSTEM;
#endif
return ((modules & mask) == mask);
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, SECONDARY, 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

Wyświetl plik

@ -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_BT_MAC_BB, 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++;

Wyświetl plik

@ -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
*/
@ -21,6 +21,7 @@
#include "esp_efuse.h"
#include "esp_timer.h"
#include "esp_sleep.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
@ -418,7 +419,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)
@ -431,22 +445,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
}
@ -462,10 +472,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 failed");
}
#endif
}

Wyświetl plik

@ -536,6 +536,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,
@ -651,10 +663,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,

Wyświetl plik

@ -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
*/
@ -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
@ -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.
@ -562,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);

Wyświetl plik

@ -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 wifi_osi_funcs_t {
#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;

@ -1 +1 @@
Subproject commit 52c5fd6537b7a97ff11673afa90dfec6bba251b6
Subproject commit 4eac0d1c3d5e0663949b5c0364e7612d423d6205

Wyświetl plik

@ -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);
@ -282,6 +329,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) {
@ -333,7 +391,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

Wyświetl plik

@ -19,7 +19,7 @@
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_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)

Wyświetl plik

@ -19,7 +19,7 @@
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_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)

Wyświetl plik

@ -9,6 +9,7 @@
#pragma once
#include <stdlib.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/lp_system_struct.h"
#include "hal/misc.h"
@ -24,7 +25,7 @@ extern "C" {
* Set the flag to inform
* @param true: deepsleep false: lightsleep
*/
static inline void lp_sys_ll_inform_wakeup_type(bool dslp)
FORCE_INLINE_ATTR void lp_sys_ll_inform_wakeup_type(bool dslp)
{
if (dslp) {
REG_SET_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */
@ -34,27 +35,27 @@ static inline void lp_sys_ll_inform_wakeup_type(bool dslp)
}
}
static inline void lp_sys_ll_set_pau_aon_bypass(bool bypass)
FORCE_INLINE_ATTR void lp_sys_ll_set_pau_aon_bypass(bool bypass)
{
LP_SYS.backup_dma_cfg1.aon_bypass = bypass ? 1 : 0;
}
static inline void lp_sys_ll_set_pau_link_tout_thres(uint32_t tout)
FORCE_INLINE_ATTR void lp_sys_ll_set_pau_link_tout_thres(uint32_t tout)
{
LP_SYS.backup_dma_cfg0.link_tout_thres_aon = tout;
}
static inline void lp_sys_ll_set_pau_link_backup_tout_thres(uint32_t tout)
FORCE_INLINE_ATTR void lp_sys_ll_set_pau_link_backup_tout_thres(uint32_t tout)
{
LP_SYS.backup_dma_cfg0.link_backup_tout_thres_aon = tout;
}
static inline void lp_sys_ll_set_pau_reg_read_interval(uint32_t val)
FORCE_INLINE_ATTR void lp_sys_ll_set_pau_reg_read_interval(uint32_t val)
{
LP_SYS.backup_dma_cfg0.read_interval_aon = val;
}
static inline void lp_sys_ll_set_pau_link_addr(uint32_t addr)
FORCE_INLINE_ATTR void lp_sys_ll_set_pau_link_addr(uint32_t addr)
{
LP_SYS.backup_dma_cfg2.link_addr_aon = addr;
}

Wyświetl plik

@ -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;
}
@ -915,18 +911,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_IEEE802154, 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_IEEE802154, 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);
@ -935,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) {

Wyświetl plik

@ -13,32 +13,54 @@
extern "C" {
#endif
typedef enum periph_retention_module_bitmap {
typedef enum periph_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_ALL = (uint32_t)-1
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,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
typedef enum periph_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_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),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#ifdef __cplusplus

Wyświetl plik

@ -13,33 +13,56 @@
extern "C" {
#endif
typedef enum periph_retention_module_bitmap {
typedef enum periph_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_I2C0 = BIT(27),
SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1
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,
SLEEP_RETENTION_MODULE_I2C0 = 27,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
typedef enum periph_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_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),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#ifdef __cplusplus

Wyświetl plik

@ -13,33 +13,53 @@
extern "C" {
#endif
typedef enum periph_retention_module_bitmap {
typedef enum periph_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_I2C0 = BIT(27),
SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
SLEEP_RETENTION_MODULE_GDMA_CH0 = 24,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 25,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 26,
SLEEP_RETENTION_MODULE_I2C0 = 27,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
typedef enum periph_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_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),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#ifdef __cplusplus

Wyświetl plik

@ -13,32 +13,55 @@
extern "C" {
#endif
typedef enum periph_retention_module_bitmap {
typedef enum periph_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 BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12),
SLEEP_RETENTION_MODULE_BT_BB = BIT(13),
SLEEP_RETENTION_MODULE_802154_MAC = BIT(14),
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_I2C0 = BIT(27),
SLEEP_RETENTION_MODULE_I2C1 = BIT(28),
SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1
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,
SLEEP_RETENTION_MODULE_I2C0 = 27,
SLEEP_RETENTION_MODULE_I2C1 = 28,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
typedef enum periph_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 BLE and 802.15.4 */
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_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),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_I2C1 = BIT(SLEEP_RETENTION_MODULE_I2C1),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#ifdef __cplusplus

Wyświetl plik

@ -13,24 +13,27 @@
extern "C" {
#endif
typedef enum periph_retention_module_bitmap {
typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_MIN = 0,
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1),
SLEEP_RETENTION_MODULE_REGDMA_SYSTEM = BIT(2),
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(10),
SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(11),
SLEEP_RETENTION_MODULE_TEE_APM = BIT(12),
SLEEP_RETENTION_MODULE_UART0 = BIT(13),
SLEEP_RETENTION_MODULE_TG0 = BIT(14),
SLEEP_RETENTION_MODULE_IOMUX = BIT(15),
SLEEP_RETENTION_MODULE_SPIMEM = BIT(16),
SLEEP_RETENTION_MODULE_SYSTIMER = BIT(17),
SLEEP_RETENTION_MODULE_L2_CACHE = BIT(18),
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
typedef enum periph_retention_module_bitmap {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* 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_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#ifdef __cplusplus

Wyświetl plik

@ -6,3 +6,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

Wyświetl plik

@ -7,3 +7,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