All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: Howto use PPC4xx memory to memory DMA
@ 2007-01-19  8:49 - Reyneke
  2007-01-19 19:48 ` T Ziomek
  0 siblings, 1 reply; 10+ messages in thread
From: - Reyneke @ 2007-01-19  8:49 UTC (permalink / raw)
  To: niklaus.giger; +Cc: linuxppc-embedded

Niklaus,

Here are a few things to check:

1. Your memory destination and source addresses are contiguous. You can get 
this using something like:

mem = (void*)__get_free_pages(GFP_KERNEL | GFP_DMA, get_order(size));

2. Your source and dest addresses are _bus_ addresses. You can get these by:

source = virt_to_bus((u32 *)mem);


Also, we had some trouble with the ppc4xx_ functions using 440 - it seems 
these functions are specific to the PLB4. So if you are trying to do DMA on 
say the PLB peripheral bus on a memory mapped device, you definitely have 
some trouble.

I have some code for doing both - so of you need any further help, just ask.

Regards
   Jan Reyneke

_________________________________________________________________
Get Hotmail, News, Sport and Entertainment from MSN on your mobile.  
http://www.msn.txt4content.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
  2007-01-19  8:49 Howto use PPC4xx memory to memory DMA - Reyneke
@ 2007-01-19 19:48 ` T Ziomek
  2007-01-21 21:28   ` - Reyneke
  0 siblings, 1 reply; 10+ messages in thread
From: T Ziomek @ 2007-01-19 19:48 UTC (permalink / raw)
  To: Reyneke; +Cc: niklaus.giger, linuxppc-embedded

On Fri, 19 Jan 2007, - Reyneke wrote:
> Here are a few things to check:
>
> 1. Your memory destination and source addresses are contiguous. You can get 
> this using something like:
>
> mem = (void*)__get_free_pages(GFP_KERNEL | GFP_DMA, get_order(size));
>
> 2. Your source and dest addresses are _bus_ addresses. You can get these by:
>
> source = virt_to_bus((u32 *)mem);

The above contradicts an email by Ben H back on 22 Dec:
<http://ozlabs.org/pipermail/linuxppc-embedded/2006-December/025546.html>
But I don't know enough to resolve the conflict...

Tom
-- 
   /"\  ASCII Ribbon Campaign   |
   \ /                          |   Email to user 'CTZ001'
    X        Against HTML       |             at 'email.mot.com'
   / \     in e-mail & news     |

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
  2007-01-19 19:48 ` T Ziomek
@ 2007-01-21 21:28   ` - Reyneke
  2007-01-22 17:18     ` Eugene Surovegin
  0 siblings, 1 reply; 10+ messages in thread
From: - Reyneke @ 2007-01-21 21:28 UTC (permalink / raw)
  To: ctz001; +Cc: linuxppc-embedded

Yes, I know - that email is in response to a question I posted.  :)

This seems to be one of those ongoing uncertainties. It seems commonly 
advocated that you shouldn't use it, but as yet I've found no suitable 
alternative.

Some more reading on why you *should* use it:

http://ozlabs.org/pipermail/linuxppc64-dev/2004-March/001276.html

It would be nice if we could get a definitive answer to this. Anyone out 
there who knows?

Cheers
   Jan Reyneke


>From: T Ziomek <ctz001@email.mot.com>
>>
>>source = virt_to_bus((u32 *)mem);
>
>The above contradicts an email by Ben H back on 22 Dec:
><http://ozlabs.org/pipermail/linuxppc-embedded/2006-December/025546.html>
>But I don't know enough to resolve the conflict...
>
>Tom

_________________________________________________________________
Get Hotmail, News, Sport and Entertainment from MSN on your mobile.  
http://www.msn.txt4content.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
  2007-01-21 21:28   ` - Reyneke
@ 2007-01-22 17:18     ` Eugene Surovegin
  0 siblings, 0 replies; 10+ messages in thread
From: Eugene Surovegin @ 2007-01-22 17:18 UTC (permalink / raw)
  To: - Reyneke; +Cc: ctz001, linuxppc-embedded

On Sun, Jan 21, 2007 at 09:28:34PM +0000, - Reyneke wrote:
> 
> This seems to be one of those ongoing uncertainties. It seems commonly 
> advocated that you shouldn't use it, but as yet I've found no suitable 
> alternative.

Really?

Could you elaborate, why API described in Documentation/DMA-API.txt 
(e.g. "Streaming DMA mappings") is not suitable for you?.

-- 
Eugene

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
@ 2008-01-07 10:57 padmanabha
  0 siblings, 0 replies; 10+ messages in thread
