AG903ライブラリリファレンス
内容インデックスホーム
Body Source
本文ソース
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(&reg); 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(&reg); 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: }
Copyright (c) 2017-2025 Axell Corporation. All rights reserved.