* Using DMA
@ 2008-11-06 2:07 Bruce_Leonard
2008-11-06 18:29 ` Scott Wood
2008-11-07 15:43 ` Timur Tabi
0 siblings, 2 replies; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-06 2:07 UTC (permalink / raw)
To: linuxppc-embedded
This may be the wrong forum for this question. If so I apologize, and
could someone please tell me the appropriate place to ask?
Assuming this is the right place, I'm working with the 2.6.27 (stable)
kernel and an MPC8347E processor. I'm using a custom NAND controller and
a custom driver to talk with that controller. I'm now to the point where
I'm trying to optimize/improve performance and something I'd like to do is
set up the driver to use DMA transfers to the controller. (As an
additional bit of info, I modeled my driver on the Cafe driver.) However,
no one here has ever had to set up DMA from scratch before, it's always
been done by an existing driver or the kernel, so I'm in uncharted
teritory.
In the Cafe driver, Linux Device Drivers 3rd Edition, and DMA-mapping.txt
everyone talks about how to allocate buffers using
dma/pci_alloc_coherent(), but no one talks about how to actually use it.
I'm pretty sure (even in my ignorance) that just allocating a DMA coherent
buffer and then copying in and out of it does NOT actually engage the
underlying hardware and perform a DMA transfer.
With some digging I've found the Freescale Elo/Elo Plus DMA driver which
supports my processor. What I'm not clear on is how to actually make use
of it. How do I tie my NAND driver to the Freescale DMA driver and
actually get the hardware to work? Any pointers are greatly appreciated.
Thanks.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-06 2:07 Using DMA Bruce_Leonard
@ 2008-11-06 18:29 ` Scott Wood
2008-11-06 18:36 ` Bill Gatliff
2008-11-07 15:43 ` Timur Tabi
1 sibling, 1 reply; 24+ messages in thread
From: Scott Wood @ 2008-11-06 18:29 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> In the Cafe driver, Linux Device Drivers 3rd Edition, and DMA-mapping.txt
> everyone talks about how to allocate buffers using
> dma/pci_alloc_coherent(), but no one talks about how to actually use it.
> I'm pretty sure (even in my ignorance) that just allocating a DMA coherent
> buffer and then copying in and out of it does NOT actually engage the
> underlying hardware and perform a DMA transfer.
Generally, you program the device itself to peform the transfer. I'm
assuming that your custom NAND controller can't do DMA by itself, though.
> With some digging I've found the Freescale Elo/Elo Plus DMA driver which
> supports my processor. What I'm not clear on is how to actually make use
> of it. How do I tie my NAND driver to the Freescale DMA driver and
> actually get the hardware to work? Any pointers are greatly appreciated.
Tell the DMA controller where to move data from, and where to move it to.
-Scott
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-06 18:29 ` Scott Wood
@ 2008-11-06 18:36 ` Bill Gatliff
2008-11-06 20:58 ` Bruce_Leonard
0 siblings, 1 reply; 24+ messages in thread
From: Bill Gatliff @ 2008-11-06 18:36 UTC (permalink / raw)
To: Scott Wood; +Cc: Bruce_Leonard, linuxppc-embedded
Scott Wood wrote:
> Bruce_Leonard@selinc.com wrote:
>> In the Cafe driver, Linux Device Drivers 3rd Edition, and
>> DMA-mapping.txt everyone talks about how to allocate buffers using
>> dma/pci_alloc_coherent(), but no one talks about how to actually use
>> it. I'm pretty sure (even in my ignorance) that just allocating a DMA
>> coherent buffer and then copying in and out of it does NOT actually
>> engage the underlying hardware and perform a DMA transfer.
Does the "adma" stuff address this any?
b.g.
--
Bill Gatliff
bgat@billgatliff.com
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-06 18:36 ` Bill Gatliff
@ 2008-11-06 20:58 ` Bruce_Leonard
2008-11-06 21:42 ` Bill Gatliff
0 siblings, 1 reply; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-06 20:58 UTC (permalink / raw)
To: Bill Gatliff; +Cc: Scott Wood, linuxppc-embedded
Bill Gatliff <bgat@billgatliff.com> wrote on 11/06/2008 10:36:58 AM:
> Scott Wood wrote:
> > Bruce_Leonard@selinc.com wrote:
> >> In the Cafe driver, Linux Device Drivers 3rd Edition, and
> >> DMA-mapping.txt everyone talks about how to allocate buffers using
> >> dma/pci_alloc_coherent(), but no one talks about how to actually use
> >> it. I'm pretty sure (even in my ignorance) that just allocating a DMA
> >> coherent buffer and then copying in and out of it does NOT actually
> >> engage the underlying hardware and perform a DMA transfer.
>
> Does the "adma" stuff address this any?
>
What is "adma"?
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-06 20:58 ` Bruce_Leonard
@ 2008-11-06 21:42 ` Bill Gatliff
0 siblings, 0 replies; 24+ messages in thread
From: Bill Gatliff @ 2008-11-06 21:42 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: Scott Wood, linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> Bill Gatliff <bgat@billgatliff.com> wrote on 11/06/2008 10:36:58 AM:
>
>> Scott Wood wrote:
>>> Bruce_Leonard@selinc.com wrote:
>>>> In the Cafe driver, Linux Device Drivers 3rd Edition, and
>>>> DMA-mapping.txt everyone talks about how to allocate buffers using
>>>> dma/pci_alloc_coherent(), but no one talks about how to actually use
>>>> it. I'm pretty sure (even in my ignorance) that just allocating a DMA
>>>> coherent buffer and then copying in and out of it does NOT actually
>>>> engage the underlying hardware and perform a DMA transfer.
>> Does the "adma" stuff address this any?
>>
>
> What is "adma"?
>
> Bruce
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
Asynchronous DMA. See this paper, for example:
http://www.power.org/devcon/07/Session_Downloads/PADC07_Aytac_Haluk_09_13_07_layout_FINAL.pdf
It looks like the structure of interest is async_tx_submit. Beyond
that, I can't offer much because I haven't used it.
b.g.
--
Bill Gatliff
bgat@billgatliff.com
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-06 2:07 Using DMA Bruce_Leonard
2008-11-06 18:29 ` Scott Wood
@ 2008-11-07 15:43 ` Timur Tabi
2008-11-07 21:31 ` Bruce_Leonard
2008-11-10 0:09 ` Bruce_Leonard
1 sibling, 2 replies; 24+ messages in thread
From: Timur Tabi @ 2008-11-07 15:43 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
On Wed, Nov 5, 2008 at 8:07 PM, <Bruce_Leonard@selinc.com> wrote:
> This may be the wrong forum for this question. If so I apologize, and
> could someone please tell me the appropriate place to ask?
You're in the right place.
> In the Cafe driver, Linux Device Drivers 3rd Edition, and DMA-mapping.txt
> everyone talks about how to allocate buffers using
> dma/pci_alloc_coherent(), but no one talks about how to actually use it.
That's because allocating a DMA buffer is a task common to all DMA
operations. Everything else about DMA is device- and/or
architecture-specific.
DMA buffers typically have special requirements with respect to
contiguousness and caching.
> I'm pretty sure (even in my ignorance) that just allocating a DMA coherent
> buffer and then copying in and out of it does NOT actually engage the
> underlying hardware and perform a DMA transfer.
That is correct. A DMA buffer, once allocated, generally acts very
much like any other piece of memory allocated by kmalloc(). The buffer
is typically allocated from main memory, so there's no way to make it
do anything special.
> With some digging I've found the Freescale Elo/Elo Plus DMA driver which
> supports my processor. What I'm not clear on is how to actually make use
> of it. How do I tie my NAND driver to the Freescale DMA driver and
> actually get the hardware to work? Any pointers are greatly appreciated.
The Elo device driver is an async DMA back-end driver. That is, you
don't communicate with that driver directly, you communicate with the
async library (which is new - so you won't find it in LDD3).
Please note that the async DMA stuff is intended for single-shot
one-way transfers only between two memory regions. It has a very
specific usage. If you need something more complicated, you'll need
to write your own DMA driver. You can find an example of that in
sound/soc/fsl/fsl_dma.c.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 15:43 ` Timur Tabi
@ 2008-11-07 21:31 ` Bruce_Leonard
2008-11-07 21:46 ` Timur Tabi
2008-11-10 0:09 ` Bruce_Leonard
1 sibling, 1 reply; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-07 21:31 UTC (permalink / raw)
To: Timur Tabi; +Cc: timur.tabi, linuxppc-embedded
Hi Timur,
Thanks for the reply, very informative.
>
> The Elo device driver is an async DMA back-end driver. That is, you
> don't communicate with that driver directly, you communicate with the
> async library (which is new - so you won't find it in LDD3).
>
> Please note that the async DMA stuff is intended for single-shot
> one-way transfers only between two memory regions. It has a very
> specific usage. If you need something more complicated, you'll need
> to write your own DMA driver. You can find an example of that in
> sound/soc/fsl/fsl_dma.c.
>
I'm not sure if I need something as complicated as sound/soc/fsl/fsl_dma.c
or not. Maybe you can offer an opinion. The NAND flash in our product is
our backing storage, i.e., our hard drive. We know that we're going to be
storing away system status at about a 1 second rate and in the future
we'll probably end up storing collected data at a very high rate, so we're
potentially going to be doing a LOT of data movement to the NAND. I'm
still not clear on the adma stuff, so I'm not sure if a "single-shot
one-way transfer" is appropriate or not. Seems like I'd waste a lot of
time setting up and tearing down the DMA channel.
So, do I need something complicated?
Thanks again for the explination Timur, I appreciate it.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 21:31 ` Bruce_Leonard
@ 2008-11-07 21:46 ` Timur Tabi
2008-11-07 22:12 ` Bruce_Leonard
0 siblings, 1 reply; 24+ messages in thread
From: Timur Tabi @ 2008-11-07 21:46 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
On Fri, Nov 7, 2008 at 3:31 PM, <Bruce_Leonard@selinc.com> wrote:
> I'm not sure if I need something as complicated as sound/soc/fsl/fsl_dma.c
> or not. Maybe you can offer an opinion. The NAND flash in our product is
> our backing storage, i.e., our hard drive. We know that we're going to be
> storing away system status at about a 1 second rate and in the future
> we'll probably end up storing collected data at a very high rate, so we're
> potentially going to be doing a LOT of data movement to the NAND. I'm
> still not clear on the adma stuff, so I'm not sure if a "single-shot
> one-way transfer" is appropriate or not. Seems like I'd waste a lot of
> time setting up and tearing down the DMA channel.
>
> So, do I need something complicated?
The Async DMA code is very much like an "offload memcpy". The Elo
control will handle the memcpy while the host CPU can do something
else. Keep in mind that while the Elo is transferring data, the
memory bus will be saturated.
Whether or not using async dma is worth the effort can only be
determined by profiling the code. Either it's better, or it's not.
There's no real way to tell in advance.
The advantage of using async DMA over memcpy is that you don't have to
worry about large memcpy operations blocking the CPU and causing apps
the kernel and apps to stall while your driver is copying data. So
even if overall performance drops, latency will improve and
the system will appear to be faster. The drawback is that async dma
is more complicated than plain old memcpy. Since the dma is
asynchronous, you'll need to register a callback function which gets
notified when the Elo has completed the DMA transfer. That's a very
different design than memcpy.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 21:46 ` Timur Tabi
@ 2008-11-07 22:12 ` Bruce_Leonard
2008-11-07 22:28 ` Timur Tabi
2008-11-09 3:25 ` Bill Gatliff
0 siblings, 2 replies; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-07 22:12 UTC (permalink / raw)
To: Timur Tabi; +Cc: timur.tabi, linuxppc-embedded
timur.tabi@gmail.com wrote on 11/07/2008 01:46:42 PM:
>
> Whether or not using async dma is worth the effort can only be
> determined by profiling the code. Either it's better, or it's not.
> There's no real way to tell in advance.
>
Pretty much the answer I expected :), I was just hoping that "wiser and
more experienced" minds would say "oh, well to do what you want you should
go in this direction". Ah well, such is the life of a kernel hacker.
So it sounds like the async dma is the way to go, since I want to off load
as much as possible from the core. As you say, though, it's new and not
in LDD3. Is .../drivers/dma/dmaengine.c what everyone is refering to as
async dma? If not, what is? And what in the kernel is already using it
so I can look at some example code.
Thanks very much for the pointers Timur.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 22:12 ` Bruce_Leonard
@ 2008-11-07 22:28 ` Timur Tabi
2008-11-07 22:37 ` Bruce_Leonard
2008-11-09 3:26 ` Bill Gatliff
2008-11-09 3:25 ` Bill Gatliff
1 sibling, 2 replies; 24+ messages in thread
From: Timur Tabi @ 2008-11-07 22:28 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: timur.tabi, linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> So it sounds like the async dma is the way to go, since I want to off load
> as much as possible from the core. As you say, though, it's new and not
> in LDD3. Is .../drivers/dma/dmaengine.c what everyone is refering to as
> async dma?
Yes.
> If not, what is? And what in the kernel is already using it
> so I can look at some example code.
There's some network stuff that uses it for optimization. If CONFIG_NET_DMA is
enabled, that will turn on some kind of TCP/IP offloading. I don't really know
much about that. There's also a dmatest.c testing driver.
It would definitely be nice to see a third client driver.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 22:28 ` Timur Tabi
@ 2008-11-07 22:37 ` Bruce_Leonard
2008-11-09 3:26 ` Bill Gatliff
1 sibling, 0 replies; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-07 22:37 UTC (permalink / raw)
To: Timur Tabi; +Cc: timur.tabi, linuxppc-embedded
>
> There's some network stuff that uses it for optimization. If
> CONFIG_NET_DMA is
> enabled, that will turn on some kind of TCP/IP offloading. I don't
> really know
> much about that. There's also a dmatest.c testing driver.
>
> It would definitely be nice to see a third client driver.
>
I'll see what I can do :). Thanks for the help.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 22:12 ` Bruce_Leonard
2008-11-07 22:28 ` Timur Tabi
@ 2008-11-09 3:25 ` Bill Gatliff
1 sibling, 0 replies; 24+ messages in thread
From: Bill Gatliff @ 2008-11-09 3:25 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: timur.tabi, Timur Tabi, linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> timur.tabi@gmail.com wrote on 11/07/2008 01:46:42 PM:
>
>> Whether or not using async dma is worth the effort can only be
>> determined by profiling the code. Either it's better, or it's not.
>> There's no real way to tell in advance.
>>
>
> Pretty much the answer I expected :), I was just hoping that "wiser and
> more experienced" minds would say "oh, well to do what you want you should
> go in this direction". Ah well, such is the life of a kernel hacker.
>
> So it sounds like the async dma is the way to go, since I want to off load
> as much as possible from the core.
One thing to watch out for is an increase in interrupt latency. If
the DMA grabs the bus and won't turn loose until the whole transfer is
finished, your interrupts will wait along with everything else.
Many DMA controllers support a "cycle steal" mode, which lets them get
interrupted by more important things. It slows the DMA transfer down,
but does less damage to the rest of the system.
b.g.
--
Bill Gatliff
bgat@billgatliff.com
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 22:28 ` Timur Tabi
2008-11-07 22:37 ` Bruce_Leonard
@ 2008-11-09 3:26 ` Bill Gatliff
1 sibling, 0 replies; 24+ messages in thread
From: Bill Gatliff @ 2008-11-09 3:26 UTC (permalink / raw)
To: Timur Tabi; +Cc: timur.tabi, Bruce_Leonard, linuxppc-embedded
Timur Tabi wrote:
> Bruce_Leonard@selinc.com wrote:
>
>> So it sounds like the async dma is the way to go, since I want to off load
>> as much as possible from the core. As you say, though, it's new and not
>> in LDD3. Is .../drivers/dma/dmaengine.c what everyone is refering to as
>> async dma?
>
> Yes.
>
>> If not, what is? And what in the kernel is already using it
>> so I can look at some example code.
>
> There's some network stuff that uses it for optimization. If CONFIG_NET_DMA is
> enabled, that will turn on some kind of TCP/IP offloading. I don't really know
> much about that. There's also a dmatest.c testing driver.
I think some md (RAID) stuff uses it, too.
> It would definitely be nice to see a third client driver.
Why stop at three? :)
b.g.
--
Bill Gatliff
bgat@billgatliff.com
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-07 15:43 ` Timur Tabi
2008-11-07 21:31 ` Bruce_Leonard
@ 2008-11-10 0:09 ` Bruce_Leonard
2008-11-10 14:35 ` Timur Tabi
2008-11-10 22:06 ` Using DMA Bruce_Leonard
1 sibling, 2 replies; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-10 0:09 UTC (permalink / raw)
To: Timur Tabi; +Cc: timur.tabi, linuxppc-embedded
>
> The Elo device driver is an async DMA back-end driver. That is, you
> don't communicate with that driver directly, you communicate with the
> async library (which is new - so you won't find it in LDD3).
>
Okay, has anyone actually _used_ the Elo driver? I can't get the probe
function to run. I get into of_fsl_dma_init(), but of_fsl_dma_probe()
never executes. I have CONFIG_DMADEVICES and CONFIG_FSL_DMA set in my
.config, obviously since the init function runs. Here's the relevant SOC
portion of my device tree:
soc8349@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
ranges = <0 e0000000 00100000>;
reg = <e0000000 00000200>;
bus-frequency = <0>; // from bootloader
<<<<<<<<<<<<<<< snip >>>>>>>>>>>>>>>>>>>
dma@82a8 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
reg = <82a8 4>;
ranges = <0 8100 1a8>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <0 80>;
cell-index = <0>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@80 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <80 80>;
cell-index = <1>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@100 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <100 80>;
cell-index = <2>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@180 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <180 28>;
cell-index = <3>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
};
<<<<<<<<<<<<<< snip >>>>>>>>>>>>>>>>>>>>
};
Is there something else I need to do? Or is there something wrong with my
device tree (always a possibility :) ). Any help is appreciated.
Thanks.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-10 0:09 ` Bruce_Leonard
@ 2008-11-10 14:35 ` Timur Tabi
2008-11-10 17:58 ` Bruce_Leonard
2008-11-10 22:06 ` Using DMA Bruce_Leonard
1 sibling, 1 reply; 24+ messages in thread
From: Timur Tabi @ 2008-11-10 14:35 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: timur.tabi, linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> Is there something else I need to do? Or is there something wrong with my
> device tree (always a possibility :) ). Any help is appreciated.
You might need to add something like this:
static struct of_device_id __initdata mpc8610_ids[] = {
{ .compatible = "fsl,mpc8610-immr", },
{ .compatible = "simple-bus", },
{}
};
static int __init mpc8610_declare_of_platform_devices(void)
{
/* Without this call, the SSI device driver won't get probed. */
of_platform_bus_probe(NULL, mpc8610_ids, NULL);
return 0;
}
machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
--
Timur Tabi
Linux Kernel Developer @ Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-10 14:35 ` Timur Tabi
@ 2008-11-10 17:58 ` Bruce_Leonard
2008-11-11 9:09 ` Rajasekaran Kaliyaperumal, Chennai
0 siblings, 1 reply; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-10 17:58 UTC (permalink / raw)
To: Timur Tabi; +Cc: timur.tabi, linuxppc-embedded
Timur Tabi <timur@freescale.com> wrote on 11/10/2008 06:35:21 AM:
> Bruce_Leonard@selinc.com wrote:
>
> > Is there something else I need to do? Or is there something wrong
with my
> > device tree (always a possibility :) ). Any help is appreciated.
>
> You might need to add something like this:
>
> static struct of_device_id __initdata mpc8610_ids[] = {
> { .compatible = "fsl,mpc8610-immr", },
> { .compatible = "simple-bus", },
> {}
> };
> static int __init mpc8610_declare_of_platform_devices(void)
> {
> /* Without this call, the SSI device driver won't get probed.
*/
> of_platform_bus_probe(NULL, mpc8610_ids, NULL);
> return 0;
> }
> machine_device_initcall(mpc86xx_hpcd,
mpc8610_declare_of_platform_devices);
>
> --
> Timur Tabi
> Linux Kernel Developer @ Freescale
Something like that already exists in
/arch/powerpc/platforms/83xx/mpc834x_itx.c, which I'm using. Only real
difference is the first compatible flag is:
.compatible = "fsl,pq2pro-localbus"
Which I presume is correct since other drivers load and work correctly
based on what's in the device tree.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-10 0:09 ` Bruce_Leonard
2008-11-10 14:35 ` Timur Tabi
@ 2008-11-10 22:06 ` Bruce_Leonard
2008-11-11 14:51 ` Timur Tabi
1 sibling, 1 reply; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-10 22:06 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: Timur Tabi, linuxppc-embedded
linuxppc-embedded-bounces+brucle=selinc.com@ozlabs.org wrote on 11/09/2008
04:09:51 PM:
> >
> > The Elo device driver is an async DMA back-end driver. That is, you
> > don't communicate with that driver directly, you communicate with the
> > async library (which is new - so you won't find it in LDD3).
> >
>
> Okay, has anyone actually _used_ the Elo driver? I can't get the probe
> function to run. I get into of_fsl_dma_init(), but of_fsl_dma_probe()
> never executes. I have CONFIG_DMADEVICES and CONFIG_FSL_DMA set in my
It would help if I was sure _when_the probe function was supposed to be
called. I traced of_fsl_dma_init() all the way down into
bus_for_each_dev(), but the call to the passed in function
(__driver_attach() in this case) never gets called. This may not be a bad
thing in and of itself, the USB core registers two interface drivers
(usbfs and hub) and a device driver (usb) just prior this that also don't
call into the function passed into bus_for_each_dev().
The only thing I'm used to yet, being so new to this level of detail, is
installing device drivers where the probe function is called right way.
For example, in my NAND driver when the init funtion runs and calls
pci_register_driver() I land in my probe function. That doesn't happen
when of_fsl_dma_init() calls of_register_platform_driver(). There are
some obvious differences in the code. For one thing, my NAND driver is
described with a device driver structure (i.e., struct pci_device),
whereas the Elo DMA driver is descibed with a platform driver structure
(i.e., struct of_platform_driver). Also, my NAND driver init function is
wrapped in module_init() whereas the Elo driver init function is wrapped
in subsys_initcall(). I'm not sure what (if any) these differences mean,
but I'm stummped. I have no idea how to attach to the Elo DMA driver.
It seems to me that the probe function should be called as soon as the
kernel calls the init function, but it doesn't happen. Any guidence on
how to make this thing work is really appreciated. Thanks.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: Using DMA
2008-11-10 17:58 ` Bruce_Leonard
@ 2008-11-11 9:09 ` Rajasekaran Kaliyaperumal, Chennai
2008-11-11 10:22 ` Porting Linux to 8051 [ was:Re: Using DMA ] Martyn Welch
0 siblings, 1 reply; 24+ messages in thread
From: Rajasekaran Kaliyaperumal, Chennai @ 2008-11-11 9:09 UTC (permalink / raw)
To: Bruce_Leonard, Timur Tabi; +Cc: timur.tabi, linuxppc-embedded
HI,=20
I would like to port a linux kernel to a 8051 Microcontroller
C8051F120(128kB flash memory 8KB Ram )=2E=20
Is this really possible?=20
What book would help me in porting a linux kernel to a modest
microcontroller such as 8051?=20
Any help would be greatly appreciated
Thanks in Advance=20
K=2ERajasekaran=2E
-----Original Message-----
From: linuxppc-embedded-bounces+rajasekaran=2Ek=3Dhcl=2Ein@ozlabs=2Eorg
[mailto:linuxppc-embedded-bounces+rajasekaran=2Ek=3Dhcl=2Ein@ozlabs=2Eorg]=
On
Behalf Of Bruce_Leonard@selinc=2Ecom
Sent: Monday, November 10, 2008 11:29 PM
To: Timur Tabi
Cc: timur=2Etabi@gmail=2Ecom; linuxppc-embedded@ozlabs=2Eorg
Subject: Re: Using DMA
Timur Tabi <timur@freescale=2Ecom> wrote on 11/10/2008 06:35:21 AM:
> Bruce_Leonard@selinc=2Ecom wrote:
>=20
> > Is there something else I need to do? Or is there something wrong=20
with my=20
> > device tree (always a possibility :) )=2E Any help is appreciated=2E
>=20
> You might need to add something like this:
>=20
> static struct of_device_id __initdata mpc8610_ids[] =3D {
> { =2Ecompatible =3D "fsl,mpc8610-immr", },
> { =2Ecompatible =3D "simple-bus", },
> {}
> };
> static int __init mpc8610_declare_of_platform_devices(void)
> {
> /* Without this call, the SSI device driver won't get probed=2E
*/
> of_platform_bus_probe(NULL, mpc8610_ids, NULL);
> return 0;
> }
> machine_device_initcall(mpc86xx_hpcd,=20
mpc8610_declare_of_platform_devices);
>=20
> --=20
> Timur Tabi
> Linux Kernel Developer @ Freescale
Something like that already exists in=20
/arch/powerpc/platforms/83xx/mpc834x_itx=2Ec, which I'm using=2E Only real=
=20
difference is the first compatible flag is:
=2E=2Ecompatible =3D "fsl,pq2pro-localbus"
Which I presume is correct since other drivers load and work correctly=20
based on what's in the device tree=2E
Bruce
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs=2Eorg
https://ozlabs=2Eorg/mailman/listinfo/linuxppc-embedded
DISCLAIMER:
---------------------------------------------------------------------------=
--------------------------------------------
The contents of this e-mail and any attachment(s) are confidential and=
intended for the named recipient(s) only=2E
It shall not attach any liability on the originator or HCL or its=
affiliates=2E Any views or opinions presented in=20
this email are solely those of the author and may not necessarily reflect=
the opinions of HCL or its affiliates=2E
Any form of reproduction, dissemination, copying, disclosure, modification,=
distribution and / or publication of=20
this message without the prior written consent of the author of this e-mail=
is strictly prohibited=2E If you have
received this email in error please delete it and notify the sender=
immediately=2E Before opening any mail and=20
attachments please check them for viruses and defect=2E
---------------------------------------------------------------------------=
--------------------------------------------
^ permalink raw reply [flat|nested] 24+ messages in thread
* Porting Linux to 8051 [ was:Re: Using DMA ]
2008-11-11 9:09 ` Rajasekaran Kaliyaperumal, Chennai
@ 2008-11-11 10:22 ` Martyn Welch
0 siblings, 0 replies; 24+ messages in thread
From: Martyn Welch @ 2008-11-11 10:22 UTC (permalink / raw)
To: Rajasekaran Kaliyaperumal, Chennai; +Cc: linuxppc-embedded
On Tue, 11 Nov 2008 14:39:38 +0530
"Rajasekaran Kaliyaperumal, Chennai" <rajasekaran.k@hcl.in> wrote:
>
>
> HI,
>
Hi Rajasekaran,
Firstly - please don't hijack an existing thread when asking a new, completely unrelated question. Start a new thread with a relevant title.
> I would like to port a linux kernel to a 8051 Microcontroller
> C8051F120(128kB flash memory 8KB Ram ).
>
> Is this really possible?
>
See:
http://www.ucdot.org/article.pl?sid=03/11/25/0049241&mode=thread
I doubt much has changed.
Martyn
--
Martyn Welch MEng MPhil MIET (Principal Software Engineer) T:+44(0)1327322748
GE Fanuc Intelligent Platforms Ltd, |Registered in England and Wales
Tove Valley Business Park, Towcester, |(3828642) at 100 Barbirolli Square,
Northants, NN12 6PF, UK T:+44(0)1327359444 |Manchester,M2 3AB VAT:GB 729849476
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-10 22:06 ` Using DMA Bruce_Leonard
@ 2008-11-11 14:51 ` Timur Tabi
2008-11-11 18:19 ` Bruce_Leonard
0 siblings, 1 reply; 24+ messages in thread
From: Timur Tabi @ 2008-11-11 14:51 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> linuxppc-embedded-bounces+brucle=selinc.com@ozlabs.org wrote on 11/09/2008
> 04:09:51 PM:
>
>>> The Elo device driver is an async DMA back-end driver. That is, you
>>> don't communicate with that driver directly, you communicate with the
>>> async library (which is new - so you won't find it in LDD3).
>>>
>> Okay, has anyone actually _used_ the Elo driver? I can't get the probe
>> function to run. I get into of_fsl_dma_init(), but of_fsl_dma_probe()
>> never executes. I have CONFIG_DMADEVICES and CONFIG_FSL_DMA set in my
>
> It would help if I was sure _when_the probe function was supposed to be
> called.
Normally, your driver's OF probe function will be called when the driver calls
of_register_platform_driver().
> I traced of_fsl_dma_init() all the way down into
> bus_for_each_dev(), but the call to the passed in function
> (__driver_attach() in this case) never gets called.
I believe this because the kernel never scanned the DMA entries in the device
tree. This is why I said you need of_platform_bus_probe() with the compatible
field of the parent of the DMA controller node. Send me your device tree.
> Also, my NAND driver init function is
> wrapped in module_init() whereas the Elo driver init function is wrapped
> in subsys_initcall().
When compiled as a module, subsys_initcall() becomes module_init(). When
compiled in-kernel, subsys_initcall() guarantees the DMA driver is initialized
before other (normal) drivers are.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-11 14:51 ` Timur Tabi
@ 2008-11-11 18:19 ` Bruce_Leonard
2008-11-11 19:22 ` Timur Tabi
0 siblings, 1 reply; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-11 18:19 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-embedded
>
> I believe this because the kernel never scanned the DMA entries in the
device
> tree. This is why I said you need of_platform_bus_probe() with the
compatible
> field of the parent of the DMA controller node. Send me your device
tree.
>
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///
///
///////////////////////////////////////////////////////////////////////////////
/ {
model = "MPC8349EMITX";
compatible = "MPC8349EMITX", "MPC834xMITX", "MPC83xxMITX";
#address-cells = <1>;
#size-cells = <1>;
cpus {
#cpus = <1>;
#address-cells = <1>;
#size-cells = <0>;
PowerPC,8349@0 {
device_type = "cpu";
reg = <0>;
d-cache-line-size = <20>;
i-cache-line-size = <20>;
d-cache-size = <8000>;
i-cache-size = <8000>;
timebase-frequency = <0>; // from bootloader
bus-frequency = <0>; // from bootloader
clock-frequency = <0>; // from bootloader
32-bit;
};
};
memory {
device_type = "memory";
reg = <00000000 20000000>;
};
localbus@e0005000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,pq2pro-localbus";
reg = <e0005000 d8>;
ranges = <0 0 ff000000 01000000>;
flash@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "amd,s29g128n", "cfi-flash";
reg = <0 0 01000000>;
bank-width = <2>;
rcw@0 {
reg = <0 20000>;
read-only;
};
rtl@20000 {
reg = <20000 a0000>;
read-only;
};
kernel@c0000 {
reg = <c0000 180000>;
};
uboot@f00000 {
reg = <f00000 40000>;
};
uboot_env1@f40000 {
reg = <f40000 20000>;
};
uboot_env2@f60000 {
reg = <f60000 20000>;
};
device_tree@fe0000 {
reg = <fe0000 20000>;
};
};
};
soc8349@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
ranges = <0 e0000000 00100000>;
reg = <e0000000 00000200>;
bus-frequency = <0>; // from bootloader
wdt@200 {
device_type = "watchdog";
compatible = "mpc83xx_wdt";
reg = <200 100>;
};
i2c@3000 {
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3000 100>;
interrupts = <e 8>;
interrupt-parent = < &ipic >;
dfsrr;
rtc@68 {
#address-cells = <1>;
#size-cells = <0>;
device_type = "rtc";
compatible = "stm,m41t00";
reg = <68 8>;
};
};
i2c@3100 {
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3100 100>;
interrupts = <f 8>;
interrupt-parent = < &ipic >;
dfsrr;
};
spi@7000 {
device_type = "spi";
compatible = "mpc83xx_spi";
reg = <7000 1000>;
interrupts = <10 8>;
interrupt-parent = < &ipic >;
mode = <0>;
};
dma@82a8 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
reg = <82a8 4>;
ranges = <0 8100 1a8>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <0 80>;
cell-index = <0>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@80 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <80 80>;
cell-index = <1>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@100 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <100 80>;
cell-index = <2>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@180 {
compatible = "fsl,mpc8349-dma-channel",
"fsl,elo-dma-channel";
reg = <180 28>;
cell-index = <3>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
};
usb@22000 {
device_type = "usb";
compatible = "fsl-usb2-mph";
reg = <22000 1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = < &ipic >;
interrupts = <27 8>;
phy_type = "ulpi";
// port0; // These are backwards in their meaning
because MPC834X_SICRL_USB0
port1; // and USB1 are wrongly defined in
arch/powerpc/platforms/83xx/mpc83xx.h
};
usb@23000 {
device_type = "usb";
compatible = "fsl-usb2-dr";
dr_mode = "peripheral";
reg = <23000 1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = < &ipic >;
interrupts = <26 8>;
phy_type = "ulpi";
};
mdio@24520 {
device_type = "mdio";
compatible = "fsl,gianfar-mdio";
reg = <24520 20>;
#address-cells = <1>;
#size-cells = <0>;
/* Vitesse 8201 */
phy0: ethernet-phy@1c {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <0>;
device_type = "ethernet-phy";
};
/* Vitesse 7385 */
phy1: ethernet-phy@1f {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <1>;
device_type = "ethernet-phy";
};
};
ethernet@24000 {
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <24000 1000>;
address = [ 00 00 00 00 00 00 ];
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <20 8 21 8 22 8>;
interrupt-parent = < &ipic >;
phy-handle = < &phy0 >;
};
ethernet@25000 {
#address-cells = <1>;
#size-cells = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <25000 1000>;
address = [ 00 00 00 00 00 00 ];
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <23 8 24 8 25 8>;
interrupt-parent = < &ipic >;
phy-handle = < &phy1 >;
};
serial@4500 {
device_type = "serial";
compatible = "ns16550";
reg = <4500 100>;
clock-frequency = <0>; // from bootloader
interrupts = <9 8>;
interrupt-parent = < &ipic >;
};
serial@4600 {
device_type = "serial";
compatible = "ns16550";
reg = <4600 100>;
clock-frequency = <0>; // from bootloader
interrupts = <a 8>;
interrupt-parent = < &ipic >;
};
pci@8500 {
interrupt-map-mask = <f800 0 0 7>;
interrupt-map = <
// IDSEL 0x12 - FPGA
9000 0 0 1 &ipic 15 8 // INTA -
UARTS
9000 0 0 2 &ipic 16 8 // INTB -
IRIG
// IDSEL 0x13 - PCI Enet
9800 0 0 1 &ipic 14 8 // INTA
// IDSEL 0x14 - PCI104 Slot 1
a000 0 0 1 &ipic 12 8 // INTA
a000 0 0 2 &ipic 13 8 // INTB
a000 0 0 3 &ipic 15 8 // INTC
a000 0 0 4 &ipic 16 8 // INTD
// IDSEL 0x15 - PCI104 Slot 2
a800 0 0 1 &ipic 13 8 // INTA
a800 0 0 2 &ipic 15 8 // INTB
a800 0 0 3 &ipic 16 8 // INTC
a800 0 0 4 &ipic 12 8 // INTD
// IDSEL 0x16 - PCI104 Slot 3
b000 0 0 1 &ipic 15 8 // INTA
b000 0 0 2 &ipic 16 8 // INTB
b000 0 0 3 &ipic 12 8 // INTC
b000 0 0 4 &ipic 13 8 // INTD
>;
interrupt-parent = < &ipic >;
interrupts = <42 8>;
bus-range = <0 0>;
ranges = <42000000 0 80000000 80000000 0 10000000
02000000 0 90000000 90000000 0 08000000
01000000 0 98000000 98000000 0
08000000>;
clock-frequency = <1f78a40>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <8500 100>;
// compatible = "83xx";
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
crypto@30000 {
device_type = "crypto";
model = "SEC2";
compatible = "talitos";
reg = <30000 10000>;
interrupts = <b 8>;
interrupt-parent = < &ipic >;
num-channels = <4>;
channel-fifo-len = <18>;
exec-units-mask = <0000007e>;
descriptor-types-mask = <01010ebf>;
};
ipic: pic@700 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <700 100>;
built-in;
device_type = "ipic";
};
};
};
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-11 18:19 ` Bruce_Leonard
@ 2008-11-11 19:22 ` Timur Tabi
2008-11-11 21:46 ` Bruce_Leonard
0 siblings, 1 reply; 24+ messages in thread
From: Timur Tabi @ 2008-11-11 19:22 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
soc8349@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
+ compatible = "simple-bus";
And then add
{ .compatible = "simple-bus", },
to your struct of_device_id array.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-11 19:22 ` Timur Tabi
@ 2008-11-11 21:46 ` Bruce_Leonard
2008-11-11 21:54 ` Timur Tabi
0 siblings, 1 reply; 24+ messages in thread
From: Bruce_Leonard @ 2008-11-11 21:46 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-embedded
Timur Tabi <timur@freescale.com> wrote on 11/11/2008 11:22:06 AM:
> Bruce_Leonard@selinc.com wrote:
>
> soc8349@e0000000 {
> #address-cells = <1>;
> #size-cells = <1>;
> #interrupt-cells = <2>;
> device_type = "soc";
> + compatible = "simple-bus";
>
>
> And then add
>
> { .compatible = "simple-bus", },
>
> to your struct of_device_id array.
>
> --
> Timur Tabi
> Linux kernel developer at Freescale
Yea, that works! I hit the probe function. Thanks very much Timur. I
would never have found that.
Experimentally, I've found that I don't need the "simple-bus"
compatibility in the of_device_id array in the Elo DMA driver. Any idea
why?
Thanks again for all the help. If you've got some time, could you explain
why adding the "simple-bus" compatibility to the SOC node of the device
tree was needed. I _still_ (after fighting with them for over a year)
don't get device trees.
Bruce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Using DMA
2008-11-11 21:46 ` Bruce_Leonard
@ 2008-11-11 21:54 ` Timur Tabi
0 siblings, 0 replies; 24+ messages in thread
From: Timur Tabi @ 2008-11-11 21:54 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
Bruce_Leonard@selinc.com wrote:
> Yea, that works! I hit the probe function. Thanks very much Timur. I
> would never have found that.
I'm glad to help.
> Experimentally, I've found that I don't need the "simple-bus"
> compatibility in the of_device_id array in the Elo DMA driver. Any idea
> why?
Not off-hand.
> Thanks again for all the help. If you've got some time, could you explain
> why adding the "simple-bus" compatibility to the SOC node of the device
> tree was needed. I _still_ (after fighting with them for over a year)
> don't get device trees.
The 'compatible' field is usually the field used to find a node. Also, I
believe the OF code only probes nodes one level deep from a node it already
knows about. So if you don't have a compatible=simple-bus where it belongs,
then the kernel won't automatically probe all nodes under it.
However, certain standard nodes, like I2C and serial ports, are probed
independently of where they are located. This happens in fsl_soc.c. I could
have updated fsl_soc.c to automatically probe the DMA nodes as well, but
fsl_soc.c is reserved for devices that have architecture-independent drivers, so
something needs to extract the data from the device tree and put it into
arch-independent platform data structures for the drivers. Since the DMA driver
is powerpc-only, it doesn't qualify for this service. The driver has to extract
all the information it needs directly from the device tree.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2008-11-11 21:54 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-06 2:07 Using DMA Bruce_Leonard
2008-11-06 18:29 ` Scott Wood
2008-11-06 18:36 ` Bill Gatliff
2008-11-06 20:58 ` Bruce_Leonard
2008-11-06 21:42 ` Bill Gatliff
2008-11-07 15:43 ` Timur Tabi
2008-11-07 21:31 ` Bruce_Leonard
2008-11-07 21:46 ` Timur Tabi
2008-11-07 22:12 ` Bruce_Leonard
2008-11-07 22:28 ` Timur Tabi
2008-11-07 22:37 ` Bruce_Leonard
2008-11-09 3:26 ` Bill Gatliff
2008-11-09 3:25 ` Bill Gatliff
2008-11-10 0:09 ` Bruce_Leonard
2008-11-10 14:35 ` Timur Tabi
2008-11-10 17:58 ` Bruce_Leonard
2008-11-11 9:09 ` Rajasekaran Kaliyaperumal, Chennai
2008-11-11 10:22 ` Porting Linux to 8051 [ was:Re: Using DMA ] Martyn Welch
2008-11-10 22:06 ` Using DMA Bruce_Leonard
2008-11-11 14:51 ` Timur Tabi
2008-11-11 18:19 ` Bruce_Leonard
2008-11-11 19:22 ` Timur Tabi
2008-11-11 21:46 ` Bruce_Leonard
2008-11-11 21:54 ` Timur Tabi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).