1 /*
2 * Copyright (c) 2023-2024 Intel Corporation
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "sedi_dma_ann_1p0.h"
8 #include "sedi_driver_pm.h"
9
10 #include "sedi_soc_regs.h"
11 #include <sedi_driver_dma.h>
12 #include <sedi_driver_ipc.h>
13 #include "sedi_driver_core.h"
14
15 #define DMA_RS0 0 /* root space for common memory */
16 #define DMA_RS1 1 /* root space for csme memory */
17 #define DMA_RS3 3 /* root space for IMR memory */
18 #define DT_IS_IN_DRAM (1 << 0)
19 #define SR_IS_IN_DRAM (1 << 1)
20
21 #define DMA_WRITE_ENABLE(i) (BIT(i) | BIT(DMA_CHANNEL_NUM + i))
22 #define DMA_WRITE_DISABLE(i) BIT(DMA_CHANNEL_NUM + i)
23 #define GET_MSB(data64) ((uint32_t)(data64 >> 32))
24 #define GET_LSB(data64) ((uint32_t)(data64))
25
26 /*driver version*/
27 static const sedi_driver_version_t driver_version = { SEDI_DMA_API_VERSION,
28 SEDI_DMA_DRIVER_VERSION };
29
30 typedef enum {
31 SEDI_CONFIG_DMA_TRANS_TYPE = SEDI_CONFIG_DMA_CONTROL_ID_MAX,
32 SEDI_CONFIG_DMA_LL_HEADER
33 } dma_inner_control_code;
34
35 /*!
36 * DMA Transfer Type, inner usage
37 */
38 typedef enum {
39 DMA_TYPE_SINGLE, /**< Single block mode. */
40 DMA_TYPE_MULTI_CONT, /**< Contiguous multiblock mode. */
41 DMA_TYPE_MULTI_LL, /**< Link list multiblock mode. */
42 DMA_TYPE_MULTI_LL_CIRCULAR, /**< Link list multiblock mode with
43 cyclic operation. */
44 DMA_TYPE_MAX
45 } dma_transfer_type_t;
46
47 /* driver capabilities */
48 static sedi_dma_capabilities_t driver_capabilities[SEDI_DMA_NUM] = { 0 };
49
50 /* channel config*/
51 typedef struct {
52 uint8_t config_applied;
53 uint8_t tf_mode;
54 uint8_t sr_mem_type;
55 uint8_t dt_mem_type;
56 uint8_t sr_msb;
57 uint8_t dt_msb;
58 uint8_t burst_length;
59 uint8_t sr_width;
60 uint8_t dt_width;
61 uint8_t direction;
62 uint8_t handshake_polarity;
63 uint8_t peripheral_direction;
64 uint16_t handshake_device_id;
65 dma_linked_list_item_t *linked_list_header;
66 } channel_config_t;
67
68 /* dma runtime context information */
69 typedef struct {
70 channel_config_t channel_config[DMA_CHANNEL_NUM];
71 sedi_dma_event_cb_t cb_event[DMA_CHANNEL_NUM]; /*event callback*/
72 void *cb_param[DMA_CHANNEL_NUM]; /*event callback*/
73 sedi_dma_status_t status[DMA_CHANNEL_NUM]; /*status flags*/
74 uint32_t done_byte[DMA_CHANNEL_NUM]; /*the transferred byte*/
75 dma_linked_list_item_t *next_llp[DMA_CHANNEL_NUM];
76 uint32_t flags[DMA_CHANNEL_NUM]; /*control and state flags*/
77 uint8_t vnn_status;
78 uint8_t power_status;
79 /*other private runtime data*/
80 } dma_context_t;
81
82 /*resources data structure*/
83 typedef struct {
84 dma_ann_1p0_regs_t *regs; /* register interface*/
85 /*other private data can go here, DMA related information etc. */
86 } dma_resources_t;
87
88 static dma_context_t dma_context[SEDI_DMA_NUM] = { 0 };
89
90 static const dma_resources_t resources[SEDI_DMA_NUM] = {
91 { .regs = (dma_ann_1p0_regs_t *)SEDI_IREG_BASE(DMA, 0) },
92 };
93
sedi_dma_get_version(void)94 sedi_driver_version_t sedi_dma_get_version(void)
95 {
96 return driver_version;
97 }
98
sedi_dma_get_capabilities(IN sedi_dma_t dma_device,INOUT sedi_dma_capabilities_t * cap)99 int sedi_dma_get_capabilities(IN sedi_dma_t dma_device,
100 INOUT sedi_dma_capabilities_t *cap)
101 {
102 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
103
104 if (sedi_dev_is_self_owned(SEDI_DEVID_DMA0 + dma_device)) {
105 driver_capabilities[dma_device].is_available = 1;
106 } else {
107 driver_capabilities[dma_device].is_available = 0;
108 }
109
110 *cap = driver_capabilities[dma_device];
111 return SEDI_DRIVER_OK;
112 }
113
dma_vnn_req(sedi_dma_t dma_device,int channel_id)114 static inline void dma_vnn_req(sedi_dma_t dma_device, int channel_id)
115 {
116 unsigned int key = sedi_core_irq_lock();
117
118 if (dma_context[dma_device].vnn_status == 0) {
119 PM_VNN_DRIVER_REQ(VNN_ID_DMA0 + dma_device);
120 }
121 dma_context[dma_device].vnn_status |= BIT(channel_id);
122 sedi_core_irq_unlock(key);
123 }
124
dma_vnn_dereq(sedi_dma_t dma_device,int channel_id)125 static inline void dma_vnn_dereq(sedi_dma_t dma_device, int channel_id)
126 {
127 unsigned int key = sedi_core_irq_lock();
128
129 if (dma_context[dma_device].vnn_status & (BIT(channel_id))) {
130 dma_context[dma_device].vnn_status &= (~BIT(channel_id));
131 if (dma_context[dma_device].vnn_status == 0) {
132 PM_VNN_DRIVER_DEREQ(VNN_ID_DMA0 + dma_device);
133 }
134 }
135 sedi_core_irq_unlock(key);
136 }
137
dma_set_default_channel_config(OUT channel_config_t * config)138 static void dma_set_default_channel_config(OUT channel_config_t *config)
139 {
140 config->tf_mode = DMA_TYPE_MAX;
141 config->sr_mem_type = DMA_SRAM_MEM;
142 config->dt_mem_type = DMA_SRAM_MEM;
143 config->sr_msb = 0;
144 config->dt_msb = 0;
145 config->burst_length = DMA_BURST_TRANS_LENGTH_MAX;
146 config->sr_width = DMA_TRANS_WIDTH_MAX;
147 config->dt_width = DMA_TRANS_WIDTH_MAX;
148 config->direction = DMA_DIRECTION_MAX;
149 config->handshake_device_id = 0;
150 config->linked_list_header = NULL;
151 config->config_applied = 0;
152 }
153
154 /* mask channel interrupt */
mask_channel_interrupt(IN sedi_dma_t dma_device,IN int channel_id)155 static void mask_channel_interrupt(IN sedi_dma_t dma_device, IN int channel_id)
156 {
157 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
158
159 regs->int_reg.mask_tfr_low = DMA_WRITE_DISABLE(channel_id);
160 regs->int_reg.mask_block_low = DMA_WRITE_DISABLE(channel_id);
161 regs->int_reg.mask_src_trans_low = DMA_WRITE_DISABLE(channel_id);
162 regs->int_reg.mask_dst_trans_low = DMA_WRITE_DISABLE(channel_id);
163 regs->int_reg.mask_err_low = DMA_WRITE_DISABLE(channel_id);
164 }
165
166 /* clear channel interrupt */
clear_channel_interrupt(IN sedi_dma_t dma_device,IN int channel_id)167 static void clear_channel_interrupt(IN sedi_dma_t dma_device, IN int channel_id)
168 {
169 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
170
171 regs->int_reg.clear_tfr_low = BIT(channel_id);
172 regs->int_reg.clear_block_low = BIT(channel_id);
173 regs->int_reg.clear_src_trans_low = BIT(channel_id);
174 regs->int_reg.clear_dst_trans_low = BIT(channel_id);
175 regs->int_reg.clear_err_low = BIT(channel_id);
176 }
177
178 /* enable channel interrupt */
unmask_channel_interrupt(IN sedi_dma_t dma_device,IN int channel_id)179 static void unmask_channel_interrupt(IN sedi_dma_t dma_device,
180 IN int channel_id)
181 {
182 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
183
184 regs->int_reg.mask_tfr_low = DMA_WRITE_ENABLE(channel_id);
185 regs->int_reg.mask_err_low = DMA_WRITE_ENABLE(channel_id);
186 }
187
sedi_dma_init(IN sedi_dma_t dma_device,IN int channel_id,IN sedi_dma_event_cb_t cb,INOUT void * param)188 int32_t sedi_dma_init(IN sedi_dma_t dma_device, IN int channel_id,
189 IN sedi_dma_event_cb_t cb, INOUT void *param)
190 {
191 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
192 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
193
194 /* init default config context */
195 channel_config_t *config =
196 &(dma_context[dma_device].channel_config[channel_id]);
197 dma_set_default_channel_config(config);
198 /*add callback*/
199 dma_context[dma_device].cb_event[channel_id] = cb;
200 dma_context[dma_device].cb_param[channel_id] = param;
201
202 mask_channel_interrupt(dma_device, channel_id);
203 clear_channel_interrupt(dma_device, channel_id);
204 dma_context[dma_device].status[channel_id].busy = 0;
205 dma_context[dma_device].status[channel_id].bus_error = 0;
206
207 return SEDI_DRIVER_OK;
208 }
209
sedi_dma_uninit(IN sedi_dma_t dma_device,IN int channel_id)210 int32_t sedi_dma_uninit(IN sedi_dma_t dma_device, IN int channel_id)
211 {
212 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
213 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
214
215 dma_context[dma_device].cb_event[channel_id] = NULL;
216
217 mask_channel_interrupt(dma_device, channel_id);
218 dma_context[dma_device].status[channel_id].busy = 0;
219 dma_context[dma_device].status[channel_id].bus_error = 0;
220 return SEDI_DRIVER_OK;
221 }
222
config_snoop(sedi_dma_t dma_device,int channel_id)223 static void config_snoop(sedi_dma_t dma_device, int channel_id)
224 {
225 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
226 volatile dma_chan_reg_t *chan_regs = &(regs->chan_reg[channel_id]);
227 volatile dma_misc_regs_t *misc_regs = &(regs->dev_misc_reg);
228
229 /* snoop */
230 misc_regs->dma_regaccess_chid = channel_id;
231
232 SET_BITS(chan_regs->cfg_low, WR_SNP_LOC, WR_SNP_LEN, 0);
233 SET_BITS(chan_regs->cfg_low, RD_SNP_LOC, RD_SNP_LEN, 0);
234 SET_BITS(chan_regs->cfg_low, RD_LLP_SNP_LOC, RD_LLP_SNP_LEN, 1);
235 SET_BITS(chan_regs->cfg_low, RD_STAT_SNP_LOC, RD_STAT_SNP_LEN, 1);
236 SET_BITS(chan_regs->cfg_low, WR_STAT_SNP_LOC, WR_STAT_SNP_LEN, 1);
237 SET_BITS(chan_regs->cfg_low, WR_CTLHI_SNP_LOC, WR_CTLHI_SNP_LEN, 1);
238 SET_BITS(misc_regs->dma_ctl_ch[channel_id], RD_NON_SNOOP_LOC,
239 RD_NON_SNOOP_LEN, 1);
240 SET_BITS(misc_regs->dma_ctl_ch[channel_id], WR_NON_SNOOP_LOC,
241 WR_NON_SNOOP_LEN, 1);
242 SET_BITS(misc_regs->dma_ctl_ch[channel_id], NON_SNOOP_LOC,
243 NON_SNOOP_LEN, 1);
244 }
245
sedi_dma_set_power(IN sedi_dma_t dma_device,IN int channel_id,IN sedi_power_state_t state)246 int32_t sedi_dma_set_power(IN sedi_dma_t dma_device, IN int channel_id,
247 IN sedi_power_state_t state)
248 {
249 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
250 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
251
252 sedi_devid_t devid = SEDI_DEVID_DMA0 + dma_device;
253
254 switch (state) {
255 case SEDI_POWER_FULL:
256 if (dma_context[dma_device].power_status == 0) {
257 sedi_pm_set_device_power(devid, SEDI_POWER_FULL);
258 }
259 dma_context[dma_device].power_status |= BIT(channel_id);
260 config_snoop(dma_device, channel_id);
261 break;
262 case SEDI_POWER_LOW:
263 case SEDI_POWER_SUSPEND:
264 case SEDI_POWER_FORCE_SUSPEND:
265 sedi_dma_abort_transfer(dma_device, channel_id);
266 if (dma_context[dma_device].power_status == 0) {
267 break;
268 }
269 dma_context[dma_device].power_status &= (~BIT(channel_id));
270 if (dma_context[dma_device].power_status == 0) {
271 sedi_pm_set_device_power(devid, SEDI_POWER_SUSPEND);
272 }
273 break;
274 case SEDI_POWER_OFF:
275 default:
276 return SEDI_DRIVER_ERROR_PARAMETER;
277 }
278 return SEDI_DRIVER_OK;
279 }
280
sedi_dma_control_aux(IN sedi_dma_t dma_device,IN int channel_id,IN uint32_t control_id,IN uint32_t arg)281 static int32_t sedi_dma_control_aux(IN sedi_dma_t dma_device, IN int channel_id,
282 IN uint32_t control_id, IN uint32_t arg)
283 {
284 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
285 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
286
287 channel_config_t *config =
288 &(dma_context[dma_device].channel_config[channel_id]);
289
290 switch (control_id) {
291 case SEDI_CONFIG_DMA_TRANS_TYPE:
292 DBG_CHECK(arg < DMA_TYPE_MAX, SEDI_DRIVER_ERROR_PARAMETER);
293 config->tf_mode = arg;
294 break;
295 case SEDI_CONFIG_DMA_SR_MEM_TYPE:
296 DBG_CHECK(arg < DMA_MEM_TYPE_MAX, SEDI_DRIVER_ERROR_PARAMETER);
297 config->sr_mem_type = arg;
298 break;
299 case SEDI_CONFIG_DMA_DT_MEM_TYPE:
300 DBG_CHECK(arg < DMA_MEM_TYPE_MAX, SEDI_DRIVER_ERROR_PARAMETER);
301 config->dt_mem_type = arg;
302 break;
303 case SEDI_CONFIG_DMA_LL_SR_MSB:
304 config->sr_msb = arg;
305 break;
306 case SEDI_CONFIG_DMA_LL_DT_MSB:
307 config->dt_msb = arg;
308 break;
309 case SEDI_CONFIG_DMA_DIRECTION:
310 DBG_CHECK(arg < DMA_DIRECTION_MAX, SEDI_DRIVER_ERROR_PARAMETER);
311 config->direction = arg;
312 break;
313 case SEDI_CONFIG_DMA_BURST_LENGTH:
314 DBG_CHECK(arg < DMA_BURST_TRANS_LENGTH_MAX,
315 SEDI_DRIVER_ERROR_PARAMETER);
316 config->burst_length = arg;
317 break;
318 case SEDI_CONFIG_DMA_SR_TRANS_WIDTH:
319 DBG_CHECK(arg < DMA_TRANS_WIDTH_MAX,
320 SEDI_DRIVER_ERROR_PARAMETER);
321 config->sr_width = arg;
322 break;
323 case SEDI_CONFIG_DMA_DT_TRANS_WIDTH:
324 DBG_CHECK(arg < DMA_TRANS_WIDTH_MAX,
325 SEDI_DRIVER_ERROR_PARAMETER);
326 config->dt_width = arg;
327 break;
328 case SEDI_CONFIG_DMA_HS_DEVICE_ID:
329 config->handshake_device_id = arg;
330 break;
331 case SEDI_CONFIG_DMA_HS_DEVICE_ID_PER_DIR:
332 config->peripheral_direction = arg;
333 break;
334 case SEDI_CONFIG_DMA_HS_POLARITY:
335 DBG_CHECK(arg < DMA_HS_PER_RTX_MAX,
336 SEDI_DRIVER_ERROR_PARAMETER);
337 config->handshake_polarity = arg;
338 break;
339 case SEDI_CONFIG_DMA_LL_HEADER:
340 DBG_CHECK((arg), SEDI_DRIVER_ERROR_PARAMETER);
341 config->linked_list_header = (dma_linked_list_item_t *)arg;
342 break;
343 default:
344 return SEDI_DRIVER_ERROR_PARAMETER;
345 }
346 config->config_applied = 0;
347 return SEDI_DRIVER_OK;
348 }
349
sedi_dma_control(IN sedi_dma_t dma_device,IN int channel_id,IN uint32_t control_id,IN uint32_t arg)350 int32_t sedi_dma_control(IN sedi_dma_t dma_device, IN int channel_id,
351 IN uint32_t control_id, IN uint32_t arg)
352 {
353 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
354 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
355 DBG_CHECK(control_id < SEDI_CONFIG_DMA_CONTROL_ID_MAX,
356 SEDI_DRIVER_ERROR_PARAMETER);
357
358 return sedi_dma_control_aux(dma_device, channel_id, control_id, arg);
359 }
360
sedi_dma_get_status(IN sedi_dma_t dma_device,IN int channel_id,OUT sedi_dma_status_t * status)361 int sedi_dma_get_status(IN sedi_dma_t dma_device, IN int channel_id,
362 OUT sedi_dma_status_t *status)
363 {
364 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
365 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
366
367 *status = dma_context[dma_device].status[channel_id];
368 return SEDI_DRIVER_OK;
369 }
370
371 /*config misc and other registers, as an adding for ctrl register*/
dma_apply_other_regs(volatile dma_misc_regs_t * misc_regs,volatile dma_chan_reg_t * chan_regs,channel_config_t * config,int channel_id)372 static int32_t dma_apply_other_regs(volatile dma_misc_regs_t *misc_regs,
373 volatile dma_chan_reg_t *chan_regs,
374 channel_config_t *config, int channel_id)
375 {
376 uint8_t sr_rs = DMA_RS0;
377 uint8_t dt_rs = DMA_RS0;
378 uint8_t dma_mem_trans_mode = 0;
379
380 /* peripheral related registers*/
381 if (config->direction != DMA_MEMORY_TO_MEMORY) {
382 /* config check */
383 DBG_CHECK(config->peripheral_direction < DMA_HS_PER_RTX_MAX,
384 SEDI_DRIVER_ERROR_PARAMETER);
385 DBG_CHECK(config->handshake_polarity < DMA_HS_POLARITY_MAX,
386 SEDI_DRIVER_ERROR_PARAMETER);
387 /* hardware handshake only*/
388 /* select peripheral rx/tx to link up with dma*/
389 SET_BITS(misc_regs->dma_xbar_sel[channel_id], RX_TX_LOC,
390 RX_TX_LEN, config->peripheral_direction);
391 /* select peripheral device to connect with dma req wire*/
392 SET_BITS(misc_regs->dma_xbar_sel[channel_id], DEVID_LOC,
393 DEVID_LEN, config->handshake_device_id);
394 /* set handshaking polarity */
395 SET_BITS(chan_regs->cfg_low, DST_HS_POL_LOC, DST_HS_POL_LEN,
396 config->handshake_polarity);
397 SET_BITS(chan_regs->cfg_low, SRC_HS_POL_LOC, SRC_HS_POL_LEN,
398 config->handshake_polarity);
399 SET_BITS(chan_regs->cfg_low, HSHAKE_NP_WR_LOC, HSHAKE_NP_WR_LEN,
400 1U);
401 /* fill channel id to DST/SRC_PER reg*/
402 SET_BITS(chan_regs->cfg_high, SRC_PER_LOC, SRC_PER_LEN,
403 channel_id);
404 SET_BITS(chan_regs->cfg_high, DST_PER_LOC, DST_PER_LEN,
405 channel_id);
406 }
407 /* memory type related registers config*/
408 /* source is memory*/
409 if ((config->direction == DMA_MEMORY_TO_PERIPHERAL) ||
410 (config->direction == DMA_MEMORY_TO_MEMORY)) {
411 DBG_CHECK(config->sr_mem_type < DMA_MEM_TYPE_MAX,
412 SEDI_DRIVER_ERROR_PARAMETER);
413 if (config->sr_mem_type == DMA_UMA_MEM) {
414 sr_rs = DMA_RS3;
415 }
416 if (config->sr_mem_type != DMA_SRAM_MEM) {
417 dma_mem_trans_mode |= SR_IS_IN_DRAM;
418 }
419 }
420 /* destination is memory*/
421 if ((config->direction == DMA_PERIPHERAL_TO_MEMORY) ||
422 (config->direction == DMA_MEMORY_TO_MEMORY)) {
423 DBG_CHECK(config->dt_mem_type < DMA_MEM_TYPE_MAX,
424 SEDI_DRIVER_ERROR_PARAMETER);
425 if (config->dt_mem_type == DMA_UMA_MEM) {
426 dt_rs = DMA_RS3;
427 }
428 if (config->dt_mem_type != DMA_SRAM_MEM) {
429 dma_mem_trans_mode |= DT_IS_IN_DRAM;
430 }
431 }
432 /*set root space and memory type*/
433 SET_BITS(misc_regs->dma_ctl_ch[channel_id], WR_RS_LOC, WR_RS_LEN,
434 dt_rs);
435 SET_BITS(misc_regs->dma_ctl_ch[channel_id], RD_RS_LOC, RD_RS_LEN,
436 sr_rs);
437 SET_BITS(misc_regs->dma_ctl_ch[channel_id], M2M_TYPE_LOC, M2M_TYPE_LEN,
438 dma_mem_trans_mode);
439
440 /* fill higher 32bit of 64bit addr */
441 misc_regs->iosf_addr_fillin_dma_ch[channel_id] = config->sr_msb;
442 misc_regs->iosf_dest_addr_fillin_dma_ch[channel_id] = config->dt_msb;
443 return SEDI_DRIVER_OK;
444 }
445
dma_channel_apply_config(IN sedi_dma_t dma_device,IN int channel_id)446 static int32_t dma_channel_apply_config(IN sedi_dma_t dma_device,
447 IN int channel_id)
448 {
449 int32_t ret;
450 channel_config_t *config =
451 &(dma_context[dma_device].channel_config[channel_id]);
452 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
453 volatile dma_chan_reg_t *chan_regs = &(regs->chan_reg[channel_id]);
454 volatile dma_misc_regs_t *misc_regs = &(regs->dev_misc_reg);
455
456 /*return if no need to config*/
457 if (config->config_applied == 1) {
458 return SEDI_DRIVER_OK;
459 }
460
461 DBG_CHECK(config->tf_mode < DMA_TYPE_MAX, SEDI_DRIVER_ERROR_PARAMETER);
462 DBG_CHECK(config->direction < DMA_DIRECTION_MAX,
463 SEDI_DRIVER_ERROR_PARAMETER);
464 misc_regs->dma_regaccess_chid = channel_id;
465 if (config->tf_mode == DMA_TYPE_SINGLE) {
466 /* single block mode config, mainly config ctrl_low reg*/
467 DBG_CHECK(config->burst_length < DMA_BURST_TRANS_LENGTH_MAX,
468 SEDI_DRIVER_ERROR_PARAMETER);
469 DBG_CHECK(config->sr_width < DMA_TRANS_WIDTH_MAX,
470 SEDI_DRIVER_ERROR_PARAMETER);
471 DBG_CHECK(config->dt_width < DMA_TRANS_WIDTH_MAX,
472 SEDI_DRIVER_ERROR_PARAMETER);
473 DBG_CHECK(config->peripheral_direction < DMA_HS_PER_RTX_MAX,
474 SEDI_DRIVER_ERROR_PARAMETER);
475 /*set dest and src burst size */
476 SET_BITS(chan_regs->ctrl_low, DEST_MSIZE_LOC, SRC_MSIZE_LEN,
477 config->burst_length);
478 SET_BITS(chan_regs->ctrl_low, SRC_MSIZE_LOC, SRC_MSIZE_LEN,
479 config->burst_length);
480 /*source and destination transfer width */
481 SET_BITS(chan_regs->ctrl_low, DST_TR_WIDTH_LOC,
482 DST_TR_WIDTH_LEN, config->dt_width);
483 SET_BITS(chan_regs->ctrl_low, SRC_TR_WIDTH_LOC,
484 SRC_TR_WIDTH_LEN, config->sr_width);
485
486 /*transfer direction */
487 SET_BITS(chan_regs->ctrl_low, TT_FC_LOC, TT_FC_LEN,
488 config->direction);
489
490 /* Set increment*/
491 switch (config->direction) {
492 case DMA_PERIPHERAL_TO_MEMORY:
493 SET_BITS(chan_regs->ctrl_low, SINC_LOC, SINC_LEN,
494 DMA_INCREMENT_NO_CHANGE);
495 SET_BITS(chan_regs->ctrl_low, DINC_LOC, DINC_LEN,
496 DMA_INCREMENT_INC);
497 break;
498 case DMA_MEMORY_TO_MEMORY:
499 SET_BITS(chan_regs->ctrl_low, SINC_LOC, SINC_LEN,
500 DMA_INCREMENT_INC);
501 SET_BITS(chan_regs->ctrl_low, DINC_LOC, DINC_LEN,
502 DMA_INCREMENT_INC);
503 break;
504 case DMA_MEMORY_TO_PERIPHERAL:
505 SET_BITS(chan_regs->ctrl_low, DINC_LOC, DINC_LEN,
506 DMA_INCREMENT_NO_CHANGE);
507 SET_BITS(chan_regs->ctrl_low, SINC_LOC, SINC_LEN,
508 DMA_INCREMENT_INC);
509 break;
510 case DMA_PERIPHERAL_TO_PERIPHERAL:
511 SET_BITS(chan_regs->ctrl_low, DINC_LOC, DINC_LEN,
512 DMA_INCREMENT_NO_CHANGE);
513 SET_BITS(chan_regs->ctrl_low, SINC_LOC, SINC_LEN,
514 DMA_INCREMENT_NO_CHANGE);
515 break;
516 default:
517 return SEDI_DRIVER_ERROR_PARAMETER;
518 }
519 chan_regs->llp_low = 0;
520 } else if (config->tf_mode == DMA_TYPE_MULTI_LL) {
521 DBG_CHECK(config->linked_list_header != NULL,
522 SEDI_DRIVER_ERROR_PARAMETER);
523 chan_regs->llp_low = (uint32_t)config->linked_list_header;
524 }
525
526 /*config misc and other registers, as an adding for ctrl register*/
527 ret = dma_apply_other_regs(misc_regs, chan_regs, config, channel_id);
528 if (ret != SEDI_DRIVER_OK) {
529 return ret;
530 }
531
532 if ((config->sr_mem_type != DMA_SRAM_MEM) ||
533 (config->dt_mem_type != DMA_SRAM_MEM)) {
534 dma_vnn_req(dma_device, channel_id);
535 }
536
537 config->config_applied = 1;
538 return SEDI_DRIVER_OK;
539 }
540
dma_fill_linkedlist(INOUT dma_linked_list_item_t * ll_p,IN uint32_t src_addr,IN uint32_t dst_addr,IN uint32_t block_size,uint32_t ctrl_low,IN dma_linked_list_item_t * ll_p_next)541 int dma_fill_linkedlist(INOUT dma_linked_list_item_t *ll_p,
542 IN uint32_t src_addr, IN uint32_t dst_addr,
543 IN uint32_t block_size, uint32_t ctrl_low,
544 IN dma_linked_list_item_t *ll_p_next)
545 {
546 DBG_CHECK(ll_p != NULL, SEDI_DRIVER_ERROR_PARAMETER);
547 DBG_CHECK(src_addr != 0, SEDI_DRIVER_ERROR_PARAMETER);
548 DBG_CHECK(dst_addr != 0, SEDI_DRIVER_ERROR_PARAMETER);
549 DBG_CHECK(block_size <= DMA_MAX_BLOCK_SIZE,
550 SEDI_DRIVER_ERROR_PARAMETER);
551
552 ll_p->src_addr = src_addr;
553 ll_p->dst_addr = dst_addr;
554 ll_p->ctrl_low.raw = ctrl_low;
555 SET_BITS(ll_p->ctrl_high.raw, BLOCK_TS_LOC, BLOCK_TS_LEN, block_size);
556 ll_p->next_ll_p = ll_p_next;
557 return SEDI_DRIVER_OK;
558 }
559
dma_fill_sc_linkedlist(INOUT dma_linked_list_item_t * llp,IN uint8_t count,IN uint32_t ctrl_reg_low,IN sc_attr_t * attr)560 int dma_fill_sc_linkedlist(INOUT dma_linked_list_item_t *llp,
561 IN uint8_t count, IN uint32_t ctrl_reg_low,
562 IN sc_attr_t *attr)
563 {
564 DBG_CHECK(llp != NULL, SEDI_DRIVER_ERROR_PARAMETER);
565 DBG_CHECK(attr != NULL, SEDI_DRIVER_ERROR_PARAMETER);
566 DBG_CHECK(count > 0, SEDI_DRIVER_ERROR_PARAMETER);
567
568 int ret;
569 dma_linked_list_item_t *ll_tmp = (dma_linked_list_item_t *)llp;
570 uint32_t src = attr->src_addr;
571 uint32_t dst = attr->dst_addr;
572
573 for (int i = 0; i < count - 1; i++) {
574 ret = dma_fill_linkedlist(ll_tmp + i, src, dst,
575 attr->block_size,
576 ctrl_reg_low, ll_tmp + i + 1);
577 if (ret != SEDI_DRIVER_OK) {
578 return ret;
579 }
580 if (attr->is_scatter) {
581 if (attr->need_reload == 0) {
582 src += attr->block_size;
583 }
584 dst += (attr->interval);
585 } else {
586 if (attr->need_reload == 0) {
587 dst += attr->block_size;
588 }
589 src += (attr->interval);
590 }
591 }
592 ret = dma_fill_linkedlist(ll_tmp + count - 1, src, dst,
593 attr->block_size, ctrl_reg_low, NULL);
594 return ret;
595 }
596
sedi_dma_start_transfer_aux(sedi_dma_t dma_device,int channel_id,uint32_t sr_addr,uint32_t dest_addr,uint32_t length)597 static int32_t sedi_dma_start_transfer_aux(sedi_dma_t dma_device,
598 int channel_id, uint32_t sr_addr,
599 uint32_t dest_addr, uint32_t length)
600 {
601 int32_t ret;
602 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
603 volatile dma_chan_reg_t *chan_regs = &(regs->chan_reg[channel_id]);
604 channel_config_t *config =
605 &(dma_context[dma_device].channel_config[channel_id]);
606
607 if (regs->misc_reg.chan_en_low & BIT(channel_id)) {
608 return SEDI_DRIVER_ERROR_BUSY;
609 }
610 /* channel config*/
611 ret = dma_channel_apply_config(dma_device, channel_id);
612 if (ret != SEDI_DRIVER_OK) {
613 dma_context[dma_device].status[channel_id].busy = 0;
614 return ret;
615 }
616 if (config->tf_mode == DMA_TYPE_SINGLE) {
617 chan_regs->sar_low = sr_addr;
618 chan_regs->dar_low = dest_addr;
619 SET_BITS(chan_regs->ctrl_high, BLOCK_TS_LOC, BLOCK_TS_LEN,
620 length);
621 SET_BITS(chan_regs->ctrl_low, INT_EN_LOC, INT_EN_LEN, 1);
622 } else if (config->tf_mode == DMA_TYPE_MULTI_LL) {
623 SET_BITS(chan_regs->ctrl_low, LLP_DST_EN_LOC, LLP_DST_EN_LEN,
624 1);
625 SET_BITS(chan_regs->ctrl_low, LLP_SRC_EN_LOC, LLP_SRC_EN_LEN,
626 1);
627 }
628
629 dma_set_default_channel_config(config);
630 /* enable interrupt */
631 unmask_channel_interrupt(dma_device, channel_id);
632
633 /* enable channel*/
634 regs->misc_reg.cfg_low = 1;
635 SET_BITS(chan_regs->cfg_low, CH_DRAIN_LOC, CH_DRAIN_LEN, 0);
636 SET_BITS(chan_regs->cfg_low, CH_SUSP_LOC, CH_SUSP_LEN, 0);
637 regs->misc_reg.chan_en_low = DMA_WRITE_ENABLE(channel_id);
638 return SEDI_DRIVER_OK;
639 }
640
sedi_dma_start_transfer(IN sedi_dma_t dma_device,IN int channel_id,IN uint64_t sr_addr,IN uint64_t dest_addr,IN uint32_t length)641 int32_t sedi_dma_start_transfer(IN sedi_dma_t dma_device, IN int channel_id,
642 IN uint64_t sr_addr, IN uint64_t dest_addr,
643 IN uint32_t length)
644 {
645 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
646 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
647 DBG_CHECK(sr_addr > 0, SEDI_DRIVER_ERROR_PARAMETER);
648 DBG_CHECK(dest_addr > 0, SEDI_DRIVER_ERROR_PARAMETER);
649 DBG_CHECK((length <= DMA_MAX_BLOCK_SIZE) && (length > 0),
650 SEDI_DRIVER_ERROR_PARAMETER);
651
652 if (dma_context[dma_device].status[channel_id].busy == 1) {
653 return SEDI_DRIVER_ERROR_BUSY;
654 }
655 dma_context[dma_device].status[channel_id].busy = 1;
656 dma_context[dma_device].status[channel_id].bus_error = 0;
657
658 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_TRANS_TYPE,
659 DMA_TYPE_SINGLE);
660 /* pass higher 32 bit of address*/
661 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_LL_SR_MSB,
662 GET_MSB(sr_addr));
663 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_LL_DT_MSB,
664 GET_MSB(dest_addr));
665
666 return sedi_dma_start_transfer_aux(dma_device, channel_id,
667 GET_LSB(sr_addr), GET_LSB(dest_addr),
668 length);
669 }
670
sedi_dma_start_ll_transfer(IN sedi_dma_t dma_device,IN int channel_id,IN dma_linked_list_item_t * linkedlist_header)671 int32_t sedi_dma_start_ll_transfer(IN sedi_dma_t dma_device, IN int channel_id,
672 IN dma_linked_list_item_t *linkedlist_header)
673 {
674 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
675 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
676 DBG_CHECK(linkedlist_header != NULL, SEDI_DRIVER_ERROR_PARAMETER);
677 int32_t ret;
678
679 if (dma_context[dma_device].status[channel_id].busy == 1) {
680 return SEDI_DRIVER_ERROR_BUSY;
681 }
682 dma_context[dma_device].status[channel_id].busy = 1;
683 dma_context[dma_device].status[channel_id].bus_error = 0;
684 /* channel config*/
685 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_TRANS_TYPE,
686 DMA_TYPE_MULTI_LL);
687 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_LL_HEADER,
688 (uint32_t)linkedlist_header);
689
690 ret = sedi_dma_start_transfer_aux(dma_device, channel_id, 0, 0, 0);
691
692 return ret;
693 }
694
dma_transfer_post(sedi_dma_t dma_device,int channel_id)695 static void dma_transfer_post(sedi_dma_t dma_device, int channel_id)
696 {
697 channel_config_t *config =
698 &(dma_context[dma_device].channel_config[channel_id]);
699 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
700 volatile dma_chan_reg_t *chan_regs = &(regs->chan_reg[channel_id]);
701
702 /* get status*/
703 dma_context[dma_device].done_byte[channel_id] =
704 GET_BITS(chan_regs->ctrl_high, BLOCK_TS_LOC, BLOCK_TS_LEN);
705 dma_context[dma_device].next_llp[channel_id] =
706 (dma_linked_list_item_t *)chan_regs->llp_low;
707
708 /* disable dma channel*/
709 regs->misc_reg.chan_en_low = DMA_WRITE_DISABLE(channel_id);
710 while (regs->misc_reg.chan_en_low & BIT(channel_id)) {
711 }
712
713 /* mask and clear interrupt*/
714 clear_channel_interrupt(dma_device, channel_id);
715 mask_channel_interrupt(dma_device, channel_id);
716
717 dma_vnn_dereq(dma_device, channel_id);
718 dma_set_default_channel_config(config);
719 dma_context[dma_device].status[channel_id].busy = 0;
720 }
721
722 /* Polling mode is only used in single-block mode */
sedi_dma_start_transfer_polling(IN sedi_dma_t dma_device,IN int channel_id,IN uint64_t sr_addr,IN uint64_t dest_addr,IN uint32_t length)723 int32_t sedi_dma_start_transfer_polling(IN sedi_dma_t dma_device,
724 IN int channel_id, IN uint64_t sr_addr,
725 IN uint64_t dest_addr,
726 IN uint32_t length)
727 {
728 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
729 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
730 DBG_CHECK(length <= DMA_MAX_BLOCK_SIZE, SEDI_DRIVER_ERROR_PARAMETER);
731
732 uint32_t ret;
733 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
734 volatile dma_chan_reg_t *chan_regs = &(regs->chan_reg[channel_id]);
735 sedi_dma_event_cb_t cb = dma_context[dma_device].cb_event[channel_id];
736 void *usr_param = dma_context[dma_device].cb_param[channel_id];
737
738 if (dma_context[dma_device].status[channel_id].busy == 1) {
739 return SEDI_DRIVER_ERROR_BUSY;
740 }
741 dma_context[dma_device].status[channel_id].busy = 1;
742 dma_context[dma_device].status[channel_id].bus_error = 0;
743
744 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_TRANS_TYPE,
745 DMA_TYPE_SINGLE);
746
747 /* pass higher 32 bit of address*/
748 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_LL_SR_MSB,
749 GET_MSB(sr_addr));
750 sedi_dma_control_aux(dma_device, channel_id, SEDI_CONFIG_DMA_LL_DT_MSB,
751 GET_MSB(dest_addr));
752
753 ret = dma_channel_apply_config(dma_device, channel_id);
754 if (ret != SEDI_DRIVER_OK) {
755 dma_context[dma_device].status[channel_id].busy = 0;
756 return ret;
757 }
758
759 chan_regs->sar_low = GET_LSB(sr_addr);
760 chan_regs->dar_low = GET_LSB(dest_addr);
761 SET_BITS(chan_regs->ctrl_high, BLOCK_TS_LOC, BLOCK_TS_LEN, length);
762
763 /* disable and clear interrupt */
764 mask_channel_interrupt(dma_device, channel_id);
765 clear_channel_interrupt(dma_device, channel_id);
766
767 /* enable channel*/
768 regs->misc_reg.cfg_low = 1;
769 regs->misc_reg.chan_en_low = DMA_WRITE_ENABLE(channel_id);
770
771 while (1) {
772 if (regs->misc_reg.chan_en_low & BIT(channel_id)) {
773 continue;
774 }
775 if (regs->int_reg.raw_err_low & BIT(channel_id)) {
776 dma_transfer_post(dma_device, channel_id);
777 dma_context[dma_device].status[channel_id].bus_error =
778 1;
779 if (cb != NULL) {
780 cb(dma_device, channel_id,
781 SEDI_DMA_EVENT_BUS_ERROR, usr_param);
782 }
783 return SEDI_DRIVER_ERROR_TRANSFER;
784 } else {
785 dma_transfer_post(dma_device, channel_id);
786 if (cb != NULL) {
787 cb(dma_device, channel_id,
788 SEDI_DMA_EVENT_TRANSFER_DONE, usr_param);
789 }
790 return SEDI_DRIVER_OK;
791 }
792 }
793 return SEDI_DRIVER_OK;
794 }
795
sedi_dma_abort_transfer(IN sedi_dma_t dma_device,IN int channel_id)796 int32_t sedi_dma_abort_transfer(IN sedi_dma_t dma_device, IN int channel_id)
797 {
798 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
799 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
800
801 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
802 volatile dma_chan_reg_t *chan_regs = &(regs->chan_reg[channel_id]);
803
804 if (dma_context[dma_device].status[channel_id].busy == 0) {
805 return SEDI_DRIVER_OK;
806 }
807
808 SET_BITS(chan_regs->cfg_low, CH_SUSP_LOC, CH_SUSP_LEN, 1);
809 SET_BITS(chan_regs->cfg_low, CH_DRAIN_LOC, CH_DRAIN_LEN, 1);
810
811 while ((chan_regs->cfg_low & BIT(FIFO_EMPTY_LOC)) == 0) {
812 }
813
814 dma_transfer_post(dma_device, channel_id);
815 return SEDI_DRIVER_OK;
816 }
817
sedi_dma_get_done_status(IN sedi_dma_t dma_device,IN int channel_id,OUT uint32_t * done_bytes,OUT dma_linked_list_item_t ** next_llp)818 int32_t sedi_dma_get_done_status(IN sedi_dma_t dma_device, IN int channel_id,
819 OUT uint32_t *done_bytes,
820 OUT dma_linked_list_item_t **next_llp)
821 {
822 DBG_CHECK(dma_device < SEDI_DMA_NUM, SEDI_DRIVER_ERROR_PARAMETER);
823 DBG_CHECK(channel_id < DMA_CHANNEL_NUM, SEDI_DRIVER_ERROR_PARAMETER);
824
825 if (dma_context[dma_device].status[channel_id].busy == 1) {
826 return SEDI_DRIVER_ERROR_BUSY;
827 }
828
829 if (done_bytes) {
830 *done_bytes = dma_context[dma_device].done_byte[channel_id];
831 }
832 if (next_llp) {
833 *next_llp = dma_context[dma_device].next_llp[channel_id];
834 }
835 return SEDI_DRIVER_OK;
836 }
837
dma_isr(IN sedi_dma_t dma_device)838 void dma_isr(IN sedi_dma_t dma_device)
839 {
840 volatile dma_ann_1p0_regs_t *regs = resources[dma_device].regs;
841 sedi_dma_event_cb_t cb;
842 void *usr_param;
843 uint32_t tfr_status = regs->int_reg.status_tfr_low;
844 uint32_t err_status = regs->int_reg.status_err_low;
845
846 for (int channel_id = 0; channel_id < DMA_CHANNEL_NUM; channel_id++) {
847 cb = dma_context[dma_device].cb_event[channel_id];
848 usr_param = dma_context[dma_device].cb_param[channel_id];
849 if (tfr_status & BIT(channel_id)) {
850 dma_transfer_post(dma_device, channel_id);
851 if (cb != NULL) {
852 cb(dma_device, channel_id,
853 SEDI_DMA_EVENT_TRANSFER_DONE, usr_param);
854 }
855 }
856 if (err_status & BIT(channel_id)) {
857 dma_transfer_post(dma_device, channel_id);
858 dma_context[dma_device].status[channel_id].bus_error =
859 1;
860 if (cb != NULL) {
861 cb(dma_device, channel_id,
862 SEDI_DMA_EVENT_BUS_ERROR, usr_param);
863 }
864 }
865 }
866 }
867