From: padmanabha @ 2008-01-07 10:57 UTC (permalink / raw)
  To: linuxppc-embedded

Hi,

I am using 2.6.23 kernel for ppc 440spe based board. When i tried  
memory to memory
  DMA ( example code taken from earlier posting, & used DMA channel  
zero ), DMA is
not happening.

Can any one help me. Any hints would be appreciated.

Thanks and Regards,
Padmanabha.s

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
  2007-01-19 22:32 Alexis Berlemont
@ 2007-01-21 19:47 ` Eugene Surovegin
  0 siblings, 0 replies; 10+ messages in thread
From: Eugene Surovegin @ 2007-01-21 19:47 UTC (permalink / raw)
  To: Alexis Berlemont; +Cc: linuxppc-embedded

On Fri, Jan 19, 2007 at 11:32:04PM +0100, Alexis Berlemont wrote:
> Hi,
> 
> I would like to add some comments on this topic, I am very interested by more 
> details.
> 
> > Here are a few things to check:
> >
> > 1. Your memory destination and source addresses are contiguous. You can get
> > this using something like:
> >
> > mem = (void*)__get_free_pages(GFP_KERNEL | GFP_DMA, get_order(size));
> >
> > 2. Your source and dest addresses are _bus_ addresses. You can get these
> > by:
> >
> > source = virt_to_bus((u32 *)mem);
> 
> But you must check that your src and dst addresses does not point to 
> a "vmallocated" buffer (unless you allocated less than PAGE_SIZE and you know 
> how to convert a virtual kernel address into a physical address, for example 
> thanks to the function iopa() ). 
> Consequently, with a 2.6 kernel, the function virt_to_bus() will not work 
> properly on a virtual address.
> 
> Consequently, if the dst or the src address belongs to a buffer allocated with 
> vmalloc() or ioremap(), you will have to use the function iopa() to perform 
> the translation.
> 
> Besides, I have a question : I do not understand why the 2.6 implementation of 
> the function virt_to_bus() is different from the 2.4 version; 
> ->on 2.4, virt_to_bus() calls iopa() (if CONFIG_PPC4xx is defined),therefore 
> it works with virtual addresses (vmallocated or ioremapped);
> ->on 2.6, virt_to_bus works with logical address (kmallocated or 
> get_free_pages);
> 
> Do you know why ?

virt_to_bus was never supposed to work on anything else except for 
directly mapped kernel address. 2.6 version just fixes this for 4xx. 
And yes, virt_to_bus is deprecated.


> 
> > Ooh - and the 3d thing - cache coherence. I.e.:
> >
> >       dma_cache_inv((u32)mem, (u32)nBytes);
> >
> 
> I just add a little precision:
> 
> With PPC405 (no cache coherency integrated), you have to invalidate the cache 
> of the destination buffer (with dma_cache_inv() )and you have to write back 
> the cache of the source buffer (with dma_cache_wback() ). But if you do not 
> want to care about the direction point, you can use dma_cache_inv_wback() 
> which does both operations.
> 
> Of course, if you work with an "ioremapped" area (either as source or 
> destination buffer), this functions are useless for this buffer (ioremap() 
> maps the address range with the flag "PAGE_NO_CACHE").

Guys, please stop reinventing the wheel. There is a documented kernel 
API which takes care of coherency issues and it should be used for any 
sort of DMA (be it general purpose DMA controller or external 
DMA-capable device).

PLEASE, read Documentation/DMA-API.txt and use it to obtain DMA-able 
address for your buffer.

-- 
Eugene

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
@ 2007-01-19 22:32 Alexis Berlemont
  2007-01-21 19:47 ` Eugene Surovegin
  0 siblings, 1 reply; 10+ messages in thread
From: Alexis Berlemont @ 2007-01-19 22:32 UTC (permalink / raw)
  To: linuxppc-embedded

Hi,

I would like to add some comments on this topic, I am very interested by more 
details.

> Here are a few things to check:
>
> 1. Your memory destination and source addresses are contiguous. You can get
> this using something like:
>
> mem = (void*)__get_free_pages(GFP_KERNEL | GFP_DMA, get_order(size));
>
> 2. Your source and dest addresses are _bus_ addresses. You can get these
> by:
>
> source = virt_to_bus((u32 *)mem);

But you must check that your src and dst addresses does not point to 
a "vmallocated" buffer (unless you allocated less than PAGE_SIZE and you know 
how to convert a virtual kernel address into a physical address, for example 
thanks to the function iopa() ). 
Consequently, with a 2.6 kernel, the function virt_to_bus() will not work 
properly on a virtual address.

