免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1846 | 回复: 2
打印 上一主题 下一主题

mx27的dma效率 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-05 13:33 |只看该作者 |倒序浏览
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>     
#include <asm/arch/dma.h>
#include <asm/arch/hardware.h>
#include <linux/completion.h>
#include <asm-arm/cacheflush.h>


#define DMA_INTERVAL_MEM 0x2000
#define MEM_DATA 0x27
struct timeval tpstart,tpend;
static volatile unsigned char flag =1;
extern void mxc_dump_dma_register(int channel);
static void dma_complete_fn(void * args, int error, unsigned int count){
     if(error != MXC_DMA_DONE) {
         printk("==========dma transfer is failure[%x]==========\n", error);
     } else {
         printk("==========dma transfer is success==========\n");
     }
     flag = 0;
}

static int __init ram2ram_test_init(void){
     dmach_t channel;
     mxc_dma_requestbuf_t buf;
     int i,j;
     char * memory_base, * src, * dest;
     for(j=0;j<10;j++){
         channel = mxc_dma_request(MXC_DMA_TEST_RAM2RAM, "dma test driver");
         if ( channel < 0 ) {
             printk("request dma fail n");
             return -ENODEV;
         }
         
         memory_base = (char *)__get_free_pages(GFP_KERNEL|GFP_DMA, 4);
         if ( memory_base == NULL ) {
             mxc_dma_free(channel);
             return -ENOMEM;
         }
        
         flush_cache_all();
         
         mxc_dma_callback_set(channel, dma_complete_fn, NULL);
         src = memory_base;   
         dest = src+DMA_INTERVAL_MEM;
         memset(src, MEM_DATA, DMA_INTERVAL_MEM);
         memset(dest, 0, DMA_INTERVAL_MEM);
         buf.src_addr = virt_to_phys(src);
         buf.dst_addr = virt_to_phys(dest);
         buf.num_of_bytes = DMA_INTERVAL_MEM;

         mxc_dma_config(channel, &buf, 1, DMA_MODE_READ);
         do_gettimeofday(&tpstart);
         flag = 1;
         mxc_dma_enable(channel);
         while(flag);
         do_gettimeofday(&tpend);
         
         for(i=0;i<DMA_INTERVAL_MEM;i++){
            if(dest!=MEM_DATA)
                break;
         }

         if(i==DMA_INTERVAL_MEM)
            printk("dest data correct\n");
         else
            printk("dest data is not the same\n");
         printk("dma transfer size:0x%x   used time:%ld s, %ld us\n",buf.num_of_bytes,
            (tpend.tv_sec-tpstart.tv_sec),(tpend.tv_usec-tpstart.tv_usec));

         do_gettimeofday(&tpstart);
         memcpy(dest,src,buf.num_of_bytes);
         do_gettimeofday(&tpend);
         printk("memcpy transfer size:0x%x   used time:%ld s, %ld us\n",buf.num_of_bytes,
            (tpend.tv_sec-tpstart.tv_sec),(tpend.tv_usec-tpstart.tv_usec));
         free_pages((unsigned long)memory_base, 4);
         mxc_dma_free(channel);
     }
     return 0;
}



static void __exit ram2ram_test_exit(void){
     //to do the cleanup
}

module_init(ram2ram_test_init);
module_exit(ram2ram_test_exit);

MODULE_LICENSE("GPL");

论坛徽章:
0
2 [报告]
发表于 2010-05-05 13:36 |只看该作者
运行结果:
# insmod dma_m2m.ko && rmmod dma_m2m
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4399 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4310 us
memcpy transfer size:0x2000   used time:0 s, 100 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4309 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4349 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4305 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4344 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4368 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4310 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4350 us
memcpy transfer size:0x2000   used time:0 s, 99 us
==========dma transfer is success==========
dest data correct
dma transfer size:0x2000   used time:0 s, 4306 us
memcpy transfer size:0x2000   used time:0 s, 99 us

论坛徽章:
0
3 [报告]
发表于 2010-05-05 13:52 |只看该作者
dma每次拷贝4个Bytes,拷贝0x2000 Bytes = 2048次,按平均每传输0x2000 Bytes耗时4500us计算,
即burst 2048次 =  4500us ==> 1 s = 445217次 = 435K 次。

mx27的dma速率只有不到450K?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP