1 /*-
2 *******************************************************************************
3 Copyright (C) 2015 Annapurna Labs Ltd.
4
5 This file may be licensed under the terms of the Annapurna Labs Commercial
6 License Agreement.
7
8 Alternatively, this file can be distributed under the terms of the GNU General
9 Public License V2 as published by the Free Software Foundation and can be
10 found at http://www.gnu.org/licenses/gpl-2.0.html
11
12 Alternatively, redistribution and use in source and binary forms, with or
13 without modification, are permitted provided that the following conditions are
14 met:
15
16 * Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
18
19 * Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in
21 the documentation and/or other materials provided with the
22 distribution.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 *******************************************************************************/
36
37 /**
38 * @file al_hal_udma_config.c
39 *
40 * @brief Universal DMA HAL driver for configurations
41 *
42 */
43
44 #include <al_hal_common.h>
45 #include <al_hal_udma_regs.h>
46 #include <al_hal_udma_config.h>
47
48 /**************** Misc configurations *********************/
49 /** Configure AXI generic configuration */
al_udma_axi_set(struct udma_gen_axi * axi_regs,struct al_udma_axi_conf * axi)50 int al_udma_axi_set(struct udma_gen_axi *axi_regs,
51 struct al_udma_axi_conf *axi)
52 {
53 uint32_t reg;
54
55 al_reg_write32(&axi_regs->cfg_1, axi->axi_timeout);
56
57 reg = al_reg_read32(&axi_regs->cfg_2);
58 reg &= ~UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_MASK;
59 reg |= axi->arb_promotion;
60 al_reg_write32(&axi_regs->cfg_2, reg);
61
62 reg = al_reg_read32(&axi_regs->endian_cfg);
63 if (axi->swap_8_bytes == AL_TRUE)
64 reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN;
65 else
66 reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN;
67
68 if (axi->swap_s2m_data == AL_TRUE)
69 reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA;
70 else
71 reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA;
72
73 if (axi->swap_s2m_desc == AL_TRUE)
74 reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC;
75 else
76 reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC;
77
78 if (axi->swap_m2s_data == AL_TRUE)
79 reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA;
80 else
81 reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA;
82
83 if (axi->swap_m2s_desc == AL_TRUE)
84 reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC;
85 else
86 reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC;
87
88 al_reg_write32(&axi_regs->endian_cfg, reg);
89 return 0;
90 }
91
92 /* Configure UDMA AXI M2S configuration */
93 /** Configure AXI M2S submaster */
al_udma_m2s_axi_sm_set(struct al_udma_axi_submaster * m2s_sm,uint32_t * cfg_1,uint32_t * cfg_2,uint32_t * cfg_max_beats)94 static int al_udma_m2s_axi_sm_set(struct al_udma_axi_submaster *m2s_sm,
95 uint32_t *cfg_1, uint32_t *cfg_2,
96 uint32_t *cfg_max_beats)
97 {
98 uint32_t reg;
99 reg = al_reg_read32(cfg_1);
100 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK;
101 reg |= m2s_sm->id & UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK;
102 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK;
103 reg |= (m2s_sm->cache_type <<
104 UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_SHIFT) &
105 UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK;
106 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK;
107 reg |= (m2s_sm->burst << UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_SHIFT) &
108 UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK;
109 al_reg_write32(cfg_1, reg);
110
111 reg = al_reg_read32(cfg_2);
112 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK;
113 reg |= m2s_sm->used_ext & UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK;
114 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK;
115 reg |= (m2s_sm->bus_size <<
116 UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_SHIFT) &
117 UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK;
118 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK;
119 reg |= (m2s_sm->qos << UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_SHIFT) &
120 UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK;
121 reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK;
122 reg |= (m2s_sm->prot << UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_SHIFT) &
123 UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK;
124 al_reg_write32(cfg_2, reg);
125
126 reg = al_reg_read32(cfg_max_beats);
127 reg &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
128 reg |= m2s_sm->max_beats &
129 UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
130 al_reg_write32(cfg_max_beats, reg);
131
132 return 0;
133 }
134
135 /** Configure UDMA AXI M2S configuration */
al_udma_m2s_axi_set(struct al_udma * udma,struct al_udma_m2s_axi_conf * axi_m2s)136 int al_udma_m2s_axi_set(struct al_udma *udma,
137 struct al_udma_m2s_axi_conf *axi_m2s)
138 {
139 uint32_t reg;
140
141 al_udma_m2s_axi_sm_set(&axi_m2s->comp_write,
142 &udma->udma_regs->m2s.axi_m2s.comp_wr_cfg_1,
143 &udma->udma_regs->m2s.axi_m2s.comp_wr_cfg_2,
144 &udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1);
145
146 al_udma_m2s_axi_sm_set(&axi_m2s->data_read,
147 &udma->udma_regs->m2s.axi_m2s.data_rd_cfg_1,
148 &udma->udma_regs->m2s.axi_m2s.data_rd_cfg_2,
149 &udma->udma_regs->m2s.axi_m2s.data_rd_cfg);
150
151 al_udma_m2s_axi_sm_set(&axi_m2s->desc_read,
152 &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_1,
153 &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_2,
154 &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_3);
155
156 reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.data_rd_cfg);
157 if (axi_m2s->break_on_max_boundary == AL_TRUE)
158 reg |= UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY;
159 else
160 reg &= ~UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY;
161 al_reg_write32(&udma->udma_regs->m2s.axi_m2s.data_rd_cfg, reg);
162
163 reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1);
164 reg &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
165 reg |= (axi_m2s->min_axi_beats <<
166 UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT) &
167 UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
168 al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1, reg);
169
170 reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.ostand_cfg);
171 reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK;
172 reg |= axi_m2s->ostand_max_data_read &
173 UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK;
174 reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK;
175 reg |= (axi_m2s->ostand_max_desc_read <<
176 UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_SHIFT) &
177 UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK;
178 reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK;
179 reg |= (axi_m2s->ostand_max_comp_req <<
180 UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_SHIFT) &
181 UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK;
182 reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK;
183 reg |= (axi_m2s->ostand_max_comp_write <<
184 UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_SHIFT) &
185 UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK;
186 al_reg_write32(&udma->udma_regs->m2s.axi_m2s.ostand_cfg, reg);
187 return 0;
188 }
189
190 /** Configure AXI S2M submaster */
al_udma_s2m_axi_sm_set(struct al_udma_axi_submaster * s2m_sm,uint32_t * cfg_1,uint32_t * cfg_2,uint32_t * cfg_max_beats)191 static int al_udma_s2m_axi_sm_set(struct al_udma_axi_submaster *s2m_sm,
192 uint32_t *cfg_1, uint32_t *cfg_2,
193 uint32_t *cfg_max_beats)
194 {
195 uint32_t reg;
196 reg = al_reg_read32(cfg_1);
197 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK;
198 reg |= s2m_sm->id & UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK;
199 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK;
200 reg |= (s2m_sm->cache_type <<
201 UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_SHIFT) &
202 UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK;
203 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK;
204 reg |= (s2m_sm->burst << UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_SHIFT) &
205 UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK;
206 al_reg_write32(cfg_1, reg);
207
208 reg = al_reg_read32(cfg_2);
209 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK;
210 reg |= s2m_sm->used_ext & UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK;
211 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK;
212 reg |= (s2m_sm->bus_size << UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_SHIFT) &
213 UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK;
214 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK;
215 reg |= (s2m_sm->qos << UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_SHIFT) &
216 UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK;
217 reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK;
218 reg |= (s2m_sm->prot << UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_SHIFT) &
219 UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK;
220 al_reg_write32(cfg_2, reg);
221
222 reg = al_reg_read32(cfg_max_beats);
223 reg &= ~UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
224 reg |= s2m_sm->max_beats &
225 UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
226 al_reg_write32(cfg_max_beats, reg);
227
228 return 0;
229 }
230
231 /** Configure UDMA AXI S2M configuration */
al_udma_s2m_axi_set(struct al_udma * udma,struct al_udma_s2m_axi_conf * axi_s2m)232 int al_udma_s2m_axi_set(struct al_udma *udma,
233 struct al_udma_s2m_axi_conf *axi_s2m)
234 {
235
236 uint32_t reg;
237
238 al_udma_s2m_axi_sm_set(&axi_s2m->data_write,
239 &udma->udma_regs->s2m.axi_s2m.data_wr_cfg_1,
240 &udma->udma_regs->s2m.axi_s2m.data_wr_cfg_2,
241 &udma->udma_regs->s2m.axi_s2m.data_wr_cfg);
242
243 al_udma_s2m_axi_sm_set(&axi_s2m->desc_read,
244 &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_4,
245 &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_5,
246 &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3);
247
248 al_udma_s2m_axi_sm_set(&axi_s2m->comp_write,
249 &udma->udma_regs->s2m.axi_s2m.comp_wr_cfg_1,
250 &udma->udma_regs->s2m.axi_s2m.comp_wr_cfg_2,
251 &udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1);
252
253 reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3);
254 if (axi_s2m->break_on_max_boundary == AL_TRUE)
255 reg |= UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY;
256 else
257 reg &= ~UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY;
258 al_reg_write32(&udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3, reg);
259
260 reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1);
261 reg &= ~UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
262 reg |= (axi_s2m->min_axi_beats <<
263 UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT) &
264 UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
265 al_reg_write32(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1, reg);
266
267 reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_rd);
268 reg &= ~UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK;
269 reg |= axi_s2m->ostand_max_desc_read &
270 UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK;
271
272 reg &= ~UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK;
273 reg |= (axi_s2m->ack_fifo_depth <<
274 UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_SHIFT) &
275 UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK;
276
277 al_reg_write32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_rd, reg);
278
279 reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_wr);
280 reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK;
281 reg |= axi_s2m->ostand_max_data_req &
282 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK;
283 reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK;
284 reg |= (axi_s2m->ostand_max_data_write <<
285 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_SHIFT) &
286 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK;
287 reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK;
288 reg |= (axi_s2m->ostand_max_comp_req <<
289 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_SHIFT) &
290 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK;
291 reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK;
292 reg |= (axi_s2m->ostand_max_comp_write <<
293 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_SHIFT) &
294 UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK;
295 al_reg_write32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_wr, reg);
296 return 0;
297 }
298
299 /** M2S packet len configuration */
al_udma_m2s_packet_size_cfg_set(struct al_udma * udma,struct al_udma_m2s_pkt_len_conf * conf)300 int al_udma_m2s_packet_size_cfg_set(struct al_udma *udma,
301 struct al_udma_m2s_pkt_len_conf *conf)
302 {
303 uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s.cfg_len);
304 uint32_t max_supported_size = UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK;
305
306 al_assert(udma->type == UDMA_TX);
307
308 if (conf->encode_64k_as_zero == AL_TRUE)
309 max_supported_size += 1; /* 64K */
310
311 if (conf->max_pkt_size > max_supported_size) {
312 al_err("udma [%s]: requested max_pkt_size (0x%x) exceeds the"
313 "supported limit (0x%x)\n", udma->name,
314 conf->max_pkt_size, max_supported_size);
315 return -EINVAL;
316 }
317
318 reg &= ~UDMA_M2S_CFG_LEN_ENCODE_64K;
319 if (conf->encode_64k_as_zero == AL_TRUE)
320 reg |= UDMA_M2S_CFG_LEN_ENCODE_64K;
321 else
322 reg &= ~UDMA_M2S_CFG_LEN_ENCODE_64K;
323
324 reg &= ~UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK;
325 reg |= conf->max_pkt_size;
326
327 al_reg_write32(&udma->udma_regs->m2s.m2s.cfg_len, reg);
328 return 0;
329 }
330
331 /** Report Error - to be used for abort */
al_udma_err_report(struct al_udma * udma)332 void al_udma_err_report(struct al_udma *udma __attribute__((__unused__)))
333 {
334 return;
335 }
336
337 /** Statistics - TBD */
al_udma_stats_get(struct al_udma * udma)338 void al_udma_stats_get(struct al_udma *udma __attribute__((__unused__)))
339 {
340 return;
341 }
342
343 /** Configure UDMA M2S descriptor prefetch */
al_udma_m2s_pref_set(struct al_udma * udma,struct al_udma_m2s_desc_pref_conf * conf)344 int al_udma_m2s_pref_set(struct al_udma *udma,
345 struct al_udma_m2s_desc_pref_conf *conf)
346 {
347 uint32_t reg;
348
349 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1);
350 reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK;
351 reg |= conf->desc_fifo_depth;
352 al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1, reg);
353
354 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2);
355
356 if (conf->sch_mode == SRR)
357 reg |= UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
358 else if (conf->sch_mode == STRICT)
359 reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
360 else {
361 al_err("udma [%s]: requested descriptor preferch arbiter "
362 "mode (%d) is invalid\n", udma->name, conf->sch_mode);
363 return -EINVAL;
364 }
365 reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK;
366 reg |= conf->max_desc_per_packet &
367 UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK;
368 al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2, reg);
369
370 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3);
371 reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
372 reg |= conf->min_burst_below_thr &
373 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
374
375 reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
376 reg |=(conf->min_burst_above_thr <<
377 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) &
378 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
379
380 reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
381 reg |= (conf->pref_thr <<
382 UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) &
383 UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
384
385 al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3, reg);
386
387 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.data_cfg);
388 reg &= ~UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK;
389 reg |= conf->data_fifo_depth &
390 UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK;
391
392 reg &= ~UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK;
393 reg |= (conf->max_pkt_limit
394 << UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_SHIFT) &
395 UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK;
396 al_reg_write32(&udma->udma_regs->m2s.m2s_rd.data_cfg, reg);
397
398 return 0;
399 }
400
401 /** Ger the M2S UDMA descriptor prefetch */
al_udma_m2s_pref_get(struct al_udma * udma,struct al_udma_m2s_desc_pref_conf * conf)402 int al_udma_m2s_pref_get(struct al_udma *udma,
403 struct al_udma_m2s_desc_pref_conf *conf)
404 {
405 uint32_t reg;
406
407 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1);
408 conf->desc_fifo_depth =
409 AL_REG_FIELD_GET(reg, UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK,
410 UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_SHIFT);
411
412 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2);
413 if (reg & UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK)
414 conf->sch_mode = SRR;
415 else
416 conf->sch_mode = STRICT;
417 conf->max_desc_per_packet =
418 AL_REG_FIELD_GET(reg,
419 UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK,
420 UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT);
421
422 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3);
423
424 conf->min_burst_below_thr =
425 AL_REG_FIELD_GET(reg,
426 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK,
427 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_SHIFT);
428
429 conf->min_burst_above_thr =
430 AL_REG_FIELD_GET(reg,
431 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK,
432 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT);
433
434 conf->pref_thr = AL_REG_FIELD_GET(reg,
435 UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK,
436 UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT);
437 return 0;
438 }
439
440 /* set max descriptors */
al_udma_m2s_max_descs_set(struct al_udma * udma,uint8_t max_descs)441 int al_udma_m2s_max_descs_set(struct al_udma *udma, uint8_t max_descs)
442 {
443 uint32_t pref_thr = max_descs;
444 uint32_t min_burst_above_thr = 4;
445 al_assert(max_descs <= AL_UDMA_M2S_MAX_ALLOWED_DESCS_PER_PACKET);
446 al_assert(max_descs > 0);
447
448 /* increase min_burst_above_thr so larger burst can be used to fetch
449 * descriptors */
450 if (pref_thr >= 8)
451 min_burst_above_thr = 8;
452 else {
453 /* don't set prefetch threshold too low so we can have the
454 * min_burst_above_thr >= 4 */
455 pref_thr = 4;
456 }
457
458 al_reg_write32_masked(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2,
459 UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK,
460 max_descs << UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT);
461
462 al_reg_write32_masked(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3,
463 UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK |
464 UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK,
465 (pref_thr << UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) |
466 (min_burst_above_thr << UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT));
467
468 return 0;
469 }
470
471 /* set s2m max descriptors */
al_udma_s2m_max_descs_set(struct al_udma * udma,uint8_t max_descs)472 int al_udma_s2m_max_descs_set(struct al_udma *udma, uint8_t max_descs)
473 {
474 uint32_t pref_thr = max_descs;
475 uint32_t min_burst_above_thr = 4;
476 al_assert(max_descs <= AL_UDMA_S2M_MAX_ALLOWED_DESCS_PER_PACKET);
477 al_assert(max_descs > 0);
478
479 /* increase min_burst_above_thr so larger burst can be used to fetch
480 * descriptors */
481 if (pref_thr >= 8)
482 min_burst_above_thr = 8;
483 else
484 /* don't set prefetch threshold too low so we can have the
485 * min_burst_above_thr >= 4 */
486 pref_thr = 4;
487
488 al_reg_write32_masked(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3,
489 UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK |
490 UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK,
491 (pref_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) |
492 (min_burst_above_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT));
493
494 return 0;
495 }
496
al_udma_s2m_full_line_write_set(struct al_udma * udma,al_bool enable)497 int al_udma_s2m_full_line_write_set(struct al_udma *udma, al_bool enable)
498 {
499 uint32_t val = 0;
500
501 if (enable == AL_TRUE) {
502 val = UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE;
503 al_info("udma [%s]: full line write enabled\n", udma->name);
504 }
505
506 al_reg_write32_masked(&udma->udma_regs->s2m.s2m_wr.data_cfg_2,
507 UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE,
508 val);
509 return 0;
510 }
511
512 /** Configure S2M UDMA descriptor prefetch */
al_udma_s2m_pref_set(struct al_udma * udma,struct al_udma_s2m_desc_pref_conf * conf)513 int al_udma_s2m_pref_set(struct al_udma *udma,
514 struct al_udma_s2m_desc_pref_conf *conf)
515 {
516 uint32_t reg;
517
518 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_1);
519 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK;
520 reg |= conf->desc_fifo_depth;
521 al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_1, reg);
522
523 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_2);
524
525 if (conf->sch_mode == SRR)
526 reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
527 else if (conf->sch_mode == STRICT)
528 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
529 else {
530 al_err("udma [%s]: requested descriptor preferch arbiter "
531 "mode (%d) is invalid\n", udma->name, conf->sch_mode);
532 return -EINVAL;
533 }
534 if (conf->q_promotion == AL_TRUE)
535 reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION;
536 else
537 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION;
538
539 if (conf->force_promotion == AL_TRUE)
540 reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION;
541 else
542 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION;
543
544 if (conf->en_pref_prediction == AL_TRUE)
545 reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION;
546 else
547 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION;
548
549 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK;
550 reg |= (conf->promotion_th
551 << UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_SHIFT) &
552 UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK;
553
554 al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_2, reg);
555
556 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3);
557 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
558 reg |= (conf->pref_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) &
559 UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
560
561 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
562 reg |= conf->min_burst_below_thr &
563 UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
564
565 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
566 reg |=(conf->min_burst_above_thr <<
567 UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) &
568 UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
569
570 al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3, reg);
571
572 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_4);
573 reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK;
574 reg |= conf->a_full_thr & UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK;
575 al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_4, reg);
576
577
578 return 0;
579 }
580
581 /* Configure S2M UDMA data write */
al_udma_s2m_data_write_set(struct al_udma * udma,struct al_udma_s2m_data_write_conf * conf)582 int al_udma_s2m_data_write_set(struct al_udma *udma,
583 struct al_udma_s2m_data_write_conf *conf)
584 {
585 uint32_t reg;
586
587 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_1);
588 reg &= ~UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK;
589 reg |= conf->data_fifo_depth &
590 UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK;
591 reg &= ~UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK;
592 reg |= (conf->max_pkt_limit <<
593 UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_SHIFT) &
594 UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK;
595 reg &= ~UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK;
596 reg |= (conf->fifo_margin <<
597 UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_SHIFT) &
598 UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK;
599 al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_1, reg);
600
601 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2);
602 reg &= ~UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK;
603 reg |= conf->desc_wait_timer &
604 UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK;
605 reg &= ~(UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC |
606 UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC |
607 UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF |
608 UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE |
609 UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1);
610 reg |= conf->flags &
611 (UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC |
612 UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC |
613 UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF |
614 UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE |
615 UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1);
616 al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, reg);
617
618 return 0;
619 }
620
621 /* Configure S2M UDMA completion */
al_udma_s2m_completion_set(struct al_udma * udma,struct al_udma_s2m_completion_conf * conf)622 int al_udma_s2m_completion_set(struct al_udma *udma,
623 struct al_udma_s2m_completion_conf *conf)
624 {
625 uint32_t reg = al_reg_read32(&udma->udma_regs->s2m.s2m_comp.cfg_1c);
626 reg &= ~UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK;
627 reg |= conf->desc_size & UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK;
628 if (conf->cnt_words == AL_TRUE)
629 reg |= UDMA_S2M_COMP_CFG_1C_CNT_WORDS;
630 else
631 reg &= ~UDMA_S2M_COMP_CFG_1C_CNT_WORDS;
632 if (conf->q_promotion == AL_TRUE)
633 reg |= UDMA_S2M_COMP_CFG_1C_Q_PROMOTION;
634 else
635 reg &= ~UDMA_S2M_COMP_CFG_1C_Q_PROMOTION;
636 if (conf->force_rr == AL_TRUE)
637 reg |= UDMA_S2M_COMP_CFG_1C_FORCE_RR;
638 else
639 reg &= ~UDMA_S2M_COMP_CFG_1C_FORCE_RR;
640 reg &= ~UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK;
641 reg |= (conf->q_free_min << UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_SHIFT) &
642 UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK;
643 al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_1c, reg);
644
645 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_comp.cfg_2c);
646 reg &= ~UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK;
647 reg |= conf->comp_fifo_depth
648 & UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK;
649 reg &= ~UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK;
650 reg |= (conf->unack_fifo_depth
651 << UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_SHIFT) &
652 UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK;
653 al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_2c, reg);
654
655 al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_application_ack,
656 conf->timeout);
657 return 0;
658 }
659
660 /** Configure the M2S UDMA scheduling mode */
al_udma_m2s_sc_set(struct al_udma * udma,struct al_udma_m2s_dwrr_conf * sched)661 int al_udma_m2s_sc_set(struct al_udma *udma,
662 struct al_udma_m2s_dwrr_conf *sched)
663 {
664 uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_dwrr.cfg_sched);
665
666 if (sched->enable_dwrr == AL_TRUE)
667 reg |= UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR;
668 else
669 reg &= ~UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR;
670
671 if (sched->pkt_mode == AL_TRUE)
672 reg |= UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN;
673 else
674 reg &= ~UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN;
675
676 reg &= ~UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_MASK;
677 reg |= sched->weight << UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_SHIFT;
678 reg &= ~UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_MASK;
679 reg |= sched->inc_factor << UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_SHIFT;
680 al_reg_write32(&udma->udma_regs->m2s.m2s_dwrr.cfg_sched, reg);
681
682 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_dwrr.ctrl_deficit_cnt);
683 reg &= ~UDMA_M2S_DWRR_CTRL_DEFICIT_CNT_INIT_MASK;
684 reg |= sched->deficit_init_val;
685 al_reg_write32(&udma->udma_regs->m2s.m2s_dwrr.ctrl_deficit_cnt, reg);
686
687 return 0;
688 }
689
690 /** Configure the M2S UDMA rate limitation */
al_udma_m2s_rlimit_set(struct al_udma * udma,struct al_udma_m2s_rlimit_mode * mode)691 int al_udma_m2s_rlimit_set(struct al_udma *udma,
692 struct al_udma_m2s_rlimit_mode *mode)
693 {
694 uint32_t reg = al_reg_read32(
695 &udma->udma_regs->m2s.m2s_rate_limiter.gen_cfg);
696
697 if (mode->pkt_mode_en == AL_TRUE)
698 reg |= UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN;
699 else
700 reg &= ~UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN;
701 reg &= ~UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK;
702 reg |= mode->short_cycle_sz &
703 UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK;
704 al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.gen_cfg, reg);
705
706 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_token);
707 reg &= ~UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK;
708 reg |= mode->token_init_val &
709 UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK;
710 al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_token, reg);
711
712 return 0;
713 }
714
al_udma_m2s_rlimit_reset(struct al_udma * udma)715 int al_udma_m2s_rlimit_reset(struct al_udma *udma)
716 {
717 uint32_t reg = al_reg_read32(
718 &udma->udma_regs->m2s.m2s_rate_limiter.ctrl_cycle_cnt);
719 reg |= UDMA_M2S_RATE_LIMITER_CTRL_CYCLE_CNT_RST;
720 al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_cycle_cnt,
721 reg);
722 return 0;
723 }
724
725 /** Configure the Stream/Q rate limitation */
al_udma_common_rlimit_set(struct udma_rlimit_common * regs,struct al_udma_m2s_rlimit_cfg * conf)726 static int al_udma_common_rlimit_set(struct udma_rlimit_common *regs,
727 struct al_udma_m2s_rlimit_cfg *conf)
728 {
729 uint32_t reg = al_reg_read32(®s->cfg_1s);
730 /* mask max burst size, and enable/pause control bits */
731 reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK;
732 reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN;
733 reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE;
734 reg |= conf->max_burst_sz &
735 UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK;
736 al_reg_write32(®s->cfg_1s, reg);
737
738 reg = al_reg_read32(®s->cfg_cycle);
739 reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK;
740 reg |= conf->long_cycle_sz &
741 UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK;
742 al_reg_write32(®s->cfg_cycle, reg);
743
744 reg = al_reg_read32(®s->cfg_token_size_1);
745 reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK;
746 reg |= conf->long_cycle &
747 UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK;
748 al_reg_write32(®s->cfg_token_size_1, reg);
749
750 reg = al_reg_read32(®s->cfg_token_size_2);
751 reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK;
752 reg |= conf->short_cycle &
753 UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK;
754 al_reg_write32(®s->cfg_token_size_2, reg);
755
756 reg = al_reg_read32(®s->mask);
757 reg &= ~0xf; /* only bits 0-3 defined */
758 reg |= conf->mask & 0xf;
759 al_reg_write32(®s->mask, reg);
760
761 return 0;
762 }
763
al_udma_common_rlimit_act(struct udma_rlimit_common * regs,enum al_udma_m2s_rlimit_action act)764 static int al_udma_common_rlimit_act(struct udma_rlimit_common *regs,
765 enum al_udma_m2s_rlimit_action act)
766 {
767 uint32_t reg;
768
769 switch (act) {
770 case AL_UDMA_STRM_RLIMIT_ENABLE:
771 reg = al_reg_read32(®s->cfg_1s);
772 reg |= UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN;
773 al_reg_write32(®s->cfg_1s, reg);
774 break;
775 case AL_UDMA_STRM_RLIMIT_PAUSE:
776 reg = al_reg_read32(®s->cfg_1s);
777 reg |= UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE;
778 al_reg_write32(®s->cfg_1s, reg);
779 break;
780 case AL_UDMA_STRM_RLIMIT_RESET:
781 reg = al_reg_read32(®s->sw_ctrl);
782 reg |= UDMA_M2S_STREAM_RATE_LIMITER_SW_CTRL_RST_TOKEN_CNT;
783 al_reg_write32(®s->sw_ctrl, reg);
784 break;
785 default:
786 return -EINVAL;
787 }
788 return 0;
789 }
790
791 /** Configure the M2S Stream rate limitation */
al_udma_m2s_strm_rlimit_set(struct al_udma * udma,struct al_udma_m2s_rlimit_cfg * conf)792 int al_udma_m2s_strm_rlimit_set(struct al_udma *udma,
793 struct al_udma_m2s_rlimit_cfg *conf)
794 {
795 struct udma_rlimit_common *rlimit_regs =
796 &udma->udma_regs->m2s.m2s_stream_rate_limiter.rlimit;
797
798 return al_udma_common_rlimit_set(rlimit_regs, conf);
799 }
800
al_udma_m2s_strm_rlimit_act(struct al_udma * udma,enum al_udma_m2s_rlimit_action act)801 int al_udma_m2s_strm_rlimit_act(struct al_udma *udma,
802 enum al_udma_m2s_rlimit_action act)
803 {
804 struct udma_rlimit_common *rlimit_regs =
805 &udma->udma_regs->m2s.m2s_stream_rate_limiter.rlimit;
806
807 if (al_udma_common_rlimit_act(rlimit_regs, act) == -EINVAL) {
808 al_err("udma [%s]: udma stream rate limit invalid action "
809 "(%d)\n", udma->name, act);
810 return -EINVAL;
811 }
812 return 0;
813 }
814
815 /** Configure the M2S UDMA Q rate limitation */
al_udma_m2s_q_rlimit_set(struct al_udma_q * udma_q,struct al_udma_m2s_rlimit_cfg * conf)816 int al_udma_m2s_q_rlimit_set(struct al_udma_q *udma_q,
817 struct al_udma_m2s_rlimit_cfg *conf)
818 {
819 struct udma_rlimit_common *rlimit_regs = &udma_q->q_regs->m2s_q.rlimit;
820
821 return al_udma_common_rlimit_set(rlimit_regs, conf);
822 }
823
al_udma_m2s_q_rlimit_act(struct al_udma_q * udma_q,enum al_udma_m2s_rlimit_action act)824 int al_udma_m2s_q_rlimit_act(struct al_udma_q *udma_q,
825 enum al_udma_m2s_rlimit_action act)
826 {
827 struct udma_rlimit_common *rlimit_regs = &udma_q->q_regs->m2s_q.rlimit;
828
829 if (al_udma_common_rlimit_act(rlimit_regs, act) == -EINVAL) {
830 al_err("udma [%s %d]: udma stream rate limit invalid action "
831 "(%d)\n",
832 udma_q->udma->name, udma_q->qid, act);
833 return -EINVAL;
834 }
835 return 0;
836 }
837
838 /** Configure the M2S UDMA Q scheduling mode */
al_udma_m2s_q_sc_set(struct al_udma_q * udma_q,struct al_udma_m2s_q_dwrr_conf * conf)839 int al_udma_m2s_q_sc_set(struct al_udma_q *udma_q,
840 struct al_udma_m2s_q_dwrr_conf *conf)
841 {
842 uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_1);
843
844 reg &= ~UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK;
845 reg |= conf->max_deficit_cnt_sz &
846 UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK;
847 if (conf->strict == AL_TRUE)
848 reg |= UDMA_M2S_Q_DWRR_CFG_1_STRICT;
849 else
850 reg &= ~UDMA_M2S_Q_DWRR_CFG_1_STRICT;
851 al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_1, reg);
852
853 reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_2);
854 reg &= ~UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
855 reg |= (conf->axi_qos << UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_SHIFT) &
856 UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
857 reg &= ~UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
858 reg |= conf->q_qos & UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
859 al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_2, reg);
860
861 reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_3);
862 reg &= ~UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK;
863 reg |= conf->weight & UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK;
864 al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_3, reg);
865
866 return 0;
867 }
868
al_udma_m2s_q_sc_pause(struct al_udma_q * udma_q,al_bool set)869 int al_udma_m2s_q_sc_pause(struct al_udma_q *udma_q, al_bool set)
870 {
871 uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_1);
872
873 if (set == AL_TRUE)
874 reg |= UDMA_M2S_Q_DWRR_CFG_1_PAUSE;
875 else
876 reg &= ~UDMA_M2S_Q_DWRR_CFG_1_PAUSE;
877 al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_1, reg);
878
879 return 0;
880 }
881
al_udma_m2s_q_sc_reset(struct al_udma_q * udma_q)882 int al_udma_m2s_q_sc_reset(struct al_udma_q *udma_q)
883 {
884 uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_sw_ctrl);
885
886 reg |= UDMA_M2S_Q_DWRR_SW_CTRL_RST_CNT;
887 al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_sw_ctrl, reg);
888
889 return 0;
890 }
891
892 /** M2S UDMA completion and application timeouts */
al_udma_m2s_comp_timeouts_set(struct al_udma * udma,struct al_udma_m2s_comp_timeouts * conf)893 int al_udma_m2s_comp_timeouts_set(struct al_udma *udma,
894 struct al_udma_m2s_comp_timeouts *conf)
895 {
896 uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_1c);
897
898 if (conf->sch_mode == SRR)
899 reg |= UDMA_M2S_COMP_CFG_1C_FORCE_RR;
900 else if (conf->sch_mode == STRICT)
901 reg &= ~UDMA_M2S_COMP_CFG_1C_FORCE_RR;
902 else {
903 al_err("udma [%s]: requested completion descriptor preferch "
904 "arbiter mode (%d) is invalid\n",
905 udma->name, conf->sch_mode);
906 return -EINVAL;
907 }
908 if (conf->enable_q_promotion == AL_TRUE)
909 reg |= UDMA_M2S_COMP_CFG_1C_Q_PROMOTION;
910 else
911 reg &= ~UDMA_M2S_COMP_CFG_1C_Q_PROMOTION;
912 reg &= ~UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK;
913 reg |=
914 conf->comp_fifo_depth << UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT;
915
916 reg &= ~UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK;
917 reg |= conf->unack_fifo_depth
918 << UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT;
919 al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_1c, reg);
920
921 al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_coal
922 , conf->coal_timeout);
923
924 reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_application_ack);
925 reg &= ~UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK;
926 reg |= conf->app_timeout << UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT;
927 al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_application_ack, reg);
928 return 0;
929 }
930
al_udma_m2s_comp_timeouts_get(struct al_udma * udma,struct al_udma_m2s_comp_timeouts * conf)931 int al_udma_m2s_comp_timeouts_get(struct al_udma *udma,
932 struct al_udma_m2s_comp_timeouts *conf)
933 {
934 uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_1c);
935
936 if (reg & UDMA_M2S_COMP_CFG_1C_FORCE_RR)
937 conf->sch_mode = SRR;
938 else
939 conf->sch_mode = STRICT;
940
941 if (reg & UDMA_M2S_COMP_CFG_1C_Q_PROMOTION)
942 conf->enable_q_promotion = AL_TRUE;
943 else
944 conf->enable_q_promotion = AL_FALSE;
945
946 conf->comp_fifo_depth =
947 AL_REG_FIELD_GET(reg,
948 UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK,
949 UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT);
950 conf->unack_fifo_depth =
951 AL_REG_FIELD_GET(reg,
952 UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK,
953 UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT);
954
955 conf->coal_timeout = al_reg_read32(
956 &udma->udma_regs->m2s.m2s_comp.cfg_coal);
957
958 reg = al_reg_read32(
959 &udma->udma_regs->m2s.m2s_comp.cfg_application_ack);
960
961 conf->app_timeout =
962 AL_REG_FIELD_GET(reg,
963 UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK,
964 UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT);
965
966 return 0;
967 }
968
969 /**
970 * S2M UDMA configure no descriptors behaviour
971 */
al_udma_s2m_no_desc_cfg_set(struct al_udma * udma,al_bool drop_packet,al_bool gen_interrupt,uint32_t wait_for_desc_timeout)972 int al_udma_s2m_no_desc_cfg_set(struct al_udma *udma, al_bool drop_packet, al_bool gen_interrupt, uint32_t wait_for_desc_timeout)
973 {
974 uint32_t reg;
975
976 reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2);
977
978 if ((drop_packet == AL_TRUE) && (wait_for_desc_timeout == 0)) {
979 al_err("udam [%s]: setting timeout to 0 will cause the udma to wait forever instead of dropping the packet", udma->name);
980 return -EINVAL;
981 }
982
983 if (drop_packet == AL_TRUE)
984 reg |= UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC;
985 else
986 reg &= ~UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC;
987
988 if (gen_interrupt == AL_TRUE)
989 reg |= UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC;
990 else
991 reg &= ~UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC;
992
993 AL_REG_FIELD_SET(reg, UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK, UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_SHIFT, wait_for_desc_timeout);
994
995 al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, reg);
996
997 return 0;
998 }
999
1000 /* S2M UDMA configure a queue's completion update */
al_udma_s2m_q_compl_updade_config(struct al_udma_q * udma_q,al_bool enable)1001 int al_udma_s2m_q_compl_updade_config(struct al_udma_q *udma_q, al_bool enable)
1002 {
1003 uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg);
1004
1005 if (enable == AL_TRUE)
1006 reg |= UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
1007 else
1008 reg &= ~UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
1009
1010 al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg);
1011
1012 return 0;
1013 }
1014
1015 /* S2M UDMA configure a queue's completion descriptors coalescing */
al_udma_s2m_q_compl_coal_config(struct al_udma_q * udma_q,al_bool enable,uint32_t coal_timeout)1016 int al_udma_s2m_q_compl_coal_config(struct al_udma_q *udma_q, al_bool enable, uint32_t
1017 coal_timeout)
1018 {
1019 uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg);
1020
1021 if (enable == AL_TRUE)
1022 reg &= ~UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
1023 else
1024 reg |= UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
1025
1026 al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg);
1027
1028 al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg_2, coal_timeout);
1029 return 0;
1030 }
1031
1032 /* S2M UDMA configure completion descriptors write burst parameters */
al_udma_s2m_compl_desc_burst_config(struct al_udma * udma,uint16_t burst_size)1033 int al_udma_s2m_compl_desc_burst_config(struct al_udma *udma, uint16_t
1034 burst_size)
1035 {
1036 if ((burst_size != 64) && (burst_size != 128) && (burst_size != 256)) {
1037 al_err("%s: invalid burst_size value (%d)\n", __func__,
1038 burst_size);
1039 return -EINVAL;
1040 }
1041
1042 /* convert burst size from bytes to beats (16 byte) */
1043 burst_size = burst_size / 16;
1044 al_reg_write32_masked(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1,
1045 UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK |
1046 UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK,
1047 burst_size << UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT |
1048 burst_size << UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT);
1049 return 0;
1050 }
1051
1052 /* S2M UDMA configure a queue's completion descriptors header split */
al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q * udma_q,al_bool enable,al_bool force_hdr_split,uint32_t hdr_len)1053 int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q, al_bool enable,
1054 al_bool force_hdr_split, uint32_t hdr_len)
1055 {
1056 uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.pkt_cfg);
1057
1058 reg &= ~UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
1059 reg &= ~UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
1060 reg &= ~UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
1061
1062 if (enable == AL_TRUE) {
1063 reg |= hdr_len & UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
1064 reg |= UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
1065
1066 if (force_hdr_split == AL_TRUE)
1067 reg |= UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
1068 }
1069
1070 al_reg_write32(&udma_q->q_regs->s2m_q.pkt_cfg, reg);
1071
1072 return 0;
1073 }
1074
1075 /* S2M UDMA per queue completion configuration */
al_udma_s2m_q_comp_set(struct al_udma_q * udma_q,struct al_udma_s2m_q_comp_conf * conf)1076 int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q,
1077 struct al_udma_s2m_q_comp_conf *conf)
1078 {
1079 uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg);
1080 if (conf->en_comp_ring_update == AL_TRUE)
1081 reg |= UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
1082 else
1083 reg &= ~UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
1084
1085 if (conf->dis_comp_coal == AL_TRUE)
1086 reg |= UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
1087 else
1088 reg &= ~UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
1089
1090 al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg);
1091
1092 al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg_2, conf->comp_timer);
1093
1094 reg = al_reg_read32(&udma_q->q_regs->s2m_q.pkt_cfg);
1095
1096 reg &= ~UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
1097 reg |= conf->hdr_split_size & UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
1098 if (conf->force_hdr_split == AL_TRUE)
1099 reg |= UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
1100 else
1101 reg &= ~UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
1102 if (conf->en_hdr_split == AL_TRUE)
1103 reg |= UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
1104 else
1105 reg &= ~UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
1106
1107 al_reg_write32(&udma_q->q_regs->s2m_q.pkt_cfg, reg);
1108
1109 reg = al_reg_read32(&udma_q->q_regs->s2m_q.qos_cfg);
1110 reg &= ~UDMA_S2M_QOS_CFG_Q_QOS_MASK;
1111 reg |= conf->q_qos & UDMA_S2M_QOS_CFG_Q_QOS_MASK;
1112 al_reg_write32(&udma_q->q_regs->s2m_q.qos_cfg, reg);
1113
1114 return 0;
1115 }
1116
1117 /* UDMA Target-ID control configuration per queue */
al_udma_gen_tgtid_conf_queue_set(struct unit_regs * unit_regs,struct al_udma_gen_tgtid_conf * conf,uint32_t qid)1118 void al_udma_gen_tgtid_conf_queue_set(
1119 struct unit_regs *unit_regs,
1120 struct al_udma_gen_tgtid_conf *conf,
1121 uint32_t qid)
1122 {
1123 uint32_t *tx_tgtid_reg, *rx_tgtid_reg, *tx_tgtaddr_reg, *rx_tgtaddr_reg;
1124 unsigned int rev_id;
1125
1126 al_assert(qid < DMA_MAX_Q);
1127 rev_id = al_udma_get_revision(unit_regs);
1128
1129 /* Target-ID TX DESC EN */
1130 al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
1131 (conf->tx_q_conf[qid].desc_en << qid) <<
1132 UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT,
1133 (conf->tx_q_conf[qid].desc_en << qid) <<
1134 UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT);
1135
1136 /* Target-ID TX QUEUE EN */
1137 al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
1138 (conf->tx_q_conf[qid].queue_en << qid) <<
1139 UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT,
1140 (conf->tx_q_conf[qid].queue_en << qid) <<
1141 UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT);
1142
1143 /* Target-ID RX DESC EN */
1144 al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
1145 (conf->rx_q_conf[qid].desc_en << qid) <<
1146 UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT,
1147 (conf->rx_q_conf[qid].desc_en << qid) <<
1148 UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT);
1149
1150 /* Target-ID RX QUEUE EN */
1151 al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
1152 (conf->rx_q_conf[qid].queue_en << qid) <<
1153 UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT,
1154 (conf->rx_q_conf[qid].queue_en << qid) <<
1155 UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT);
1156
1157 switch (qid) {
1158 case 0:
1159 case 1:
1160 tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_1;
1161 rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_3;
1162 tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_0;
1163 rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_2;
1164 break;
1165 case 2:
1166 case 3:
1167 tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_2;
1168 rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_4;
1169 tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_1;
1170 rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_3;
1171 break;
1172 default:
1173 al_assert(AL_FALSE);
1174 return;
1175 }
1176
1177 al_reg_write32_masked(tx_tgtid_reg,
1178 UDMA_GEN_TGTID_CFG_TGTID_MASK(qid),
1179 conf->tx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid));
1180
1181 al_reg_write32_masked(rx_tgtid_reg,
1182 UDMA_GEN_TGTID_CFG_TGTID_MASK(qid),
1183 conf->rx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid));
1184
1185 if (rev_id >= AL_UDMA_REV_ID_REV2) {
1186 al_reg_write32_masked(tx_tgtaddr_reg,
1187 UDMA_GEN_TGTADDR_CFG_MASK(qid),
1188 conf->tx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid));
1189
1190 al_reg_write32_masked(rx_tgtaddr_reg,
1191 UDMA_GEN_TGTADDR_CFG_MASK(qid),
1192 conf->rx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid));
1193 }
1194 }
1195
1196 /* UDMA Target-ID control configuration */
al_udma_gen_tgtid_conf_set(struct unit_regs * unit_regs,struct al_udma_gen_tgtid_conf * conf)1197 void al_udma_gen_tgtid_conf_set(
1198 struct unit_regs *unit_regs,
1199 struct al_udma_gen_tgtid_conf *conf)
1200 {
1201 int i;
1202
1203 for (i = 0; i < DMA_MAX_Q; i++)
1204 al_udma_gen_tgtid_conf_queue_set(unit_regs, conf, i);
1205 }
1206
1207 /* UDMA Target-ID MSIX control configuration */
al_udma_gen_tgtid_msix_conf_set(struct unit_regs * unit_regs,struct al_udma_gen_tgtid_msix_conf * conf)1208 void al_udma_gen_tgtid_msix_conf_set(
1209 struct unit_regs *unit_regs,
1210 struct al_udma_gen_tgtid_msix_conf *conf)
1211 {
1212 al_reg_write32_masked(
1213 &unit_regs->gen.tgtid.cfg_tgtid_0,
1214 UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN |
1215 UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL,
1216 (conf->access_en ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN : 0) |
1217 (conf->sel ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL : 0));
1218 }
1219