1:
14:
15:
19:
20:
21:
#include "AG903_common.h"
22:
#include "AG903_regmap.h"
23:
24:
#include "dmac/dmacprm.h"
25:
#include "dmac/dmacmgr.h"
26:
#include "int/intmgr.h"
27:
28:
29:
typedef struct _AG903_DMACMgrAddrTable
30: {
31: uint32_t current;
32: uint32_t next;
33: }
AG903_DMACMgrAddrTable;
34:
35:
36:
typedef struct _AG903_DMACMgrHandleStat
37: {
38:
void *cb_term;
39:
void *cb_abt;
40:
void *cb_wdt;
41:
void *cb_error;
42:
43:
46:
AG903_DMACMgrAddrTable term_addr_table[
AG903_DMAC_DESC_LINK_MAX];
47: uint32_t term_addr_table_num;
48:
49: uint8_t unit_id;
50: uint8_t term_count;
51: uint8_t reserve[2];
52:
53: }
AG903_DMACMgrHandleStat;
54:
55:
static AG903_DMACMgrHandleStat handle_list[
AG903_DMAC_UNIT_NUM];
56:
static _Bool handle_used_flag[
AG903_DMAC_UNIT_NUM] = {
false};
57:
58:
#define LOCAL_DESC_MEM_ADDR (0xFD100000)
59:
60:
#define CH_REG_SIZE (0x20)
61:
62:
static int8_t dmac_int_init_flag =
false;
63:
64:
65:
static int32_t dmac_int_dmactc_hdrid = 0;
66:
67:
static int8_t ldd_flag[
AG903_DMAC_LDD_ENTRY_NUM] = {0};
68:
69:
static int8_t rdd_flag[
AG903_DMAC_RDD_ENTRY_NUM] = {0};
70:
static uint8_t* rdd_data = NULL;
71:
72:
#define TOTAL_ENTRY_NUM (
AG903_DMAC_LDD_ENTRY_NUM+
AG903_DMAC_RDD_ENTRY_NUM)
73:
74:
#define AG903_DMAC_CONFIG_TCMASK (1<<0)
75:
76:
static _Bool initdesc =
false;
77:
78:
static void write_desc(
AG903_DMACMgrDesc *from,
AG903_DMACMgrDesc *next,
void *to,
int is_reg);
79:
static int32_t remove_desc_entry(
int seq_id);
80:
static uint8_t DMACMgr_CheckEnable(uint32_t unit);
81:
static void DMACMgrTermIntHandler(uint32_t term);
82:
static void DMACMgrErrIntHandler(uint32_t abt, uint32_t err);
83:
84:
87:
static void DMACMgrDmactcIntHandler()
88: {
89: uint32_t term, abt, wdt, err;
90:
91:
AG903_DMACPrmGetTIMECOUNT_STATUS(&term);
92:
AG903_DMACPrmGetERR_ABORT_STATUS(&err, &wdt, &abt);
93:
94:
if(0 != term) {
95: DMACMgrTermIntHandler(term);
96: }
97:
if((0 != abt) || (0 != err)) {
98: DMACMgrErrIntHandler(abt, err);
99: }
100:
if(0 != wdt) {
101:
102:
103: }
104:
105:
return;
106: }
107:
108:
111:
static void DMACMgrTermIntHandler(uint32_t term)
112: {
113:
AG903_DMACMgrHandleStat *handle;
114:
AG903_DMACMgrDesc *desc = NULL;
115:
AG903_DMACMgrDesc *next = NULL;
116: uint32_t desc_save_mem;
117:
int loop;
118: uint8_t end =
false;
119:
120:
for(loop=0; loop<
AG903_DMAC_UNIT_NUM; loop++) {
121:
if(0 == term) {
122:
break;
123: }
124:
if(term & (0x1<<loop)) {
125:
if(
true == handle_used_flag[loop]) {
126:
127:
AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(0x1<<loop);
128:
129: handle = &handle_list[loop];
130:
if(handle->cb_term != NULL) {
131:
void (*cb_term)(
AG903_DMACMgrHandle*,
AG903_DMACMgrDesc**, uint8_t*) =
132: (
void(*)(
AG903_DMACMgrHandle*,
AG903_DMACMgrDesc**, uint8_t*))handle->cb_term;
133:
if(0 >= handle->term_addr_table_num) {
134: cb_term((
AG903_DMACMgrHandle*)handle, NULL, NULL);
135: }
136:
else {
137: cb_term((
AG903_DMACMgrHandle*)handle, &desc, &end);
138:
if(NULL != desc) {
139:
if(
true == end) {
140: next = NULL;
141: }
142:
else {
143: next = (
AG903_DMACMgrDesc*)handle->term_addr_table[handle->term_count].next;
144: }
145: desc_save_mem = handle->term_addr_table[handle->term_count].current;
146: write_desc(desc, next, (
void*)desc_save_mem, 0);
147: }
148:
else {
149:
150:
if(
true == end) {
151: desc_save_mem = handle->term_addr_table[handle->term_count].current;
152: *(uint32_t*)(((uint32_t)desc_save_mem)+0x8) = 0;
153: }
154: }
155: handle->term_count = ((handle->term_count+1) % handle->term_addr_table_num);
156: }
157: }
158: }
159:
else {
160:
161: }
162: term &= ~(0x1<<loop);
163: }
164:
165: }
166:
167:
return;
168: }
169:
170:
173:
static void DMACMgrErrIntHandler(uint32_t abt, uint32_t err)
174: {
175:
AG903_DMACMgrHandleStat *handle;
176:
int loop;
177:
178:
182:
for(loop=0; loop<
AG903_DMAC_UNIT_NUM; loop++) {
183:
if(0 == abt) {
184:
break;
185: }
186:
if(abt & (0x1<<loop)) {
187:
if(
true == handle_used_flag[loop]) {
188: handle = &handle_list[loop];
189:
if(NULL != handle_list[loop].cb_abt) {
190:
void (*cb_abt)(
AG903_DMACMgrHandle*) = (
void(*)(
AG903_DMACMgrHandle*))handle->cb_abt;
191: cb_abt((
AG903_DMACMgrHandle*)handle);
192: }
193:
AG903_DMACMgrClearInt((
AG903_DMACMgrHandle*)handle,
AG903_DMAC_INTSTS_ABORT);
194: }
195:
else {
196:
197: }
198: abt &= ~(0x1<<loop);
199: }
200: }
201:
202:
for(loop=0; loop<
AG903_DMAC_UNIT_NUM; loop++) {
203:
if(0 == err) {
204:
break;
205: }
206:
if(err & (0x1<<loop)) {
207:
if(
true == handle_used_flag[loop]) {
208: handle = &handle_list[loop];
209:
if(NULL != handle_list[loop].cb_error) {
210:
void (*cb_error)(
AG903_DMACMgrHandle*) = (
void(*)(
AG903_DMACMgrHandle*))handle->cb_error;
211: cb_error((
AG903_DMACMgrHandle*)handle);
212: }
213:
AG903_DMACMgrClearInt((
AG903_DMACMgrHandle*)handle,
AG903_DMAC_INTSTS_ERROR);
214: }
215:
else {
216:
217: }
218: err &= ~(0x1<<loop);
219: }
220: }
221:
222:
return;
223: }
224:
225:
235: int32_t
AG903_DMACMgrGetHandle(
int ch,
AG903_DMACMgrHandle **handle)
236: {
237:
if(ch < 0 ||
AG903_DMAC_UNIT_NUM <= ch || NULL == handle)
238: {
239:
return -
AG903_EINVAL;
240: }
241:
242:
if(handle_used_flag[ch] ==
true)
243: {
244:
return -
AG903_EBUSY;
245: }
246:
247:
248: uint32_t chpos = 1 << ch;
249:
AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(chpos);
250:
AG903_DMACPrmSetERR_ABORT_INT_CLEAR(chpos, chpos, chpos);
251:
252: (*handle) = (
AG903_DMACMgrHandle*)&handle_list[ch];
253: handle_used_flag[ch] =
true;
254:
255: handle_list[ch].unit_id = ch;
256:
257: handle_list[ch].cb_term = NULL;
258: handle_list[ch].cb_error = NULL;
259: handle_list[ch].cb_abt = NULL;
260: handle_list[ch].cb_wdt = NULL;
261:
262:
return AG903_ENONE;
263: }
264:
265:
277: int32_t
AG903_DMACMgrReleaseHandle(
AG903_DMACMgrHandle *handle)
278: {
279: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
280: uint8_t enable;
281:
282:
283:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
284: {
285:
return -
AG903_EINVAL;
286: }
287:
288:
289: enable = DMACMgr_CheckEnable(unit);
290:
if(
true == enable) {
291:
return -
AG903_EBUSY;
292: }
293:
294: remove_desc_entry(unit);
295: handle_used_flag[unit] =
false;
296:
297:
return AG903_ENONE;
298: }
299:
300:
309: int32_t
AG903_DMACMgrGetIntStatus(
AG903_DMACMgrHandle *handle, uint32_t *status)
310: {
311: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
312: uint32_t term, abt, wdt, error;
313:
314:
315:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle || NULL == status)
316: {
317:
return -
AG903_EINVAL;
318: }
319:
320:
AG903_DMACPrmGetTIMECOUNT_STATUS(&term);
321:
AG903_DMACPrmGetERR_ABORT_STATUS(&error, &wdt, &abt);
322: term = (term >> unit) & 0x01;
323: error = (error >> unit) & 0x01;
324: wdt = (wdt >> unit) & 0x01;
325: abt = (abt >> unit) & 0x01;
326:
327: (*status) = (uint32_t)term;
328: (*status) |= (uint32_t)(abt<<1);
329: (*status) |= (uint32_t)(wdt<<2);
330: (*status) |= (uint32_t)(error<<3);
331:
332:
return AG903_ENONE;
333: }
334:
335:
344: int32_t
AG903_DMACMgrClearInt(
AG903_DMACMgrHandle *handle, uint32_t clrbit)
345: {
346: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
347: uint8_t term, abt, wdt, error;
348:
349:
350:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
351: {
352:
return -
AG903_EINVAL;
353: }
354:
355: term = 0;
356: abt = 0;
357: wdt = 0;
358: error = 0;
359:
if(
AG903_DMAC_INTSTS_TERM&clrbit) {
360: term =1;
361: }
362:
if(
AG903_DMAC_INTSTS_ABORT&clrbit) {
363: abt=1;
364: }
365:
if(
AG903_DMAC_INTSTS_WDT&clrbit) {
366: wdt=1;
367: }
368:
if(
AG903_DMAC_INTSTS_ERROR&clrbit) {
369: error=1;
370: }
371:
AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(term<<unit);
372:
AG903_DMACPrmSetERR_ABORT_INT_CLEAR(error<<unit, wdt<<unit, abt<<unit);
373:
374:
return AG903_ENONE;
375: }
376:
377:
396: int32_t
AG903_DMACMgrSetIntCallback(
AG903_DMACMgrHandle *handle,
397:
void (*cb_term)(
AG903_DMACMgrHandle*,
AG903_DMACMgrDesc**, uint8_t*),
398:
void (*cb_abt)(
AG903_DMACMgrHandle*),
399:
void (*cb_error)(
AG903_DMACMgrHandle*))
400: {
401: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
402:
AG903_INTMgrHdrPrm inthdr;
403:
404:
405:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
406: {
407:
return -
AG903_EINVAL;
408: }
409:
410:
411:
if(dmac_int_init_flag ==
false)
412: {
413: inthdr.atr =
AG903_INT_HLNG;
414: inthdr.intno =
AG903_IRQ26_DMAC;
415: inthdr.func = (
void*)DMACMgrDmactcIntHandler;
416: dmac_int_dmactc_hdrid =
AG903_INTMgrSetHandler(&inthdr);
417:
if(0 >= dmac_int_dmactc_hdrid)
418: {
419:
return -
AG903_EFAULT;
420: }
421: dmac_int_init_flag =
true;
422: }
423:
424: handle_list[unit].cb_term = (
void*)cb_term;
425: handle_list[unit].cb_abt = (
void*)cb_abt;
426: handle_list[unit].cb_error = (
void*)cb_error;
427:
428:
AG903_INTMgrEnableInt(
AG903_IRQ26_DMAC);
429:
430:
return AG903_ENONE;
431: }
432:
433:
451: int32_t
AG903_DMACMgrUnsetIntCallback(
AG903_DMACMgrHandle *handle)
452: {
453: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
454: int32_t retval;
455:
456:
457:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
458: {
459:
return -
AG903_EINVAL;
460: }
461:
462:
463:
if(dmac_int_init_flag ==
false || dmac_int_dmactc_hdrid <= 0)
464: {
465:
return -
AG903_EPERM;
466: }
467:
468: retval =
AG903_INTMgrDeleteHandler(dmac_int_dmactc_hdrid);
469:
if(retval < 0)
470: {
471:
return -
AG903_EFAULT;
472: }
473:
474: dmac_int_init_flag =
false;
475: dmac_int_dmactc_hdrid = 0;
476:
477:
return AG903_ENONE;
478: }
479:
480:
489: int32_t
AG903_DMACMgrEnable(
AG903_DMACMgrHandle *handle)
490: {
491: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
492: uint8_t enable;
493:
494:
495:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
496: {
497:
return -
AG903_EINVAL;
498: }
499:
500:
501: enable = DMACMgr_CheckEnable(unit);
502:
if(
true == enable) {
503:
return -
AG903_EBUSY;
504: }
505:
506:
510: handle_list[unit].term_count = 0;
511:
512:
DMACPrmParamCTRL ctrl;
513:
AG903_DMACPrmGetCTRL_REG(unit, &ctrl);
514: ctrl.ChEn = 1;
515:
AG903_DMACPrmSetCTRL_REG(unit, &ctrl);
516:
517:
return AG903_ENONE;
518: }
519:
520:
529: int32_t
AG903_DMACMgrAbort(
AG903_DMACMgrHandle *handle)
530: {
531: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
532: uint8_t enable;
533:
534:
535:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
536: {
537:
return -
AG903_EINVAL;
538: }
539:
540:
541: enable = DMACMgr_CheckEnable(unit);
542:
if(
false == enable) {
543:
return -
AG903_EPERM;
544: }
545:
546:
AG903_DMACPrmSetCHANNEL_ENABLE(~(1 << unit));
547:
548:
return AG903_ENONE;
549: }
550:
551:
560: int32_t
AG903_DMACMgrSetSyncPeripheral(
int port,
int val)
561: {
562:
563:
if(0 > port || port >=
AG903_DMAC_PORT_NUM)
564: {
565:
return -
AG903_EINVAL;
566: }
567:
568:
if(!(val == 0 || val == 1))
569: {
570:
return -
AG903_EINVAL;
571: }
572:
573: uint32_t reg;
574:
AG903_DMACPrmGetSYNC_PERI_IF(®);
575:
if (val == 0)
576: reg &= ~(1 << port);
577:
else
578: reg |= (1 << port);
579:
AG903_DMACPrmSetSYNC_PERI_IF(reg);
580:
581:
return AG903_ENONE;
582: }
583:
584:
593: int32_t
AG903_DMACMgrSetWatchdog(
int val)
594: {
595:
if(0 > val || val > 0xFFFF)
596: {
597:
return -
AG903_EINVAL;
598: }
599:
600:
AG903_DMACPrmSetWATCHDOG_TIMER(val);
601:
602:
return AG903_ENONE;
603: }
604:
605:
613: int32_t
AG903_DMACMgrSetConstantValue(uint32_t val)
614: {
615:
AG903_DMACPrmSetCONSTANT_VALUE_WRITE_ONLY(val);
616:
617:
return AG903_ENONE;
618: }
619:
620:
628: int32_t
AG903_DMACMgrSetEvent(
int id)
629: {
630:
if(0 > id ||
AG903_DMAC_EVENT_NUM <= id)
631: {
632:
return -
AG903_EINVAL;
633: }
634:
635:
AG903_DMACPrmSetGLOBAL_EVENT(1 << id, 0);
636:
637:
return AG903_ENONE;
638: }
639:
640:
648: int32_t
AG903_DMACMgrClearEvent(
int id)
649: {
650:
if(0 > id ||
AG903_DMAC_EVENT_NUM <= id)
651: {
652:
return -
AG903_EINVAL;
653: }
654:
655:
AG903_DMACPrmSetGLOBAL_EVENT(0, 1 << id);
656:
657:
return AG903_ENONE;
658: }
659:
660:
669: int32_t
AG903_DMACMgrGetEvent(
int id, uint8_t *val)
670: {
671:
if(0 > id ||
AG903_DMAC_EVENT_NUM <= id || NULL == val)
672: {
673:
return -
AG903_EINVAL;
674: }
675:
676: uint32_t reg;
677:
AG903_DMACPrmGetGLOBAL_EVENT(®);
678: *val = (reg >> id) & 0x01;
679:
680:
return AG903_ENONE;
681: }
682:
683:
692: int32_t
AG903_DMACMgrGetStatus(
AG903_DMACMgrHandle *handle,
AG903_DMACMgrStatus *status)
693: {
694: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
695:
696:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle || NULL == status)
697: {
698:
return -
AG903_EINVAL;
699: }
700:
701: status->enable = DMACMgr_CheckEnable(unit);
702:
703:
return AG903_ENONE;
704: }
705:
706:
710:
static uint8_t DMACMgr_CheckEnable(uint32_t unit)
711: {
712: uint8_t retval =
false;
713:
DMACPrmParamCTRL ctrl;
714:
715:
AG903_DMACPrmGetCTRL_REG(unit, &ctrl);
716:
if(0 != ctrl.ChEn) {
717: retval =
true;
718: }
719:
720:
return retval;
721: }
722:
723:
724:
725:
726:
732:
static int get_free_desc_index(
int seq_id)
733: {
734:
int i;
735:
736:
740:
if(seq_id == 0) seq_id = TOTAL_ENTRY_NUM;
741:
742:
743:
for(i = 0 ; i <
AG903_DMAC_LDD_ENTRY_NUM ; i++)
744: {
745:
if(ldd_flag[i] == 0)
746: {
747: ldd_flag[i] = seq_id;
748:
return i;
749: }
750: }
751:
752:
753:
if(NULL != rdd_data)
754: {
755:
for(i =
AG903_DMAC_LDD_ENTRY_NUM ; i <
AG903_DMAC_RDD_ENTRY_NUM+
AG903_DMAC_LDD_ENTRY_NUM ; i++)
756: {
757:
if(rdd_flag[i-
AG903_DMAC_LDD_ENTRY_NUM] == 0)
758: {
759: rdd_flag[i-
AG903_DMAC_LDD_ENTRY_NUM] = seq_id;
760:
return i;
761: }
762: }
763: }
764:
765:
766:
return -1;
767: }
768:
769:
773:
static int32_t remove_desc_entry(
int seq_id)
774: {
775:
int i;
776:
777:
if(seq_id == 0) seq_id = TOTAL_ENTRY_NUM;
778:
779:
780:
for(i = 0 ; i <
AG903_DMAC_LDD_ENTRY_NUM ; i++)
781: {
782:
if(ldd_flag[i] == seq_id)
783: {
784: ldd_flag[i] = 0;
785: }
786: }
787:
788:
789:
for(i =
AG903_DMAC_LDD_ENTRY_NUM ; i <
AG903_DMAC_RDD_ENTRY_NUM+
AG903_DMAC_LDD_ENTRY_NUM ; i++)
790: {
791:
if(rdd_flag[i-
AG903_DMAC_LDD_ENTRY_NUM] == seq_id)
792: {
793: rdd_flag[i-
AG903_DMAC_LDD_ENTRY_NUM] = 0;
794: }
795: }
796:
797:
return AG903_ENONE;
798: }
799:
800:
805:
static AG903_DMACMgrDesc* desc_index_to_addr(
int index)
806: {
807:
if(index <
AG903_DMAC_LDD_ENTRY_NUM)
808: {
809:
return (
AG903_DMACMgrDesc*)(LOCAL_DESC_MEM_ADDR + (index * CH_REG_SIZE));
810: }
else
811: {
812:
return (
AG903_DMACMgrDesc*)(rdd_data+((index-
AG903_DMAC_LDD_ENTRY_NUM)*CH_REG_SIZE));
813: }
814: }
815:
816:
821:
static void* get_desc_reg_addr(
int unit)
822: {
823:
return (
void*)(
AG903_DMAC_BASE + 0x100 + (unit*
AG903_DMAC_DESC_SIZE));
824: }
825:
826:
832:
static AG903_DMACMgrDesc* get_free_desc(
int seq_id)
833: {
834:
int index = get_free_desc_index(seq_id);
835:
if(index == -1)
836: {
837:
return NULL;
838: }
839:
840:
841:
return desc_index_to_addr(index);
842: }
843:
844:
851:
static void write_desc(
AG903_DMACMgrDesc *from,
AG903_DMACMgrDesc *next,
void *to,
int is_reg)
852: {
853:
if(is_reg == 1)
854: {
855: *(uint32_t*)(((uint32_t)to) + 0x0) = from->Ctrl.val;
856: *(uint32_t*)(((uint32_t)to) + 0x8) = from->SrcAddr;
857: *(uint32_t*)(((uint32_t)to) + 0xc) = from->DstAddr;
858: *(uint32_t*)(((uint32_t)to) + 0x10) = (uint32_t)next;
859: *(uint32_t*)(((uint32_t)to) + 0x14) = from->Trns.val;
860: *(uint32_t*)(((uint32_t)to) + 0x18) = from->Stride.val;
861: }
else
862: {
863: *(uint32_t*)(((uint32_t)to) + 0x0) = from->SrcAddr;
864: *(uint32_t*)(((uint32_t)to) + 0x4) = from->DstAddr;
865: *(uint32_t*)(((uint32_t)to) + 0x8) = (uint32_t)next;
866: *(uint32_t*)(((uint32_t)to) + 0xc) = from->Ctrl.val;
867: *(uint32_t*)(((uint32_t)to) + 0x10) = from->Trns.val;
868: *(uint32_t*)(((uint32_t)to) + 0x14) = from->Stride.val;
869: }
870: }
871:
872:
873:
879:
static int set_desc_entry(
AG903_DMACMgrHandleStat *handle,
AG903_DMACMgrDesc *desc_list,
int list_num)
880: {
881:
int i;
882: uint32_t loop;
883:
DMACPrmParamCFG cfg;
884:
AG903_DMACMgrDesc *desc = desc_list;
885:
886:
895:
896:
struct
897: {
898:
899:
AG903_DMACMgrDesc *src;
900:
901:
902:
AG903_DMACMgrDesc *dst;
903: } desc_copy_entry[TOTAL_ENTRY_NUM];
904:
int desc_copy_entry_num = 0;
905:
906:
907: uint8_t ll_circ =
false;
908: uint32_t unit = (handle - handle_list);
909:
910:
911:
AG903_DMACMgrDesc *desc_save_mem = get_free_desc(unit);
912:
if(desc_save_mem == NULL)
913: {
914:
return -
AG903_ENOBUFS;
915: }
916:
917:
918:
AG903_DMACMgrDesc first_desc;
919:
920: first_desc.SrcAddr = 0;
921: first_desc.DstAddr = 0;
922: first_desc.next = 0;
923: first_desc.Ctrl.val = 0;
924: first_desc.Ctrl.st.TCMsk = 1;
925: first_desc.Trns.val = 0;
926: first_desc.Stride.val = 0;
927: write_desc(&first_desc, desc_save_mem, get_desc_reg_addr(unit), 1);
928:
929:
930: handle->term_count = 0;
931: handle->term_addr_table_num = 0;
932:
AG903_DMACPrmGetCFG_REG(unit, &cfg);
933:
934:
for(loop=0; loop<
AG903_DMAC_DESC_LINK_MAX; loop++)
935: {
936:
937:
AG903_DMACMgrDesc *next_desc_save_mem = NULL;
938:
939:
if(desc->next != NULL)
940: {
941:
942:
for(i = 0 ; i < desc_copy_entry_num ; i++)
943: {
944:
if(desc_copy_entry[i].src == desc->next)
945: {
946: next_desc_save_mem = desc_copy_entry[i].dst;
947: ll_circ =
true;
948: }
949: }
950:
951:
952:
if(ll_circ !=
true)
953: {
954: next_desc_save_mem = get_free_desc(unit);
955:
956:
957:
if(next_desc_save_mem == NULL)
958: {
959: remove_desc_entry(unit);
960:
return -
AG903_ENOBUFS;
961: }
962: }
963: }
964:
965:
966: write_desc(desc, next_desc_save_mem, (
void*)desc_save_mem, 0);
967:
968:
if(
true == ll_circ)
969: {
970: handle->term_addr_table[handle->term_addr_table_num].current = (uint32_t)desc_save_mem;
971: handle->term_addr_table[handle->term_addr_table_num].next = (uint32_t)next_desc_save_mem;
972: handle->term_addr_table_num++;
973: }
974:
975: desc_copy_entry[desc_copy_entry_num].src = desc;
976: desc_copy_entry[desc_copy_entry_num].dst = desc_save_mem;
977: desc_save_mem = next_desc_save_mem;
978: desc_copy_entry_num++;
979:
980:
986:
if(desc->next == NULL || ll_circ ==
true || list_num == 0)
987: {
988:
break;
989: }
990:
991: list_num--;
992: desc = desc->next;
993: }
994:
if(
AG903_DMAC_DESC_LINK_MAX <= loop)
995: {
996:
return -
AG903_EINVAL;
997: }
998:
999:
return AG903_ENONE;
1000: }
1001:
1002:
1003:
1016: int32_t
AG903_DMACMgrSetSimpleTrnsDesc(
AG903_DMACMgrHandle *handle,
void *from,
1017: uint32_t from_size,
void *to)
1018: {
1019: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
1020:
AG903_DMACMgrDesc dmac_desc;
1021:
DMACPrmParamCFG cfg = {0};
1022: uint8_t enable;
1023:
1024:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle ||
1025: NULL == from || NULL == to || 0 == from_size ||
AG903_DMAC_1DTRANS_MAX < from_size)
1026: {
1027:
return -
AG903_EINVAL;
1028: }
1029:
1030:
1031: enable = DMACMgr_CheckEnable(unit);
1032:
if(
true == enable) {
1033:
return -
AG903_EBUSY;
1034: }
1035:
1036: cfg.ChPri = 1;
1037:
AG903_DMACPrmSetCFG_REG(unit, &cfg);
1038:
1039: dmac_desc.SrcAddr = (uint32_t)from;
1040: dmac_desc.DstAddr = (uint32_t)to;
1041: dmac_desc.next = 0;
1042: dmac_desc.Ctrl.val = 0;
1043: dmac_desc.Trns.val = 0;
1044: dmac_desc.Trns.d1.TCnt = from_size;
1045: dmac_desc.Stride.val = 0;
1046:
1047:
1048: write_desc(&dmac_desc, NULL, get_desc_reg_addr(unit), 1);
1049:
1050:
return AG903_ENONE;
1051: }
1052:
1053:
1076: int32_t
AG903_DMACMgrSetDescList(
AG903_DMACMgrHandle *handle,
AG903_DMACMgrConfig *config,
1077:
AG903_DMACMgrDesc *desc_list,
int list_num)
1078: {
1079: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
1080: uint8_t enable;
1081:
1082:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle ||
1083: NULL == config || NULL == desc_list || 0 == list_num)
1084: {
1085:
return -
AG903_EINVAL;
1086: }
1087:
1088:
1089: enable = DMACMgr_CheckEnable(unit);
1090:
if(
true == enable) {
1091:
return -
AG903_EBUSY;
1092: }
1093:
1094:
if(
false == initdesc) {
1095: initdesc =
true;
1096:
AG903_DMACPrmSetLOCAL_DESC_MEM_BASE(LOCAL_DESC_MEM_ADDR);
1097: }
1098:
DMACPrmParamCFG cfg = {
1099: .TCIntMsk = config->st.TCIntMsk,
1100: .ErrIntMsk = config->st.ErrIntMsk,
1101: .AbtIntMsk = config->st.AbtIntMsk,
1102: .SrcRS = config->st.SrcRS,
1103: .SrcHEn = config->st.SrcHEn,
1104: .DstRS = config->st.DstRS,
1105: .DstHEn = config->st.DstHEn,
1106: .LLPCnt = config->st.LLPCnt,
1107: .ChGntWin = config->st.ChGntWin,
1108: .ChPri = config->st.ChPri,
1109: .WOMode = config->st.WOMode,
1110: .UnalignMode = config->st.UnalignMode,
1111: };
1112:
AG903_DMACPrmSetCFG_REG(unit, &cfg);
1113:
1114:
return set_desc_entry((
AG903_DMACMgrHandleStat*)handle, desc_list, list_num);
1115: }
1116:
1117:
1127: int32_t
AG903_DMACMgrRemoveDescList(
AG903_DMACMgrHandle *handle)
1128: {
1129: uint32_t unit = ((
AG903_DMACMgrHandleStat*)handle - handle_list);
1130:
1131:
1132:
if(unit >=
AG903_DMAC_UNIT_NUM || &handle_list[unit] != (
AG903_DMACMgrHandleStat*)handle)
1133: {
1134:
return -
AG903_EINVAL;
1135: }
1136:
1137:
return remove_desc_entry(unit);
1138: }
1139:
1140:
1156: int32_t
AG903_DMACMgrSetRemoteDescAddr(
void *addr)
1157: {
1158: int32_t retval =
AG903_ENONE;
1159: uint32_t loop;
1160: uint8_t enable;
1161:
1162:
if(NULL == addr)
1163: {
1164:
return -
AG903_EINVAL;
1165: }
1166:
if(NULL != rdd_data)
1167: {
1168:
return -
AG903_EPERM;
1169: }
1170:
1171:
for(loop=0; loop<
AG903_DMAC_UNIT_NUM; loop++)
1172: {
1173: enable = DMACMgr_CheckEnable(loop);
1174:
if(
true == enable) {
1175: retval = -
AG903_EBUSY;
1176:
break;
1177: }
1178: }
1179:
if(
AG903_ENONE == retval)
1180: {
1181: rdd_data = (uint8_t*)addr;
1182: }
1183:
1184:
return retval;
1185: }
1186:
1187:
1197: int32_t
AG903_DMACMgrClearRemoteDescAddr(
void)
1198: {
1199: int32_t retval =
AG903_ENONE;
1200: uint32_t loop;
1201: uint8_t enable;
1202:
1203:
for(loop=0; loop<
AG903_DMAC_UNIT_NUM; loop++)
1204: {
1205: enable = DMACMgr_CheckEnable(loop);
1206:
if(
true == enable) {
1207: retval = -
AG903_EBUSY;
1208:
break;
1209: }
1210: }
1211:
if(
AG903_ENONE == retval)
1212: {
1213: rdd_data = NULL;
1214: }
1215:
1216:
return retval;
1217: }