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