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