1 /*
2  * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 #include <stdint.h>
9 #include "sdkconfig.h"
10 #include "soc/soc_caps.h"
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #if SOC_PAU_SUPPORTED
17 #include "esp_regdma.h"
18 
19 /**
20  * @file sleep_retention.h
21  *
22  * This file contains declarations of sleep retention related functions, it
23  * includes sleep retention list creation, destruction and debugging interfaces.
24  */
25 
26 typedef enum sleep_retention_module {
27     SLEEP_RETENTION_MODULE_MIN          = 0,
28     /* clock module, which includes system and modem */
29     SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
30     SLEEP_RETENTION_MODULE_CLOCK_MODEM  = 2,
31 
32     /* modem module, which includes WiFi, BLE and 802.15.4 */
33     SLEEP_RETENTION_MODULE_WIFI_MAC     = 10,
34     SLEEP_RETENTION_MODULE_WIFI_BB      = 11,
35     SLEEP_RETENTION_MODULE_BLE_MAC      = 12,
36     SLEEP_RETENTION_MODULE_BT_BB        = 13,
37     SLEEP_RETENTION_MODULE_802154_MAC   = 14,
38 
39     /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
40      * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
41     SLEEP_RETENTION_MODULE_SYS_PERIPH   = 16,
42 
43     SLEEP_RETENTION_MODULE_ADC          = 17,
44 
45     SLEEP_RETENTION_MODULE_GDMA_CH0     = 24,
46     SLEEP_RETENTION_MODULE_GDMA_CH1     = 25,
47     SLEEP_RETENTION_MODULE_GDMA_CH2     = 26,
48 
49     SLEEP_RETENTION_MODULE_MAX          = 31
50 } sleep_retention_module_t;
51 
52 typedef enum sleep_retention_module_bitmap {
53     /* clock module, which includes system and modem */
54     SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
55     SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM  = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM),
56 
57     /* modem module, which includes WiFi, BLE and 802.15.4 */
58     SLEEP_RETENTION_MODULE_BM_WIFI_MAC     = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
59     SLEEP_RETENTION_MODULE_BM_WIFI_BB      = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
60     SLEEP_RETENTION_MODULE_BM_BLE_MAC      = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
61     SLEEP_RETENTION_MODULE_BM_BT_BB        = BIT(SLEEP_RETENTION_MODULE_BT_BB),
62     SLEEP_RETENTION_MODULE_BM_802154_MAC   = BIT(SLEEP_RETENTION_MODULE_802154_MAC),
63 
64     /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
65      * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
66     SLEEP_RETENTION_MODULE_BM_SYS_PERIPH   = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
67 
68     SLEEP_RETENTION_MODULE_BM_ADC          = BIT(SLEEP_RETENTION_MODULE_ADC),
69 
70     SLEEP_RETENTION_MODULE_BM_GDMA_CH0     = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
71     SLEEP_RETENTION_MODULE_BM_GDMA_CH1     = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
72     SLEEP_RETENTION_MODULE_BM_GDMA_CH2     = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
73 
74     SLEEP_RETENTION_MODULE_BM_ALL          = (uint32_t)-1
75 } sleep_retention_module_bitmap_t;
76 
77 typedef regdma_entry_buf_t sleep_retention_entries_t;
78 
79 typedef struct {
80     regdma_link_config_t    config;
81     uint32_t                owner;  /**< Indicates which regdma entries the current node will insert into */
82 } sleep_retention_entries_config_t;
83 
84 typedef esp_err_t (*sleep_retention_callback_t)(void *args);
85 
86 typedef struct {
87     sleep_retention_callback_t handle;
88     void *arg;
89 } sleep_retention_create_callback_t;
90 
91 typedef struct {
92     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 */
93 } sleep_retention_module_callbacks_t;
94 
95 typedef enum {
96     SLEEP_RETENTION_MODULE_ATTR_PASSIVE = 0x1
97 } sleep_retention_module_attribute_t;
98 
99 /**
100  * @brief Create a runtime sleep retention linked list
101  *
102  * @param retent   sleep retention linked list node configuration table
103  * @param num      the total number of sleep retention linked list configuration
104  *                 items
105  * @param priority the priority of the created sleep retention linked list
106  * @param module   the number of the module to which the created sleep retention
107  *                 linked list belongs
108  * @return
109  *      - ESP_OK on success
110  *      - ESP_ERR_NO_MEM not enough memory for sleep retention
111  *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
112  */
113 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);
114 
115 /**
116  * @brief Dump all runtime sleep retention linked lists
117  */
118 void sleep_retention_dump_entries(FILE *out);
119 
120 /**
121  * @brief Find the linked list node with the unique id
122  *
123  * @param  id the unique identifier of specified linked list node
124  *
125  * @return NULL or the address of the linked list node found
126  */
127 void * sleep_retention_find_link_by_id(int id);
128 
129 /**
130  * @brief Get the head pointer of all entry linked list of REGDMA
131  *
132  * @param  entries buffer for getting results
133  */
134 void sleep_retention_entries_get(sleep_retention_entries_t *entries);
135 
136 typedef struct sleep_retention_module_init_param {
137     sleep_retention_module_callbacks_t  cbs;        /*!< The callbacks list of the initialize module */
138     sleep_retention_module_attribute_t  attribute;  /*!< A bitmap indicating attribute of the initialize module */
139     sleep_retention_module_bitmap_t     depends;    /*!< A bitmap identifying all modules that the current module depends on */
140 } sleep_retention_module_init_param_t;
141 
142 /**
143  * @brief sleep retention initialization for the module
144  *
145  * @param module   the module number that needs initialization
146  * @param param    the initialize parameters for module sleep retention initialization
147  *
148  * @return
149  *      - ESP_OK on success
150  *      - ESP_ERR_NO_MEM not enough memory for sleep retention
151  *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
152  *      - ESP_ERR_INVALID_STATE if the retention context of module already been allocated
153  */
154 esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param);
155 
156 /**
157  * @brief sleep retention de-initialization for the module
158  *
159  * @param module   the module number that needs de-initialization
160  *
161  * @return
162  *      - ESP_OK on success
163  *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
164  *      - ESP_ERR_INVALID_STATE if the retention context of module already been allocated
165  */
166 esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module);
167 
168 /**
169  * @brief Allocate the sleep retention context for the module
170  *
171  * @param module   the module number that need to allocating sleep retention context
172  *
173  * @return
174  *      - ESP_OK on success
175  *      - ESP_ERR_NO_MEM not enough memory for sleep retention
176  *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
177  *      - ESP_ERR_INVALID_STATE if the module is de-initialized
178  *      - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE
179  */
180 esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module);
181 
182 /**
183  * @brief Free the sleep retention context for the module
184  *
185  * @param module   the module number that need to free sleep retention context
186  *
187  * @return
188  *      - ESP_OK on success
189  *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
190  *      - ESP_ERR_INVALID_STATE if the module is de-initialized
191  *      - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE
192  */
193 esp_err_t sleep_retention_module_free(sleep_retention_module_t module);
194 
195 /**
196  * @brief Get all initialized modules that require sleep retention
197  *
198  * This is an unprotected interface for getting a bitmap of all modules that
199  * require sleep retention.
200  *
201  * It can only be called by the sleep procedure.
202  *
203  * @return the bitmap for all modules that require sleep retention
204  */
205 uint32_t sleep_retention_get_inited_modules(void);
206 
207 /**
208  * @brief Get all created modules that require sleep retention
209  *
210  * This is an unprotected interface for getting a bitmap of all modules that
211  * require sleep retention.
212  *
213  * It can only be called by the sleep procedure.
214  *
215  * @return the bitmap for all modules that have successfully created a sleep
216  * retention context
217  */
218 uint32_t sleep_retention_get_created_modules(void);
219 
220 #if SOC_PM_RETENTION_HAS_CLOCK_BUG
221 /**
222  * @brief Software trigger REGDMA to do extra linked list retention
223  *
224  * @param backup_or_restore true for backup register context to memory
225  *                          or false for restore to register from memory
226  */
227 void sleep_retention_do_extra_retention(bool backup_or_restore);
228 #endif
229 
230 #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
231 /**
232  * @brief Software trigger REGDMA to do system linked list retention
233  *
234  * @param backup_or_restore true for backup register context to memory
235  *                          or false for restore to register from memory
236  */
237 void sleep_retention_do_system_retention(bool backup_or_restore);
238 #endif
239 
240 #endif // SOC_PAU_SUPPORTED
241 
242 #ifdef __cplusplus
243 }
244 #endif
245