Consequently, if the dst or the src address belongs to a buffer allocated with 
vmalloc() or ioremap(), you will have to use the function iopa() to perform 
the translation.

Besides, I have a question : I do not understand why the 2.6 implementation of 
the function virt_to_bus() is different from the 2.4 version; 
->on 2.4, virt_to_bus() calls iopa() (if CONFIG_PPC4xx is defined),therefore 
it works with virtual addresses (vmallocated or ioremapped);
->on 2.6, virt_to_bus works with logical address (kmallocated or 
get_free_pages);

Do you know why ?

> Ooh - and the 3d thing - cache coherence. I.e.:
>
>       dma_cache_inv((u32)mem, (u32)nBytes);
>

I just add a little precision:

With PPC405 (no cache coherency integrated), you have to invalidate the cache 
of the destination buffer (with dma_cache_inv() )and you have to write back 
the cache of the source buffer (with dma_cache_wback() ). But if you do not 
want to care about the direction point, you can use dma_cache_inv_wback() 
which does both operations.

Of course, if you work with an "ioremapped" area (either as source or 
destination buffer), this functions are useless for this buffer (ioremap() 
maps the address range with the flag "PAGE_NO_CACHE").

>
>
> Also, we had some trouble with the ppc4xx_ functions using 440 - it seems
> these functions are specific to the PLB4. So if you are trying to do DMA on
> say the PLB peripheral bus on a memory mapped device, you definitely have
> some trouble.

I do not understand, I would be very interested by what kind of trouble you 
had to cope with.

Alexis.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Howto use PPC4xx memory to memory DMA
  2007-01-19  9:35 - Reyneke
@ 2007-01-19 20:47 ` Niklaus Giger
  0 siblings, 0 replies; 10+ messages in thread
From: Niklaus Giger @ 2007-01-19 20:47 UTC (permalink / raw)
  To: - Reyneke; +Cc: linuxppc-embedded

Am Freitag, 19. Januar 2007 10:35 schrieb - Reyneke:
> Ooh - and the 3d thing - cache coherence. I.e.:
>
> 	dma_cache_inv((u32)mem, (u32)nBytes);
>
> >>Here are a few things to check:
Thanks a lot for your tips. First I called
a) __get_free_pages(GFP_KERNEL | GFP_DMA, get_order(size));
for the source and destination address.
Then before calling ppc4xx_enable_dma I added
b) ppc4xx_set_src_addr(DMA_NR, virt_to_bus(src));
c) ppc4xx_set_src_addr(DMA_NR, virt_to_bus(dst));
d) flush_dcache_all(); 
With these changes I got at least one byte copied. After fixing the 
ppc4xx_enable_dma everything worked fine. (Patch posted a few minutes ago.)

Did you manage to use DMA on PLB peripheral bus on a memory mapped dev? I 
think there one should also increment the source or destination address. But 
I have no example HW/code at hand to test these two cases too.

Best regards
-- 
Niklaus Giger

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Howto use PPC4xx memory to memory DMA
@ 2007-01-19  9:35 - Reyneke
  2007-01-19 20:47 ` Niklaus Giger
  0 siblings, 1 reply; 10+ messages in thread
From: - Reyneke @ 2007-01-19  9:35 UTC (permalink / raw)
  To: niklaus.giger; +Cc: linuxppc-embedded

Ooh - and the 3d thing - cache coherence. I.e.:

	dma_cache_inv((u32)mem, (u32)nBytes);



>>Here are a few things to check:

_________________________________________________________________
Find Love This New Year With match.com! http://msnuk.match.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Howto use PPC4xx memory to memory DMA
@ 2007-01-18 22:16 Niklaus Giger
  0 siblings, 0 replies; 10+ messages in thread
From: Niklaus Giger @ 2007-01-18 22:16 UTC (permalink / raw)
  To: linuxppc-embedded

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-01-07 11:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-19  8:49 Howto use PPC4xx memory to memory DMA - Reyneke
2007-01-19 19:48 ` T Ziomek
2007-01-21 21:28   ` - Reyneke
2007-01-22 17:18     ` Eugene Surovegin
  -- strict thread matches above, loose matches on Subject: below --
2008-01-07 10:57 padmanabha
2007-01-19 22:32 Alexis Berlemont
2007-01-21 19:47 ` Eugene Surovegin
2007-01-19  9:35 - Reyneke
2007-01-19 20:47 ` Niklaus Giger
2007-01-18 22:16 Niklaus Giger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.