- 论坛徽章:
- 0
|
#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"); |
|