s32 bsp_edma_channel_async_start (u32 channel_id, u32 src_addr, u32 des_addr, u32 len) { struct edma_chan * chan = NULL; struct edma_chan_ops* chan_ops = NULL; u32 a_count = 0; u32 b_count = 0; chan = chan_id_to_chan( channel_id ); if(!chan){ edma_error("chan_id=%d err\n", channel_id); return ERROR; } if(len >= SZ_64K){ /* try 2 vec */ b_count = (!(len%SZ_16K)) ? (len/SZ_16K - 1) \ : (!(len%SZ_8K )) ? (len/SZ_8K - 1) \ : (!(len%SZ_4K )) ? (len/SZ_4K - 1) : 0; if(0==b_count){ edma_error(" len=0x%x is too large, and try 2vec failed \n",len); return ERROR; }else{ a_count = len / (b_count+1); return bsp_edma_channel_2vec_start (channel_id, src_addr, des_addr, len, a_count); } }else{ chan->desc.chan_cfg.lli = 0; chan->desc.chan_cfg.bindx = 0; chan->desc.chan_cfg.cindx = 0; chan->desc.chan_cfg.cnt1 = 0; chan->desc.chan_cfg.cnt0 = len; chan->desc.chan_cfg.src_addr = src_addr; chan->desc.chan_cfg.des_addr = des_addr; chan_ops = chan->device->driver->chan_ops; chan_ops->submit( chan, &chan->desc ); chan_ops->start( chan ); } return OK; }
s32 edmac_test_channel_2vec(enum edma_req_id req, u32 direction) { s32 ret_id = 0; u32 bur_width = 2; u32 bur_len = 3; u32 byte_len = (EDMA_M2M_TEST_LENGHT+1); char *temp = NULL; s32 count = 0; if((NULL == src_buf) || (NULL == des_buf)) { hiedmac_trace(BSP_LOG_LEVEL_ERROR,"-----------edma test not inited \n\n"); return EDMA_FAIL; } temp = src_buf; while (count < EDMA_M2M_TEST_LENGHT) { *temp++ = 'a' + count%20; ++count; } src_buf[EDMA_M2M_TEST_LENGHT - 1]='\0'; temp = des_buf; count = 0; while (count < EDMA_M2M_TEST_LENGHT) { *temp++ = 'b' + count%20; ++count; } des_buf[EDMA_M2M_TEST_LENGHT - 1]='\0'; hiedmac_trace(BSP_LOG_LEVEL_DEBUG,"---src_buf =%c%c%c%c%c%c%c\n", *((char*)src_buf + 0), *((char*)src_buf + 1), *((char*)src_buf + 2), *((char*)src_buf + 3), *((char*)src_buf + 4), *((char*)src_buf + 5), *((char*)src_buf + 6)); hiedmac_trace(BSP_LOG_LEVEL_DEBUG,"---des_buf =%c%c%c%c%c%c%c\n", *((char*)des_buf + 0), *((char*)des_buf + 1), *((char*)des_buf + 2), *((char*)des_buf + 3), *((char*)des_buf + 4), *((char*)des_buf + 5), *((char*)des_buf + 6)); ret_id = bsp_edma_channel_init(req, NULL, 0, 0); if (ret_id < 0) { hiedmac_trace(BSP_LOG_LEVEL_ERROR,"----------error ret_id = 0x%X\n\n",ret_id); return EDMA_CHANNEL_INVALID; } /* set config reg */ if (bsp_edma_channel_set_config((u32)ret_id, direction, bur_width, bur_len)) { hiedmac_trace(BSP_LOG_LEVEL_ERROR,"----------bsp_edma_channel_set_config failed!\n\n"); bsp_edma_channel_free((u32)ret_id); return EDMA_CONFIG_ERROR; } if (bsp_edma_channel_2vec_start((u32)ret_id, (u32)edma_src_addr, (u32)edma_des_addr , byte_len,64)) { hiedmac_trace(BSP_LOG_LEVEL_ERROR,"----------bsp_edma_channel_start FAILED!\n\n"); bsp_edma_channel_free((u32)ret_id); return EDMA_TRXFER_ERROR; } bsp_edma_channel_free((u32)ret_id); if(edmac_verify_data_blk(src_buf,des_buf)) { return EDMA_TRXFER_ERROR; } hiedmac_trace(BSP_LOG_LEVEL_CRIT,"=============== EDMA_CHANNEL_START_SUCCESS !\n"); return EDMA_SUCCESS; }
s32 edma_test(enum edma_req_id req_id, u32 size, u32 bst_width,u32 bst_len, s32 vec_flag) { s32 chan_id = -1; u32 index_size = 0; u32 addr_use1 = 0; u32 addr_use2 = 0; u32 * temp = 0; //bsp_edma_init(); if(0 == (addr1 = (u32*)cacheDmaMalloc(size+32))) { hiedmac_trace(BSP_LOG_LEVEL_DEBUG," malloc1 size=0x%x failed \n",size); return -1; } if(0 == (addr2 = (u32*)cacheDmaMalloc(size+32))) { free(addr1); hiedmac_trace(BSP_LOG_LEVEL_DEBUG," malloc2 size=0x%x failed \n",size); return -1; } printf("addr1=0x%x, addr2=0x%x \n",(u32)addr1,(u32)addr2); edma_build_data((u8*)addr1, size+32, 0x20); edma_build_data((u8*)addr2, size+32, 0x40); /*test: 让addr 1k 对齐 */ addr_use1 = (u32)addr1+4; addr_use2 = (u32)addr2+4; printf("addr_use1=0x%x, addr_use2=0x%x \n",addr_use1,addr_use2); temp = (u32*)addr_use1; for(index_size=0; index_size<(size/4);index_size++ ) { *temp++ = (u32)index_size; } chan_id = bsp_edma_channel_init(req_id,0,0,0); bsp_edma_channel_set_config(chan_id,3,bst_width,bst_len); if(1==vec_flag) { bsp_edma_channel_start(chan_id, addr_use1, addr_use2 , size ); } else { bsp_edma_channel_2vec_start(chan_id, addr_use1, addr_use2 , size,edma_align_size); } while( EDMA_CHN_BUSY == bsp_edma_channel_is_idle(chan_id) ) { printf("a"); chan_stop++; if (20==chan_stop) { bsp_edma_channel_stop( chan_id); printf("A"); } } printf("a\n"); bsp_edma_channel_free(chan_id); hiedmac_trace(BSP_LOG_LEVEL_DEBUG, "CMP after edma tranfer:%d \n",memcmp((void*)addr_use1,(void*)addr_use2,size)); hiedmac_trace(BSP_LOG_LEVEL_DEBUG, "CMP size+4 after edma :%d \n",memcmp((void*)addr_use1,(void*)addr_use2,size+4)); cacheDmaFree(addr1); cacheDmaFree(addr2); return 0; }
s32 edma_test(enum edma_req_id req_id, u32 size, u32 bst_width,u32 bst_len, s32 vec_flag, u32 edma_align_size ) { s32 chan_id = -1; s32 index = 0; u8* src_virt = 0; u8* des_virt = 0; edma_addr_t src_phy; edma_addr_t des_phy; u32 src_phy_used = 0; u32 des_phy_used = 0; u8 *temp = NULL; u32 count = 0; u32 size_plus = 32; //bsp_edma_init(); src_virt = dma_alloc_coherent(NULL, (size+size_plus), &src_phy, GFP_DMA|__GFP_WAIT); if(0==src_virt) { printk("dma_alloc_coherent ERROR, src_virt \n"); return EDMA_FAIL; } des_virt = dma_alloc_coherent(NULL, (size+size_plus), &des_phy, GFP_DMA|__GFP_WAIT); if(0==des_virt) { dma_free_coherent(NULL, (size+size_plus) , src_virt, src_phy); printk("dma_alloc_coherent ERROR, des_virt \n"); return EDMA_FAIL; } printk("src_virt=0x%x, des_virt=0x%x \n",(u32)src_virt,(u32)des_virt); printk("src_phy=0x%x, des_phy=0x%x \n",src_phy,des_phy); temp = src_virt; while (count < (size+size_plus)) { *temp++ = 'a' + count%20; ++count; } src_virt[size - 1]='\0'; temp = des_virt; count = 0; while (count < (size+size_plus)) { *temp++ = 'b' + count%20; ++count; } des_virt[size - 1]='\0'; printk("\n src_virt:"); for(index=0;index<32;index++) { printk("%c",*((char*)src_virt + index)); } printk("\n des_virt:"); for(index=0;index<32;index++) { printk("%c",*((char*)des_virt + index)); } printk("\n"); src_phy_used = (u32)src_phy+4; des_phy_used = (u32)des_phy+4; printk("addr_use1=0x%x, addr_use2=0x%x \n",src_phy_used,des_phy_used); chan_id = bsp_edma_channel_init(req_id,0,0,0); bsp_edma_channel_set_config(chan_id,3,bst_width,bst_len); if(1==vec_flag) { bsp_edma_channel_start(chan_id, src_phy_used, des_phy_used , size ); } else { bsp_edma_channel_2vec_start(chan_id, src_phy_used, des_phy_used , size, edma_align_size); } while( EDMA_CHN_BUSY == bsp_edma_channel_is_idle(chan_id) ) { printk("a"); /*bsp_edma_channel_stop(chan_id);*/ //bsp_edma_current_cnt( chan_id); } printk("a\n"); bsp_edma_channel_free(chan_id); hiedmac_trace(BSP_LOG_LEVEL_DEBUG, "CMP after edma tranfer:%d \n",memcmp((void*)(src_virt+4),(void*)(des_virt+4),size)); hiedmac_trace(BSP_LOG_LEVEL_DEBUG, "CMP size+4 after edma :%d \n",memcmp((void*)(src_virt+4),(void*)(des_virt+4),size+4)); printk("\n src_virt:"); for(index=0;index<20;index++) { printk("%c",*((char*)src_virt + index)); } printk("\n des_virt:"); for(index=0;index<20;index++) { printk("%c",*((char*)des_virt + index)); } hiedmac_trace(BSP_LOG_LEVEL_DEBUG," ---des_buf =%c%c%c%c%c%c%c\n", *((char*)des_virt + 0), *((char*)des_virt + 1), *((char*)des_virt + 2), *((char*)des_virt + 3), *((char*)des_virt + 4), *((char*)des_virt + 5), *((char*)des_virt + 6)); printk("\n"); dma_free_coherent(NULL, (size+size_plus) , src_virt, src_phy); dma_free_coherent(NULL, (size+size_plus) , des_virt, des_phy); return 0; }