[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: External DMA



Hi!

I have a couple of comments:

>etrax_dma_descr 	descr;

This variable is stack allocated and will disappear when setup_dma
exits. This means that the DMA will point to deallocated data.
You can declare the descriptor globally in the file or in a struct
describing the port/driver. 

>*R_DMA_CH5_FIRST = (unsigned long)&descr;

The DMA always work with physical addresses so you should do

*R_DMA_CH5_FIRST = virt_to_phys(&descr);

I have attached an experimental external DMA driver for linux 2.4
that I am working on. The driver is not tested and will not
compile for the current version of elinux but it may give you a 
few hints.

I am not sure yet if it is best to use the dma descriptor interrupt
or the external DMA interrupt. The experimental driver uses the
external DMA interrupt.

Please keep me informed of any progress with the external DMA.

Best Regards,
/Mikael



-----Original Message-----
From: owner-dev-etrax@xxxxxxx.com]On">mailto:owner-dev-etrax@xxxxxxx.com]On Behalf Of Randy Lee(õ)
Sent: Friday, February 16, 2001 6:30 AM
To: dev-etrax
Subject: External DMA


Hi!
I am trying to use external dma to transfer bulk of data from external
device to extrax's dram memory.
After starting dma, I got eol dma interrupt. But returning from interrupt
handler to normal program sequence failed, and system locked.

Following is my source code.
// ?????????????????????????????
void setup_dma(int size, char * buffer)
{
 	etrax_dma_descr 	descr;

	descr.sw_len = size;
 	descr.ctrl = d_int| d_eol;   // Interrupt when dma done
	descr.next = 0;
	descr.buf = virt_to_phys(buf);
	descr.hw_len = 0;
	descr.status = 0;

	RESET_DMA(5);
	WAIT_DMA(5);
	*R_DMA_CH5_CLR_INTR	= 3;
	*R_DMA_CH5_FIRST = (unsigned long)&descr;
  	*R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, start);

	*R_EXT_DMA_0_CMD =  IO_STATE(R_EXT_DMA_0_CMD, cnt, enable) |
				IO_STATE(R_EXT_DMA_0_CMD, rqpol, ahigh) |
				IO_STATE(R_EXT_DMA_0_CMD, apol, alow) |
				IO_STATE(R_EXT_DMA_0_CMD, rq_ack, burst) |
				IO_STATE(R_EXT_DMA_0_CMD, wid, word) |
				IO_STATE(R_EXT_DMA_0_CMD, dir, input) |
				IO_STATE(R_EXT_DMA_0_CMD, run, start) |
				((size >> 1) & 0xffff);
}

static void dma_int(int irq, void *dev_id, pt_regs * regs)
{
	printk("dma_int\n");
	*R_SET_EOP = 0x2;	 // Force EOP for DMA channel 5
	*R_DMA_CH5_CLR_INTR	= 3;
	printk("dma_int done\n");
}
// ???????????????????????????????????????????????????

Are there any source codes to succeed using external dma?

Thanks,
Randy

============================================
Randy Lee(AIA좬)
Sr. System Engineer.
3R Inc.
Tel) +82-2-840-3551
Email) randylee@xxxxxxx.kr
Web) http://www.3r.co.kr


extern_dma.c

extern_dma.h