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 
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "esp_assert.h"
12 #include "esp_macros.h"
13 #include "esp_err.h"
14 #include "esp_bit_defs.h"
15 #include "soc/soc_caps.h"
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 #if SOC_PAU_SUPPORTED
22 #include "hal/pau_types.h"
23 
24 #define REGDMA_LINK_DBG 0       /* Enable REGDMA link info dump apis*/
25 #define REGDMA_LINK_ENTRY_NUM   (PAU_REGDMA_LINK_NUM) /* Maximum number of REG DMA linked list entries */
26 
27 #define ENTRY(n)    (BIT(n))
28 
29 #define REGDMA_PHY_LINK(_pri)               ((0x00 << 8) | _pri)
30 #define REGDMA_PCR_LINK(_pri)               ((0x01 << 8) | _pri)
31 #define REGDMA_MODEMSYSCON_LINK(_pri)       ((0x02 << 8) | _pri)
32 #define REGDMA_MODEMLPCON_LINK(_pri)        ((0x03 << 8) | _pri)
33 
34 #define REGDMA_INTMTX_LINK(_pri)            ((0x0d << 8) | _pri)
35 #define REGDMA_HPSYS_LINK(_pri)             ((0x0e << 8) | _pri)
36 #define REGDMA_TEEAPM_LINK(_pri)            ((0x0f << 8) | _pri)
37 
38 #define REGDMA_UART_LINK(_pri)              ((0x10 << 8) | _pri)
39 #define REGDMA_TIMG_LINK(_pri)              ((0x11 << 8) | _pri)
40 #define REGDMA_IOMUX_LINK(_pri)             ((0x12 << 8) | _pri)
41 #define REGDMA_SPIMEM_LINK(_pri)            ((0x13 << 8) | _pri)
42 #define REGDMA_SYSTIMER_LINK(_pri)          ((0x14 << 8) | _pri)
43 #define REGDMA_BLE_MAC_LINK(_pri)           ((0x15 << 8) | _pri)
44 #define REGDMA_MODEM_BT_BB_LINK(_pri)       ((0x16 << 8) | _pri)
45 #define REGDMA_MODEM_IEEE802154_LINK(_pri)  ((0x17 << 8) | _pri)
46 #define REGDMA_MODEM_GDMA_LINK(_pri)        ((0x18 << 8) | _pri)
47 #define REGDMA_MODEM_FE_LINK(_pri)          ((0xFF << 8) | _pri)
48 
49 typedef enum {
50     REGDMA_LINK_PRI_0 = 0,
51     REGDMA_LINK_PRI_1,
52     REGDMA_LINK_PRI_2,
53     REGDMA_LINK_PRI_3,
54     REGDMA_LINK_PRI_4,
55     REGDMA_LINK_PRI_5,
56     REGDMA_LINK_PRI_6,
57     REGDMA_LINK_PRI_7,
58 } regdma_link_priority_t;
59 
60 typedef pau_regdma_link_addr_t  regdma_entry_buf_t;
61 
62 typedef enum regdma_link_mode {
63     REGDMA_LINK_MODE_CONTINUOUS = 0, /*!< Link used to backup registers with consecutive addresses */
64     REGDMA_LINK_MODE_ADDR_MAP,       /*!< Link used to backup selected registers according to bitmap */
65     REGDMA_LINK_MODE_WRITE,          /*!< Link used to direct write to registers*/
66     REGDMA_LINK_MODE_WAIT            /*!< Link used to wait for register value to meet condition*/
67 } regdma_link_mode_t;
68 
69 
70 #define REGDMA_LINK_PRI_SYS_CLK                 REGDMA_LINK_PRI_0
71 #define REGDMA_LINK_PRI_MODEM_CLK               REGDMA_LINK_PRI_1
72 #define REGDMA_LINK_PRI_CRITICAL_TEE_APM        REGDMA_LINK_PRI_2
73 #define REGDMA_LINK_PRI_WIFI_MAC_BB             REGDMA_LINK_PRI_3
74 #define REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM    REGDMA_LINK_PRI_4
75 #define REGDMA_LINK_PRI_BT_MAC_BB               REGDMA_LINK_PRI_5
76 #define REGDMA_LINK_PRI_SYS_PERIPH_HIGH         REGDMA_LINK_PRI_5 // INT_MTX & HP_SYSTEM & Console UART
77 #define REGDMA_LINK_PRI_SYS_PERIPH_LOW          REGDMA_LINK_PRI_6 // TG0 & IO MUX & SPI MEM & Systimer
78 #define REGDMA_LINK_PRI_IEEE802154              REGDMA_LINK_PRI_7
79 #define REGDMA_LINK_PRI_GDMA                    REGDMA_LINK_PRI_7
80 
81 typedef struct regdma_link_head {
82     volatile uint32_t length: 10, /* total count of registers that need to be backup or restore, unit: 1 word = 4 bytes */
83              reserve0: 6,
84              mode    : 4, /* mode of current link */
85              reserve1: 8,
86              branch  : 1, /* branch link flag */
87              skip_r  : 1, /* skip the current linked node when restore the register */
88              skip_b  : 1, /* skip the current linked node when backup the register */
89              eof     : 1; /* end of link */
90 } regdma_link_head_t;
91 
92 /* Continuous type linked list node body type definition */
93 typedef struct regdma_link_continuous_body {
94     volatile void       *next;
95     volatile void       *backup;
96     volatile void       *restore;
97     volatile void       *mem;
98 } regdma_link_continuous_body_t;
99 
100 /* Address Map type linked list node body type definition */
101 typedef struct regdma_link_addr_map_body {
102     volatile void       *next;
103     volatile void       *backup;
104     volatile void       *restore;
105     volatile void       *mem;
106     volatile uint32_t   map[4];
107 } regdma_link_addr_map_body_t;
108 
109 /* Write/Wait type linked list node body type definition */
110 typedef struct regdma_link_write_wait_body {
111     volatile void       *next;
112     volatile void       *backup;
113     volatile uint32_t   value;
114     volatile uint32_t   mask;
115 } regdma_link_write_wait_body_t;
116 
117 /* Branch Continuous type linked list node body type definition */
118 typedef struct regdma_link_branch_continuous_body {
119     regdma_entry_buf_t  next;
120     volatile void       *backup;
121     volatile void       *restore;
122     volatile void       *mem;
123 } regdma_link_branch_continuous_body_t;
124 
125 /* Branch Address Map type linked list node body type definition */
126 typedef struct regdma_link_branch_addr_map_body {
127     regdma_entry_buf_t  next;
128     volatile void       *backup;
129     volatile void       *restore;
130     volatile void       *mem;
131     volatile uint32_t   map[4];
132 } regdma_link_branch_addr_map_body_t;
133 
134 /* Branch Write/Wait type linked list node body type definition */
135 typedef struct regdma_link_branch_write_wait_body {
136     regdma_entry_buf_t  next;
137     volatile void       *backup;
138     volatile uint32_t   value;
139     volatile uint32_t   mask;
140 } regdma_link_branch_write_wait_body_t;
141 
142 ESP_STATIC_ASSERT(REGDMA_LINK_ENTRY_NUM < 16, "regdma link entry number should less 16");
143 typedef struct regdma_link_stats {
144     volatile uint32_t   ref: REGDMA_LINK_ENTRY_NUM, /* a bitmap, identifies which entry has referenced the current link */
145              reserve: 16-REGDMA_LINK_ENTRY_NUM,
146              id: 16; /* REGDMA linked list node unique identifier */
147     volatile uint32_t   module; /* a bitmap used to identify the module to which the current node belongs */
148 } regdma_link_stats_t;
149 
150 typedef struct regdma_link_continuous {
151     regdma_link_stats_t             stat;
152     regdma_link_head_t              head;
153     regdma_link_continuous_body_t   body;
154     volatile uint32_t               buff[0];
155 } regdma_link_continuous_t;
156 
157 typedef struct regdma_link_addr_map {
158     regdma_link_stats_t             stat;
159     regdma_link_head_t              head;
160     regdma_link_addr_map_body_t     body;
161     volatile uint32_t               buff[0];
162 } regdma_link_addr_map_t;
163 
164 typedef struct regdma_link_write_wait {
165     regdma_link_stats_t             stat;
166     regdma_link_head_t              head;
167     regdma_link_write_wait_body_t   body;
168 } regdma_link_write_wait_t;
169 
170 typedef struct regdma_link_branch_continuous {
171     regdma_link_stats_t                  stat;
172     regdma_link_head_t                   head;
173     regdma_link_branch_continuous_body_t body;
174     volatile uint32_t                    buff[0];
175 } regdma_link_branch_continuous_t;
176 
177 typedef struct regdma_link_branch_addr_map {
178     regdma_link_stats_t                  stat;
179     regdma_link_head_t                   head;
180     regdma_link_branch_addr_map_body_t   body;
181     volatile uint32_t                    buff[0];
182 } regdma_link_branch_addr_map_t;
183 
184 typedef struct regdma_link_branch_write_wait {
185     regdma_link_stats_t                  stat;
186     regdma_link_head_t                   head;
187     regdma_link_branch_write_wait_body_t body;
188 } regdma_link_branch_write_wait_t;
189 
190 typedef struct regdma_link_config {
191     regdma_link_head_t  head;
192     union {
193         regdma_link_continuous_body_t        continuous;
194         regdma_link_addr_map_body_t          addr_map;
195         regdma_link_write_wait_body_t        write_wait;
196     };
197     int id; /* REGDMA linked list node unique identifier */
198 } regdma_link_config_t;
199 
200 #define REGDMA_LINK_HEAD(plink)  (((regdma_link_config_t *)plink)->head)
201 
202 #define REGDMA_LINK_HEAD_INIT(_l, _m, _b, _sr, _sb) \
203     {                       \
204         .length = (_l),     \
205         .mode   = (_m),     \
206         .branch = (_b),     \
207         .skip_r = (_sr),    \
208         .skip_b = (_sb),    \
209         .eof    = 0         \
210     }
211 
212 #define REGDMA_LINK_CONTINUOUS_INIT(_id, _backup, _restore, _len, _skip_b, _skip_r) \
213     {                                       \
214         .head = REGDMA_LINK_HEAD_INIT(      \
215                 _len,                       \
216                 REGDMA_LINK_MODE_CONTINUOUS,\
217                 0,                          \
218                 _skip_r,                    \
219                 _skip_b                     \
220             ),                              \
221         .continuous = {                     \
222             .next    = NULL,                \
223             .backup  = (void *)_backup,     \
224             .restore = (void *)_restore,    \
225             .mem     = NULL                 \
226         },                                  \
227         .id = (_id)                         \
228     }
229 
230 #define REGDMA_LINK_ADDR_MAP_INIT(_id, _backup, _restore, _len, _skip_b, _skip_r, ...) \
231     {                                       \
232         .head = REGDMA_LINK_HEAD_INIT(      \
233                 _len,                       \
234                 REGDMA_LINK_MODE_ADDR_MAP,  \
235                 0,                          \
236                 _skip_r,                    \
237                 _skip_b                     \
238             ),                              \
239         .addr_map = {                       \
240             .next    = NULL,                \
241             .backup  = (void *)_backup,     \
242             .restore = (void *)_restore,    \
243             .mem     = NULL,                \
244             .map     = {__VA_ARGS__}        \
245         },                                  \
246         .id = (_id)                         \
247     }
248 
249 #define REGDMA_LINK_WRITE_INIT(_id, _backup, _val, _mask, _skip_b, _skip_r) \
250     {                                       \
251         .head = REGDMA_LINK_HEAD_INIT(      \
252                 0,                          \
253                 REGDMA_LINK_MODE_WRITE,     \
254                 0,                          \
255                 _skip_r,                    \
256                 _skip_b                     \
257             ),                              \
258         .write_wait = {                     \
259             .next    = NULL,                \
260             .backup  = (void *)_backup,     \
261             .value   = (_val),              \
262             .mask    = (_mask)              \
263         },                                  \
264         .id = (_id)                         \
265     }
266 
267 #define REGDMA_LINK_WAIT_INIT(_id, _backup, _val, _mask, _skip_b, _skip_r) \
268     {                                       \
269         .head = REGDMA_LINK_HEAD_INIT(      \
270                 0,                          \
271                 REGDMA_LINK_MODE_WAIT,      \
272                 0,                          \
273                 _skip_r,                    \
274                 _skip_b                     \
275             ),                              \
276         .write_wait = {                     \
277             .next    = NULL,                \
278             .backup  = (void *)_backup,     \
279             .value   = (_val),              \
280             .mask    = (_mask)              \
281         },                                  \
282         .id = (_id)                         \
283     }
284 
285 
286 /**
287  * @brief Create a REGDMA continuous type linked list node without retention buffer and the retention buffer is passed in by the caller
288  * @param  backup  Register address to be backed up by REGDMA
289  * @param  buff    Retention buffer, it needs to be allocated by the caller and passed in by this argument
290  * @param  len     Number of registers to be backed up
291  * @param  restore Register address to be restored by REGDMA
292  * @param  next    The next REGDMA linked list node
293  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
294  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
295  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
296  * @param  module  The module identifier of the current linked list node
297  * @return         Created REGDMA linked list node pointer
298  */
299 void *regdma_link_new_continuous(void *backup, void *buff, int len, void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
300 
301 /**
302  * @brief Create a REGDMA addr_map type linked list node without retention buffer and the retention buffer is passed in by the caller
303  * @param  backup  Register address to be backed up by REGDMA
304  * @param  buff    Retention buffer, it needs to be allocated by the caller and passed in by this argument
305  * @param  bitmap  The register bitmap that needs to be backed up and restored. when the bitmap corresponding to the
306  *                 register is 1, it needs to be backed up or restored, otherwise the corresponding register is skipped.
307  * @param  len     Number of registers to be backed up
308  * @param  restore Register address to be restored by REGDMA
309  * @param  next    The next REGDMA linked list node
310  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
311  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
312  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
313  * @param  module  The module identifier of the current linked list node
314  * @return         Created REGDMA linked list node pointer
315  */
316 void *regdma_link_new_addr_map(void *backup, void *buff, uint32_t bitmap[4], int len, void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
317 
318 /**
319  * @brief  Create a REGDMA write type linked list node without retention buffer and the retention buffer is passed in by the caller
320  * @param  backup Register address to be backed up by REGDMA
321  * @param  value  The value to be written to the register
322  * @param  mask   The mask of value
323  * @param  next   The next REGDMA linked list node
324  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
325  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
326  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
327  * @param  module The module identifier of the current linked list node
328  * @return        Created REGDMA linked list node pointer
329  */
330 void *regdma_link_new_write(void *backup, uint32_t value, uint32_t mask, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
331 
332 /**
333  * @brief Create a REGDMA write type linked list node without retention buffer and the retention buffer is passed in by the caller
334  * @param  backup Register address to be backed up by REGDMA
335  * @param  value  The register value that needs to be waited for
336  * @param  mask   The mask of value
337  * @param  next   The next REGDMA linked list node
338  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
339  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
340  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
341  * @param  module The module identifier of the current linked list node
342  * @return        Created REGDMA linked list node pointer
343  */
344 void *regdma_link_new_wait(void *backup, uint32_t value, uint32_t mask, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
345 
346 /**
347  * @brief Create a REGDMA continuouos branch list node without retention buffer and the retention buffer is passed in by the caller
348  * @param  backup  Register address to be backed up by REGDMA
349  * @param  buff    Retention buffer, it needs to be allocated by the caller and passed in by this argument
350  * @param  len     Number of registers to be backed up
351  * @param  restore Register address to be restored by REGDMA
352  * @param  next    The next REGDMA linked list node (supports up to 4 next pointers)
353  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
354  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
355  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
356  * @param  module  The module identifier of the current linked list node
357  * @return         Created REGDMA linked list node pointer
358  */
359 void *regdma_link_new_branch_continuous(void *backup, void *buff, int len, void *restore, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
360 
361 /**
362  * @brief Create a REGDMA addr_map branch list node without retention buffer and the retention buffer is passed in by the caller
363  * @param  backup  Register address to be backed up by REGDMA
364  * @param  buff    Retention buffer, it needs to be allocated by the caller and passed in by this argument
365  * @param  bitmap  The register bitmap that needs to be backed up and restored. when the bitmap corresponding to the
366  *                 register is 1, it needs to be backed up or restored, otherwise the corresponding register is skipped.
367  * @param  len     Number of registers to be backed up
368  * @param  restore Register address to be restored by REGDMA
369  * @param  next    The next REGDMA linked list node (supports up to 4 next pointers)
370  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
371  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
372  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
373  * @param  module  The module identifier of the current linked list node
374  * @return         Created REGDMA linked list node pointer
375  */
376 void *regdma_link_new_branch_addr_map(void *backup, void *buff, uint32_t bitmap[4], int len, void *restore, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
377 
378 /**
379  * @brief Create a REGDMA write branch list node without retention buffer and the retention buffer is passed in by the caller
380  * @param  backup Register address to be backed up by REGDMA
381  * @param  value  The value to be written to the register
382  * @param  mask   The mask of value
383  * @param  next   The next REGDMA linked list node (supports up to 4 next pointers)
384  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
385  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
386  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
387  * @param  module The module identifier of the current linked list node
388  * @return        Created REGDMA linked list node pointer
389  */
390 void *regdma_link_new_branch_write(void *backup, uint32_t value, uint32_t mask, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
391 
392 /**
393  * @brief Create a REGDMA wait branch list node without retention buffer and the retention buffer is passed in by the caller
394  * @param  backup Register address to be backed up by REGDMA
395  * @param  value  The register value that needs to be waited for
396  * @param  mask   The mask of value
397  * @param  next   The next REGDMA linked list node (supports up to 4 next pointers)
398  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
399  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
400  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
401  * @param  module The module identifier of the current linked list node
402  * @return        Created REGDMA linked list node pointer
403  */
404 void *regdma_link_new_branch_wait(void *backup, uint32_t value, uint32_t mask, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
405 
406 /**
407  * @brief Create a default REGDMA continuous type linked list node with retention buffer
408  * @param  backup  Register address to be backed up by REGDMA
409  * @param  len     Number of registers to be backed up
410  * @param  restore Register address to be restored by REGDMA
411  * @param  next    The next REGDMA linked list node
412  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
413  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
414  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
415  * @param  module  The module identifier of the current linked list node
416  * @return         Created REGDMA linked list node pointer
417  */
418 void *regdma_link_new_continuous_default(void *backup, int len, void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
419 
420 /**
421  * @brief Create a default REGDMA addr_map type linked list node with retention buffer
422  * @param  backup  Register address to be backed up by REGDMA
423  * @param  bitmap  The register bitmap that needs to be backed up and restored. when the bitmap corresponding to the
424  *                 register is 1, it needs to be backed up or restored, otherwise the corresponding register is skipped.
425  * @param  len     Number of registers to be backed up
426  * @param  restore Register address to be restored by REGDMA
427  * @param  next    The next REGDMA linked list node
428  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
429  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
430  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
431  * @param  module  The module identifier of the current linked list node
432  * @return         Created REGDMA linked list node pointer
433  */
434 void *regdma_link_new_addr_map_default(void *backup, uint32_t bitmap[4], int len, void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
435 
436 /**
437  * @brief Create a default REGDMA write type linked list node with retention buffer
438  * @param  backup Register address to be backed up by REGDMA
439  * @param  value  The register value that needs to be waited for
440  * @param  mask   The mask of value
441  * @param  next   The next REGDMA linked list node
442  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
443  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
444  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
445  * @param  module The module identifier of the current linked list node
446  * @return        Created REGDMA linked list node pointer
447  */
448 void *regdma_link_new_write_default(void *backup, uint32_t value, uint32_t mask, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
449 
450 /**
451  * @brief Create a default REGDMA wait type linked list node with retention buffer
452  * @param  backup Register address to be backed up by REGDMA
453  * @param  value  The register value that needs to be waited for
454  * @param  mask   The mask of value
455  * @param  next   The next REGDMA linked list node
456  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
457  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
458  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
459  * @param  module The module identifier of the current linked list node
460  * @return        Created REGDMA linked list node pointer
461  */
462 void *regdma_link_new_wait_default(void *backup, uint32_t value, uint32_t mask, void *next, bool skip_b, bool skip_r, int id, uint32_t module);
463 
464 /**
465  * @brief Create a default REGDMA continuous branch list node with retention buffer
466  * @param  backup  Register address to be backed up by REGDMA
467  * @param  len     Number of registers to be backed up
468  * @param  restore Register address to be restored by REGDMA
469  * @param  next    The next REGDMA linked list node (supports up to 4 next pointers)
470  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
471  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
472  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
473  * @param  module  The module identifier of the current linked list node
474  * @return         Created REGDMA linked list node pointer
475  */
476 void *regdma_link_new_branch_continuous_default(void *backup, int len, void *restore, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
477 
478 /**
479  * @brief Create a default REGDMA addr_map branch list node with retention buffer
480  * @param  backup  Register address to be backed up by REGDMA
481  * @param  bitmap  The register bitmap that needs to be backed up and restored. when the bitmap corresponding to the
482  *                 register is 1, it needs to be backed up or restored, otherwise the corresponding register is skipped.
483  * @param  len     Number of registers to be backed up
484  * @param  restore Register address to be restored by REGDMA
485  * @param  next    The next REGDMA linked list node (supports up to 4 next pointers)
486  * @param  skip_b  Skip backup, True means that REGDMA skips the current node when executing the backup task
487  * @param  skip_r  Skip restore, True means that REGDMA skips the current node when executing the restore task
488  * @param  id      REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
489  * @param  module  The module identifier of the current linked list node
490  * @return         Created REGDMA linked list node pointer
491  */
492 void *regdma_link_new_branch_addr_map_default(void *backup, uint32_t bitmap[4], int len, void *restore, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
493 
494 /**
495  * @brief Create a default REGDMA write branch list node with retention buffer
496  * @param  backup Register address to be backed up by REGDMA
497  * @param  value  The value to be written to the register
498  * @param  mask   The mask of value
499  * @param  next   The next REGDMA linked list node (supports up to 4 next pointers)
500  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
501  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
502  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
503  * @param  module The module identifier of the current linked list node
504  * @return        Created REGDMA linked list node pointer
505  */
506 void *regdma_link_new_branch_write_default(void *backup, uint32_t value, uint32_t mask, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
507 
508 /**
509  * @brief Create a default REGDMA wait branch list node with retention buffer
510  * @param  backup Register address to be backed up by REGDMA
511  * @param  value  The register value that needs to be waited for
512  * @param  mask   The mask of value
513  * @param  next   The next REGDMA linked list node (supports up to 4 next pointers)
514  * @param  skip_b Skip backup, True means that REGDMA skips the current node when executing the backup task
515  * @param  skip_r Skip restore, True means that REGDMA skips the current node when executing the restore task
516  * @param  id     REGDMA linked list node unique identifier, the caller needs to ensure that the id of each node is unique
517  * @param  module The module identifier of the current linked list node
518  * @return        Created REGDMA linked list node pointer
519  */
520 void *regdma_link_new_branch_wait_default(void *backup, uint32_t value, uint32_t mask, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module);
521 
522 /**
523  * @brief Create and initialize a REGDMA linked list node through configuration parameters
524  * @param  config REGDMA linked node configuration parameters
525  * @param  branch Is it a branch node
526  * @param  module The module identifier of the current linked list node
527  * @param  nentry The number of next pointers
528  * @param  args   next pointer, Since REGDMA supports 4 entries, it supports up to 4 variable parameter next pointers, and more will be ignored
529  * @return        Initialized REGDMA linked list head node pointer
530  */
531 void *regdma_link_init(const regdma_link_config_t *config, bool branch, uint32_t module, int nentry, ...);
532 
533 /**
534  * @brief Get REGDMA linked list node mode through configuration parameters
535  * @param  config REGDMA linked node configuration parameters
536  * @return        REGDMA linked list node mode
537  */
538 regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config);
539 
540 /**
541  * @brief Recurse the REGDMA linked list and call the hook subroutine for each node
542  * @param  link  The REGDMA linkded list head pointer
543  * @param  entry For nodes that support branching, use the branch specified by entry argument recursively
544  * @param  hook  Subroutines called during recursion, argument 1 is the pointer to the
545  *               recursive node object, argument 2 is the entry to which the node belongs
546  *               and the argument 3 is the position of the node in the current linked
547  *               list (from head to tail, the position of the head node is 0)
548  * @return       The REGDMA linked list node pointer indicated by the link argument
549  */
550 void *regdma_link_recursive(void *link, int entry, void (*hook)(void *, int, int));
551 
552 /**
553  * @brief Find the linked list node object by node position
554  * @param  link  The REGDMA linkded list head pointer
555  * @param  entry For nodes that support branching, use the branch specified by entry argument recursively
556  * @param  pos   Node position
557  * @return       The linked list node object pointer or NULL
558  */
559 void *regdma_find_link_by_pos(void *link, int entry, int pos);
560 
561 /**
562  * @brief Find the linked list node object by node unique identifier
563  * @param  link  The REGDMA linkded list head pointer
564  * @param  entry For nodes that support branching, use the branch specified by entry argument recursively
565  * @param  id    REGDMA linked list node unique identifier
566  * @return       The linked list node object pointer or NULL
567  */
568 void *regdma_find_link_by_id(void *link, int entry, int id);
569 
570 /**
571  * @brief Destroy the REGDMA linked list indicated by the entry argument
572  * @param link  The REGDMA linkded list head pointer
573  * @param entry For nodes that support branching, use the branch specified by entry argument recursively
574  */
575 void regdma_link_destroy(void *link, int entry);
576 
577 /**
578  * @brief Generate the statistics information of the REGDMA linked list indicated by the entry argument
579  * @param link  The REGDMA linkded list head pointer
580  * @param entry For nodes that support branching, use the branch specified by entry argument recursively
581  */
582 void regdma_link_stats(void *link, int entry);
583 
584 /**
585  * @brief Set the value and mask of write or wait type REGDMA linked list node
586  * @param link  Write or wait type REGDMA linked list node pointer
587  * @param value The value to be written to the register
588  * @param mask  The mask of value
589  */
590 void regdma_link_set_write_wait_content(void *link, uint32_t value, uint32_t mask);
591 
592 /**
593  * @brief Dump all node information of the REGDMA linked list indicated by the entry argument
594  * @param link  The REGDMA linkded list head pointer
595  * @param entry For nodes that support branching, use the branch specified by entry argument recursively
596  */
597 void regdma_link_dump(FILE *out, void *link, int entry);
598 
599 /**
600  * @brief Update REGDMA linked list node next pointers
601  * @param link  The pointer of the REGDMA linked list node whose next field will be modified
602  * @param nentry The number of next pointers
603  */
604 void regdma_link_update_next(void *link, int nentry, ...);
605 
606 /**
607  * @brief Get all node entry reference bitmaps from the start of the link argument to the
608  * end of the tail argument in the REGDMA linked list indicated by the entry argument
609  * @param  link  The REGDMA linkded list head pointer
610  * @param  tail  The REGDMA linkded list tail pointer
611  * @param  entry For nodes that support branching, use the branch specified by entry argument recursively
612  * @return       The entry reference bitmap of all nodes starting from the link argument to the end of the tail argument
613  */
614 uint32_t regdma_link_get_owner_bitmap(void *link, void *tail, int entry);
615 
616 /**
617  * @brief Find the head node of the specified module in the REGDMA linked list indicated by the
618  * entry argument starting from the link argument to the end of the tail argument
619  * @param  link   The REGDMA linkded list head pointer
620  * @param  tail   The REGDMA linkded list tail pointer
621  * @param  entry  For nodes that support branching, use the branch specified by entry argument recursively
622  * @param  module Module bitmap Identification
623  * @return        The found head node pointer or NULL
624  */
625 void *regdma_find_module_link_head(void *link, void *tail, int entry, uint32_t module);
626 
627 /**
628  * @brief Find the tail node of the specified module in the REGDMA linked list indicated by the
629  * entry argument starting from the link argument to the end of the tail argument
630  * @param  link   The REGDMA linkded list head pointer
631  * @param  tail   The REGDMA linkded list tail pointer
632  * @param  entry  For nodes that support branching, use the branch specified by entry argument recursively
633  * @param  module Module bitmap Identification
634  * @return        The found tail node pointer or NULL
635  */
636 void *regdma_find_module_link_tail(void *link, void *tail, int entry, uint32_t module);
637 
638 /**
639  * @brief Find the tail node of the previous module of the specified module in the REGDMA linked list
640  * indicated by the entry argument starting from the link argument to the end of the tail argument
641  * @param  link   The REGDMA linkded list head pointer
642  * @param  tail   The REGDMA linkded list tail pointer
643  * @param  entry  For nodes that support branching, use the branch specified by entry argument recursively
644  * @param  module Module bitmap Identification
645  * @return        The found tail node pointer or NULL
646  */
647 void *regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint32_t module);
648 
649 /**
650  * @brief Find the head node of the next module of the specified module in the REGDMA linked list
651  * indicated by the entry argument starting from the link argument to the end of the tail argument
652  * @param  link   The REGDMA linkded list head pointer
653  * @param  tail   The REGDMA linkded list tail pointer
654  * @param  entry  For nodes that support branching, use the branch specified by entry argument recursively
655  * @param  module Module bitmap Identification
656  * @return        The found head node pointer or NULL
657  */
658 void *regdma_find_next_module_link_head(void *link, void *tail, int entry, uint32_t module);
659 
660 #define regdma_link_init_safe(pcfg, branch, module, ...)    regdma_link_init((pcfg), (branch), (module), __VA_NARG__(__VA_ARGS__), ##__VA_ARGS__)
661 
662 #define regdma_link_update_next_safe(link, ...)             regdma_link_update_next((link), __VA_NARG__(__VA_ARGS__), ##__VA_ARGS__)
663 
664 #endif // SOC_PAU_SUPPORTED
665 
666 #ifdef __cplusplus
667 }
668 #endif
669