1 /*
2  * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef __REGDMA_LINK_H__
7 #define __REGDMA_LINK_H__
8 
9 #include <stdint.h>
10 #include <stddef.h>
11 #include "esp_bit_defs.h"
12 #include "soc/soc_caps.h"
13 
14 #if SOC_PAU_SUPPORTED
15 #include "esp_regdma.h"
16 
17 #define FILL_PLINK_HEAD(_pl, _len, _mode, _branch, _sr, _sb, _eof) { \
18     _pl->head.length = _len;     \
19     _pl->head.mode   = _mode;    \
20     _pl->head.branch = _branch;   \
21     _pl->head.skip_r = _sr;      \
22     _pl->head.skip_b = _sb;      \
23     _pl->head.eof    = _eof;     \
24 }
25 
26 #define FILL_PLINK_STAT(_pl, _ref, _id, _module) { \
27     _pl->stat.ref    = _ref;     \
28     _pl->stat.id     = _id;      \
29     _pl->stat.module = _module;  \
30 }
31 
regdma_link_init_continuous(regdma_link_continuous_t * plink,void * buff,void * backup,int len,void * restore,void * next,bool skip_b,bool skip_r,int id,uint32_t module)32 static inline void * regdma_link_init_continuous(
33         regdma_link_continuous_t *plink, void *buff, void *backup, int len,
34             void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module)
35 {
36     assert(plink != NULL);
37     assert(buff !=NULL);
38 
39     FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_CONTINUOUS, 0, skip_r, skip_b, !next);
40     plink->body.next    = next;
41     plink->body.backup  = backup;
42     plink->body.restore = restore;
43     plink->body.mem     = buff;
44     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
45 
46     return (void *)plink;
47 }
48 
regdma_link_addr_map_count(uint32_t bitmap[4])49 static inline int regdma_link_addr_map_count(uint32_t bitmap[4])
50 {
51     return  __builtin_popcount(bitmap[0]) + \
52             __builtin_popcount(bitmap[1]) + \
53             __builtin_popcount(bitmap[2]) + \
54             __builtin_popcount(bitmap[3]);
55 }
56 
regdma_link_init_addr_map(regdma_link_addr_map_t * plink,void * buff,void * backup,uint32_t bitmap[4],int len,void * restore,void * next,bool skip_b,bool skip_r,int id,uint32_t module)57 static inline void * regdma_link_init_addr_map(
58         regdma_link_addr_map_t *plink, void *buff, void *backup, uint32_t bitmap[4],
59             int len, void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module)
60 {
61     assert(plink != NULL);
62     assert(buff != NULL);
63     assert(len == regdma_link_addr_map_count(bitmap));
64 
65     FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_ADDR_MAP, 0, skip_r, skip_b, !next);
66     plink->body.next    = next;
67     plink->body.backup  = backup;
68     plink->body.restore = restore;
69     plink->body.mem     = buff;
70     plink->body.map[0]  = bitmap[0];
71     plink->body.map[1]  = bitmap[1];
72     plink->body.map[2]  = bitmap[2];
73     plink->body.map[3]  = bitmap[3];
74     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
75 
76     return (void *)plink;
77 }
78 
regdma_link_init_write(regdma_link_write_wait_t * plink,void * backup,uint32_t value,uint32_t mask,void * next,bool skip_b,bool skip_r,int id,uint32_t module)79 static inline void * regdma_link_init_write(
80         regdma_link_write_wait_t *plink, void *backup, uint32_t value,
81             uint32_t mask, void *next, bool skip_b, bool skip_r, int id,
82                 uint32_t module)
83 {
84     assert(plink != NULL);
85 
86     FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WRITE, 0, skip_r, skip_b, !next);
87     plink->body.next    = next;
88     plink->body.backup  = backup;
89     plink->body.value   = value;
90     plink->body.mask    = mask;
91     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
92 
93     return (void *)plink;
94 }
95 
regdma_link_init_wait(regdma_link_write_wait_t * plink,void * backup,uint32_t value,uint32_t mask,void * next,bool skip_b,bool skip_r,int id,uint32_t module)96 static inline void * regdma_link_init_wait(
97         regdma_link_write_wait_t *plink, void *backup, uint32_t value,
98             uint32_t mask, void *next, bool skip_b, bool skip_r, int id,
99                 uint32_t module)
100 {
101     assert(plink != NULL);
102 
103     FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WAIT, 0, skip_r, skip_b, !next);
104     plink->body.next    = next;
105     plink->body.backup  = backup;
106     plink->body.value   = value;
107     plink->body.mask    = mask;
108     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
109 
110     return (void *)plink;
111 }
112 
regdma_link_init_branch_continuous(regdma_link_branch_continuous_t * plink,void * buff,void * backup,int len,void * restore,regdma_entry_buf_t * next,bool skip_b,bool skip_r,int id,uint32_t module)113 static inline void * regdma_link_init_branch_continuous(
114         regdma_link_branch_continuous_t *plink, void *buff, void *backup, int len, void *restore,
115             regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module)
116 {
117     assert(plink != NULL);
118     assert(buff !=NULL);
119 
120     FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_CONTINUOUS, 1, skip_r, skip_b, 0);
121     plink->body.backup  = backup;
122     plink->body.restore = restore;
123     plink->body.mem     = buff;
124     for (int i = 0; i < REGDMA_LINK_ENTRY_NUM; i++) {
125         plink->body.next[i] = (*next)[i];
126     }
127     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
128 
129     return (void *)plink;
130 }
131 
regdma_link_init_branch_addr_map(regdma_link_branch_addr_map_t * plink,void * buff,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)132 static inline void * regdma_link_init_branch_addr_map(
133         regdma_link_branch_addr_map_t *plink, void *buff, void *backup, uint32_t bitmap[4],
134             int len, void *restore, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id,
135                 uint32_t module)
136 {
137     assert(plink != NULL);
138     assert(buff != NULL);
139 
140     FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_ADDR_MAP, 1, skip_r, skip_b, 0);
141     plink->body.backup  = backup;
142     plink->body.restore = restore;
143     plink->body.mem     = buff;
144     memcpy(plink->body.next, *next, REGDMA_LINK_ENTRY_NUM * sizeof((*next)[0]));
145     plink->body.map[0]  = bitmap[0];
146     plink->body.map[1]  = bitmap[1];
147     plink->body.map[2]  = bitmap[2];
148     plink->body.map[3]  = bitmap[3];
149     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
150 
151     return (void *)plink;
152 }
153 
regdma_link_init_branch_write(regdma_link_branch_write_wait_t * plink,void * backup,uint32_t value,uint32_t mask,regdma_entry_buf_t * next,bool skip_b,bool skip_r,int id,uint32_t module)154 static inline void * regdma_link_init_branch_write(
155         regdma_link_branch_write_wait_t *plink, void *backup, uint32_t value, uint32_t mask,
156             regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module)
157 {
158     assert(plink != NULL);
159 
160     FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WRITE, 1, skip_r, skip_b, 0);
161     plink->body.backup  = backup;
162     plink->body.value   = value;
163     plink->body.mask    = mask;
164     for (int i = 0; i < REGDMA_LINK_ENTRY_NUM; i++) {
165         plink->body.next[i] = (*next)[i];
166     }
167     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
168 
169     return (void *)plink;
170 }
171 
regdma_link_init_branch_wait(regdma_link_branch_write_wait_t * plink,void * backup,uint32_t value,uint32_t mask,regdma_entry_buf_t * next,bool skip_b,bool skip_r,int id,uint32_t module)172 static inline void * regdma_link_init_branch_wait(
173         regdma_link_branch_write_wait_t *plink, void *backup, uint32_t value, uint32_t mask,
174             regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module)
175 {
176     assert(plink != NULL);
177 
178     FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WAIT, 1, skip_r, skip_b, 0);
179     plink->body.backup  = backup;
180     plink->body.value   = value;
181     plink->body.mask    = mask;
182     for (int i = 0; i < REGDMA_LINK_ENTRY_NUM; i++) {
183         plink->body.next[i] = (*next)[i];
184     }
185     FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
186 
187     return (void *)plink;
188 }
189 
regdma_link_update_stats(regdma_link_stats_t * stats,int entry,int depth)190 static inline void regdma_link_update_stats(regdma_link_stats_t *stats, int entry, int depth)
191 {
192     assert(stats != NULL);
193 
194     stats->ref |= BIT(entry);
195 }
196 
197 #endif // SOC_PAU_SUPPORTED
198 
199 #endif /* __REGDMA_LINK_H__ */
200