Howto use PPC4xx memory to memory DMA

Niklaus Giger niklaus.giger at member.fsf.org
Fri Jan 19 09:16:36 EST 2007


Hi

I ported successfully the Linux 2.6.19 kernel to our PPC405GPr based board and 
mostly everything just works as it should.

As an example I tried to make a small example program to use memory to memory 
DMA and failed miserably. I used the ppc4xx_*dma function, which are not 
referenced anywhere in a stock 2.6.19.1 kernel in the following function:

void dma_mem_to_mem(void *src, void *dst, unsigned int length,
			unsigned int use_interrupt)
{
	int res = 0;
	memset((char *)&p_init, sizeof(p_init), 0);
	p_init.polarity = 0;
	p_init.pwidth   = PW_8;
 	res = ppc4xx_init_dma_channel(DMA_NR, &p_init);
	if (res) {
		printk("%32s: nit_dma_channel return %d %d bytes dest %p\n",
			__FUNCTION__, res, length, dst);
	}
	res = ppc4xx_clr_dma_status(DMA_NR);
	if (res) { 
		printk("%32s: ppc4xx_clr_dma_status %d\n", __FUNCTION__, res);
	}

	ppc4xx_set_dma_mode(DMA_NR, DMA_MODE_MM);
	ppc4xx_set_src_addr(DMA_NR, src);
	ppc4xx_set_dst_addr(DMA_NR, dst);
	ppc4xx_set_dma_count(DMA_NR, length);
	ppc4xx_enable_dma(DMA_NR);
	if (use_interrupt) {
		res = ppc4xx_enable_dma_interrupt(DMA_NR);
	} else {
		res = ppc4xx_disable_dma_interrupt(DMA_NR);
	}
	if (res) { 
		printk("%32s: en/disable_dma_interrupt %d return %d per %d\n",
		__FUNCTION__, use_interrupt, res, 
		ppc4xx_get_peripheral_width(DMA_NR));
	}
}

However the destination memory never changed, even when calling repeatedly 
ppc4xx_get_dma_residu function correctly return first something between 
length and 0 and finally 0.

Any hints would be appreciated. As googleing around didn't allow me to find an 
answer.

Also I am a little confused as I cannot see how something dma_alloc_coherent 
should work on a PPC4xx board.

Best regards

-- 
Niklaus Giger



More information about the Linuxppc-embedded mailing list