linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* AW: [PATCH]: [MPC5200] Add ATA DMA support
@ 2008-11-25 14:45 ` Lehmann, Hans (Ritter Elektronik)
  2008-11-25 15:19   ` Matt Sealey
  2008-12-20  7:18   ` Grant Likely
  0 siblings, 2 replies; 24+ messages in thread
From: Lehmann, Hans (Ritter Elektronik) @ 2008-11-25 14:45 UTC (permalink / raw)
  To: Tim Yamin, Grant Likely; +Cc: linuxppc-dev

Tim, Grant,

just an info.

Very often the Bestcomm-FEC crashed without any error logs if I initiate =
a transaction over FEC and save the file to disk (I rememeber I have =
read something like that). A restart of FEC don't work.  =20
But no I figured out, if I connect to the other ethernet port of our =
board (natsemi) the FEC will awake to life again, if I initiate a new =
transaction over natsemi. This seems a little oddly to me.

Cheers =20

Mit freundlichen Gr=FC=DFen

Hans Lehmann
Softwareentwicklung

Telefon	+49 (0)2191-67-2520
Fax 	+49 (0)2191-67-703408
e-mail 	hans.lehmann@ritter-elektronik.de

=20

Ritter Elektronik GmbH
Leverkuser Stra=DFe 65
D-42897 Remscheid
www.ritter-elektronik.de <http://www.ritter-elektronik.de/start.html>=20

Gesch=E4ftsf=FChrer: Manfred A. Wagner, Dr. Uwe Baader
Sitz der Gesellschaft: Oberhausen
HRB 17168 Duisburg  /  USt-ID DE 814009849

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-11-25 14:45 ` AW: [PATCH]: [MPC5200] Add ATA DMA support Lehmann, Hans (Ritter Elektronik)
@ 2008-11-25 15:19   ` Matt Sealey
  2008-11-25 15:35     ` AW: " Lehmann, Hans (Ritter Elektronik)
  2008-12-20  7:15     ` Grant Likely
  2008-12-20  7:18   ` Grant Likely
  1 sibling, 2 replies; 24+ messages in thread
From: Matt Sealey @ 2008-11-25 15:19 UTC (permalink / raw)
  To: Lehmann, Hans (Ritter Elektronik); +Cc: Tim Yamin, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1012 bytes --]

On Tue, Nov 25, 2008 at 8:45 AM, Lehmann, Hans (Ritter Elektronik) <
hans.lehmann@ritter-elektronik.de> wrote:

> Tim, Grant,
>
> just an info.
>
> Very often the Bestcomm-FEC crashed without any error logs if I initiate a
> transaction over FEC and save the file to disk (I rememeber I have read
> something like that). A restart of FEC don't work.
> But no I figured out, if I connect to the other ethernet port of our board
> (natsemi) the FEC will awake to life again, if I initiate a new transaction
> over natsemi. This seems a little oddly to me.
>

Hi guys,

We tried to get the SUSE guys to push the patch into openSUSE 11.1 release
and the tests came back negative here too with regards to FEC support; for
some odd reason, it does this;

https://bugzilla.novell.com/show_bug.cgi?id=445856#c10

There is some weird interaction here, but I can't imagine what it might be.
Tim, did you ever see any ethernet problems like this?

-- 
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

[-- Attachment #2: Type: text/html, Size: 1458 bytes --]

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

* AW: [PATCH]: [MPC5200] Add ATA DMA support
  2008-11-25 15:19   ` Matt Sealey
@ 2008-11-25 15:35     ` Lehmann, Hans (Ritter Elektronik)
  2008-12-20  7:15     ` Grant Likely
  1 sibling, 0 replies; 24+ messages in thread
From: Lehmann, Hans (Ritter Elektronik) @ 2008-11-25 15:35 UTC (permalink / raw)
  To: Matt Sealey, Tim Yamin, Grant Likely; +Cc: linuxppc-dev

Tim, Grant=20
=20
here are some more information.=20
I think there is a also a problem with memory after FEC crasched.
=20
root@EL392:~ free
              total         used         free       shared      buffers
   Mem:       127100        26424       100676            0          432
  Swap:            0            0            0
Total:       127100        26424       100676
root@EL392:~
root@EL392:~
root@EL392:~ ifdown eth0
net eth0: queues didn't drain
net eth0:   tx: index: 10, outdex: 6
net eth0:   rx: index: 117, outdex: 118
root@EL392:~ ifup eth0
net eth0: attached phy 0 to driver Generic PHY
root@EL392:~ freePHY: f0003000:00 - Link is Up - 100/Full
root@EL392:~ free
              total         used         free       shared      buffers
  Mem:       127100        35028        92072            0          760
 Swap:            0            0            0
Total:       127100        35028        92072
=20
Cheers


Mit freundlichen Gr=FC=DFen

Hans Lehmann

Softwareentwicklung

Telefon +49 (0)2191-67-2520

Fax     +49 (0)2191-67-703408

e-mail  hans.lehmann@ritter-elektronik.de =
<mailto:hans.lehmann@ritter-elektronik.de>=20

Ritter Elektronik GmbH

Leverkuser Stra=DFe 65

D-42897 Remscheid

www.ritter-elektronik.de <http://www.ritter-elektronik.de/start.html>=20

Gesch=E4ftsf=FChrer: Manfred A. Wagner, Dr. Uwe Baader

Sitz der Gesellschaft: Oberhausen

HRB 17168 Duisburg  /  USt-ID DE 814009849

=20

________________________________

Von: Matt Sealey [mailto:matt@genesi-usa.com]=20
Gesendet: Dienstag, 25. November 2008 16:19
An: Lehmann, Hans (Ritter Elektronik)
Cc: Tim Yamin; Grant Likely; linuxppc-dev@ozlabs.org
Betreff: Re: [PATCH]: [MPC5200] Add ATA DMA support




On Tue, Nov 25, 2008 at 8:45 AM, Lehmann, Hans (Ritter Elektronik) =
<hans.lehmann@ritter-elektronik.de> wrote:


	Tim, Grant,
=09
	just an info.
=09
	Very often the Bestcomm-FEC crashed without any error logs if I =
initiate a transaction over FEC and save the file to disk (I rememeber I =
have read something like that). A restart of FEC don't work.
	But no I figured out, if I connect to the other ethernet port of our =
board (natsemi) the FEC will awake to life again, if I initiate a new =
transaction over natsemi. This seems a little oddly to me.
=09


Hi guys,

We tried to get the SUSE guys to push the patch into openSUSE 11.1 =
release and the tests came back negative here too with regards to FEC =
support; for some odd reason, it does this;

https://bugzilla.novell.com/show_bug.cgi?id=3D445856#c10=20


There is some weird interaction here, but I can't imagine what it might =
be. Tim, did you ever see any ethernet problems like this?

--=20
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-11-25 15:19   ` Matt Sealey
  2008-11-25 15:35     ` AW: " Lehmann, Hans (Ritter Elektronik)
@ 2008-12-20  7:15     ` Grant Likely
  1 sibling, 0 replies; 24+ messages in thread
From: Grant Likely @ 2008-12-20  7:15 UTC (permalink / raw)
  To: Matt Sealey, Olaf Hering
  Cc: Lehmann, Hans (Ritter Elektronik), Tim Yamin, linuxppc-dev

On Tue, Nov 25, 2008 at 8:19 AM, Matt Sealey <matt@genesi-usa.com> wrote:
>
>
> On Tue, Nov 25, 2008 at 8:45 AM, Lehmann, Hans (Ritter Elektronik)
> <hans.lehmann@ritter-elektronik.de> wrote:
>>
>> Tim, Grant,
>>
>> just an info.
>>
>> Very often the Bestcomm-FEC crashed without any error logs if I initiate a
>> transaction over FEC and save the file to disk (I rememeber I have read
>> something like that). A restart of FEC don't work.
>> But no I figured out, if I connect to the other ethernet port of our board
>> (natsemi) the FEC will awake to life again, if I initiate a new transaction
>> over natsemi. This seems a little oddly to me.
>
> Hi guys,
>
> We tried to get the SUSE guys to push the patch into openSUSE 11.1 release
> and the tests came back negative here too with regards to FEC support; for
> some odd reason, it does this;
>
> https://bugzilla.novell.com/show_bug.cgi?id=445856#c10
>
> There is some weird interaction here, but I can't imagine what it might be.
> Tim, did you ever see any ethernet problems like this?

It looks like something getting messed up during allocation of buffers
and not DMA operation related at all.  I don't see the problem here...

Digging deeper I think the problem is due to this:

>   ------- Comment #6 From Olaf Hering 2008-11-18 01:32:52 MST  -------
>
> Also, the patches do not seem to apply and compile with our kernel-source.
> bcom_task->bd changed to void*, this breaks sound/ppc/mpc52xx_ac97.c. It looks
> like an unneeded cosmetic change.
> The Kconfig changes are appearently also not required for an existing .config.
>
> I removed the bcom_task->bd  change.

The patch does depend on bcom_task->bd being (void *).  Without it the
calculation of BD offsets is entirely wrong in bcom_get_bd().

That being said, the next version of the patch will leave the pointer
as (bcom_bd *) and handle the offset calculation in a different way.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-11-25 14:45 ` AW: [PATCH]: [MPC5200] Add ATA DMA support Lehmann, Hans (Ritter Elektronik)
  2008-11-25 15:19   ` Matt Sealey
@ 2008-12-20  7:18   ` Grant Likely
  2009-01-05  9:25     ` AW: " Lehmann, Hans (Ritter Elektronik)
  1 sibling, 1 reply; 24+ messages in thread
From: Grant Likely @ 2008-12-20  7:18 UTC (permalink / raw)
  To: Lehmann, Hans (Ritter Elektronik); +Cc: Tim Yamin, linuxppc-dev

On Tue, Nov 25, 2008 at 7:45 AM, Lehmann, Hans (Ritter Elektronik)
<hans.lehmann@ritter-elektronik.de> wrote:
> Tim, Grant,
>
> just an info.
>
> Very often the Bestcomm-FEC crashed without any error logs if I initiate a transaction over FEC and save the file to disk (I rememeber I have read something like that). A restart of FEC don't work.
> But no I figured out, if I connect to the other ethernet port of our board (natsemi) the FEC will awake to life again, if I initiate a new transaction over natsemi. This seems a little oddly to me.

Hans, what ATA modes do you see this problem in?  UDMA?  MWDMA?  Or
does just having the patch applied but still using PIO mode expose the
problem?

Thanks,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* AW: [PATCH]: [MPC5200] Add ATA DMA support
  2008-12-20  7:18   ` Grant Likely
@ 2009-01-05  9:25     ` Lehmann, Hans (Ritter Elektronik)
  2009-01-05 15:31       ` Grant Likely
  0 siblings, 1 reply; 24+ messages in thread
From: Lehmann, Hans (Ritter Elektronik) @ 2009-01-05  9:25 UTC (permalink / raw)
  To: Grant Likely; +Cc: Tim Yamin, linuxppc-dev

> Hans, what ATA modes do you see this problem in?  UDMA?  MWDMA?  Or =
does just having the patch applied but still using PIO mode expose the =
problem?


This problem occurs in MWDMA 2 mode.

Happy new year




Mit freundlichen Gr=FC=DFen

Hans Lehmann
Softwareentwicklung

Telefon	+49 (0)2191-67-2520
Fax 	+49 (0)2191-67-703408
e-mail 	hans.lehmann@ritter-elektronik.de



Ritter Elektronik GmbH
Leverkuser Stra=DFe 65
D-42897 Remscheid
www.ritter-elektronik.de

Gesch=E4ftsf=FChrer: Manfred A. Wagner, Dr. Uwe Baader
Sitz der Gesellschaft: Oberhausen
HRB 17168 Duisburg  /  USt-ID DE 814009849

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2009-01-05  9:25     ` AW: " Lehmann, Hans (Ritter Elektronik)
@ 2009-01-05 15:31       ` Grant Likely
  2009-07-09 14:24         ` Roman Fietze
  0 siblings, 1 reply; 24+ messages in thread
From: Grant Likely @ 2009-01-05 15:31 UTC (permalink / raw)
  To: Lehmann, Hans (Ritter Elektronik); +Cc: Tim Yamin, linuxppc-dev

On Mon, Jan 5, 2009 at 2:25 AM, Lehmann, Hans (Ritter Elektronik)
<hans.lehmann@ritter-elektronik.de> wrote:
>> Hans, what ATA modes do you see this problem in?  UDMA?  MWDMA?  Or does just having the patch applied but still using PIO mode expose the problem?
>
>
> This problem occurs in MWDMA 2 mode.

Thanks Hans.  DMA support is now in mainline, but it is disabled by
default.  It shouldn't break anything if MWDMA or UDMA does not get
enabled.  Let me know if it causes you any problems.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2009-01-05 15:31       ` Grant Likely
@ 2009-07-09 14:24         ` Roman Fietze
  0 siblings, 0 replies; 24+ messages in thread
From: Roman Fietze @ 2009-07-09 14:24 UTC (permalink / raw)
  To: linuxppc-dev

Hallo,

On Monday 05 January 2009 16:31:33 Grant Likely wrote:

> DMA support is now in mainline, but it is disabled by
> default ...

I had problems using ATA DMA on an own MPC5200B board, too. This board
has no problems at all using DMA33 with DENX 2.4.25, with all kinds of
automotive disks from 20 to 40GB. I definitively tested all three
listed drives below, but we are using other drives as well
(e.g. Hitachi 20 and 40 GB variants).

On exactly those boards I'm now running the 2.6.30 from DENX. The
following harddisks work well on this board, including network traffic
in parallel (which sometimes was a problem on old kernels or MPC5200's
w/o a 'B'):

=2D Toshiba MK4036GA
=2D Hitachi HEJ423020F9AT00


But an old 20GB Seagate ST940813AM shows the following problem when
booting the system:

PHY: f0003000:00 - Link is Up - 100/Half
ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6
ata1.00: BMDMA stat 0x5
ata1.00: cmd ca/00:08:1f:10:9c/00:00:00:00:00/e0 tag 0 dma 4096 out
         res 51/84:08:1f:10:9c/00:00:00:00:00/e0 Emask 0x10 (ATA bus error)
ata1.00: status: { DRDY ERR }
ata1.00: error: { ICRC ABRT }
ata1: soft resetting link
ata1.00: configured for UDMA/33
ata1: EH complete


I think this is similar to the errors reported after the ATA DMA patch
for the MPC5200B was introduced in this mailing list.

I even tried to use some modified timings from the 2.4.25 kernel, but
(of course) w/o success.

Are there any other patches I should try? Anything I could do to help
you to get this problem fixed?


Roman

=2D-=20
Roman Fietze  Telemotive AG  B=FCro M=FChlhausen

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-11-11 14:04                                 ` Lehmann, Hans (Ritter Elektronik)
@ 2008-11-11 14:35                                   ` Matt Sealey
  0 siblings, 0 replies; 24+ messages in thread
From: Matt Sealey @ 2008-11-11 14:35 UTC (permalink / raw)
  To: Lehmann, Hans (Ritter Elektronik); +Cc: Tim Yamin, linuxppc-dev

Oddly I built 2.6.27.2 with the patch and the Efika "waited" for a disk to appear
and didn't get anywhere. If I set libata.dma=0 then it complained about missing
symbols (but not with it enabled!).

This was a clean SUSE kernel from Factory, with only the ATA patch applied with
a few hand-merges (pata_mpc52xx.c has had a line of whitespace removed at some
point, but otherwise identical).

Lehmann, Hans (Ritter Elektronik) wrote:
> Tim, Grant,
> 
> I have tested the patch on our MPC5200B based board with Kingston Elite Pro CF-card and it worked fine with DMA2. I have port the patch back to 2.6.24.7 Kernel and I can't detect problems our errors, even with big files (40 mB) over FEC wich I save to card . We get performance up to 10,5mB/s which is near to the max. speed.
> 
> Greetings
> 
> 
> 
> 
> Mit freundlichen Grüßen
> 
> Hans Lehmann
> Softwareentwicklung
> 
> Telefon	+49 (0)2191-67-2520
> Fax 	+49 (0)2191-67-703408
> e-mail 	hans.lehmann@ritter-elektronik.de
> 
> 
> 
> Ritter Elektronik GmbH
> Leverkuser Straße 65
> D-42897 Remscheid
> www.ritter-elektronik.de
> 
> Geschäftsführer: Manfred A. Wagner, Dr. Uwe Baader
> Sitz der Gesellschaft: Oberhausen
> HRB 17168 Duisburg  /  USt-ID DE 814009849
> 
> 
> -----Ursprüngliche Nachricht-----
> Von: linuxppc-dev-bounces+hans.lehmann=ritter-elektronik.de@ozlabs.org [mailto:linuxppc-dev-bounces+hans.lehmann=ritter-elektronik.de@ozlabs.org] Im Auftrag von Tim Yamin
> Gesendet: Mittwoch, 13. August 2008 11:07
> An: Grant Likely
> Cc: linuxppc-dev@ozlabs.org
> Betreff: [WW Spam: medium] Re: [PATCH]: [MPC5200] Add ATA DMA support
> 
> On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> Sounds good to me.  You will get more testers that way.  I can pick it 
>> up for -next if everything else looks good.
> 
> Here are the new patches; tested against 2.6.27-rc3.
> 
> Thanks,
> 
> Tim
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

-- 
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-13  9:07                               ` Tim Yamin
  2008-09-15  5:54                                 ` Grant Likely
@ 2008-11-11 14:04                                 ` Lehmann, Hans (Ritter Elektronik)
  2008-11-11 14:35                                   ` Matt Sealey
  1 sibling, 1 reply; 24+ messages in thread
From: Lehmann, Hans (Ritter Elektronik) @ 2008-11-11 14:04 UTC (permalink / raw)
  To: Tim Yamin, Grant Likely; +Cc: linuxppc-dev

Tim, Grant,

I have tested the patch on our MPC5200B based board with Kingston Elite =
Pro CF-card and it worked fine with DMA2. I have port the patch back to =
2.6.24.7 Kernel and I can't detect problems our errors, even with big =
files (40 mB) over FEC wich I save to card . We get performance up to =
10,5mB/s which is near to the max. speed.

Greetings




Mit freundlichen Gr=FC=DFen

Hans Lehmann
Softwareentwicklung

Telefon	+49 (0)2191-67-2520
Fax 	+49 (0)2191-67-703408
e-mail 	hans.lehmann@ritter-elektronik.de



Ritter Elektronik GmbH
Leverkuser Stra=DFe 65
D-42897 Remscheid
www.ritter-elektronik.de

Gesch=E4ftsf=FChrer: Manfred A. Wagner, Dr. Uwe Baader
Sitz der Gesellschaft: Oberhausen
HRB 17168 Duisburg  /  USt-ID DE 814009849


-----Urspr=FCngliche Nachricht-----
Von: linuxppc-dev-bounces+hans.lehmann=3Dritter-elektronik.de@ozlabs.org =
[mailto:linuxppc-dev-bounces+hans.lehmann=3Dritter-elektronik.de@ozlabs.o=
rg] Im Auftrag von Tim Yamin
Gesendet: Mittwoch, 13. August 2008 11:07
An: Grant Likely
Cc: linuxppc-dev@ozlabs.org
Betreff: [WW Spam: medium] Re: [PATCH]: [MPC5200] Add ATA DMA support

On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely =
<grant.likely@secretlab.ca> wrote:
> Sounds good to me.  You will get more testers that way.  I can pick it =

> up for -next if everything else looks good.

Here are the new patches; tested against 2.6.27-rc3.

Thanks,

Tim

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-09-15  5:54                                 ` Grant Likely
@ 2008-10-29 15:34                                   ` Matt Sealey
  0 siblings, 0 replies; 24+ messages in thread
From: Matt Sealey @ 2008-10-29 15:34 UTC (permalink / raw)
  To: Grant Likely; +Cc: Tim Yamin, linuxppc-dev, Bienert, Shawn



Grant Likely wrote:
> On Wed, Aug 13, 2008 at 3:07 AM, Tim Yamin <plasm@roo.me.uk> wrote:
>> On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>>> Sounds good to me.  You will get more testers that way.  I can pick it
>>> up for -next if everything else looks good.
>> Here are the new patches; tested against 2.6.27-rc3.
> 
> Hi Tim,
> 
> I finally got a chance to try out your patches on my lite5200 board.
> Unfortunately, I wasn't able to get it to work easily.  I'm very early
> in the debugging this issue, but I thought I'd send you my results in
> case you've seen it before.  I've tried this with both an STEC 1GB CF
> and a Transcend Ultra industrial 1GB CF card.

[snip]

Grant, Tim,

Any chance of this being picked up even though it "doesn't work"?

I'm going to be rolling a couple kernels this weekend (2.6.27.4
for Efika, ADS512101, 8610HPCN and 8641DHPCD) and I'll patch this
in and see what happens and give some more test data (since my
Efika is nice and trashed it won't matter if I trash it some
more).

We at Genesi still hold by the fact that ATA DMA is irrevocably
broken but hold some bittersweet hope that Freescale might fix
it after the fact in some useless future revision, the biggest
problem is that if nobody writes a driver for it, nobody experiences
the problem!

Once the patch is in maybe someone will be willing to use the
BestComm-assisted PIO idea as implemented in the bplan 2.6.19
kernel and compare results?

-- 
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-13  9:07                               ` Tim Yamin
@ 2008-09-15  5:54                                 ` Grant Likely
  2008-10-29 15:34                                   ` Matt Sealey
  2008-11-11 14:04                                 ` Lehmann, Hans (Ritter Elektronik)
  1 sibling, 1 reply; 24+ messages in thread
From: Grant Likely @ 2008-09-15  5:54 UTC (permalink / raw)
  To: Tim Yamin; +Cc: linuxppc-dev, Bienert, Shawn

On Wed, Aug 13, 2008 at 3:07 AM, Tim Yamin <plasm@roo.me.uk> wrote:
> On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> Sounds good to me.  You will get more testers that way.  I can pick it
>> up for -next if everything else looks good.
>
> Here are the new patches; tested against 2.6.27-rc3.

Hi Tim,

I finally got a chance to try out your patches on my lite5200 board.
Unfortunately, I wasn't able to get it to work easily.  I'm very early
in the debugging this issue, but I thought I'd send you my results in
case you've seen it before.  I've tried this with both an STEC 1GB CF
and a Transcend Ultra industrial 1GB CF card.

When the patch is enabled, Linux boots to the point of probing the ATA
bus.  The first attempt to probe uses UDMA/33 which ends in a timeout.
 Second attempt limits it to UDMA/25 which also times out.  Third
attempt falls back to PIO4 mode which then succeeds and the boot
process continues.  I haven't dug into the details of MPC5200 UDMA
support yet, but I'd like to know if you have any ideas.

Cheers,
g.

Full boot log below:

U-Boot 1.3.4-rc2 (Aug  1 2008 - 14:11:20)

CPU:   MPC5200B v2.2, Core v1.4 at 462 MHz
       Bus 132 MHz, IPB 132 MHz, PCI 33 MHz
Board: Freescale Lite5200B
I2C:   85 kHz, ready
DRAM:  256 MB
FLASH: 32 MB
PCI:   Bus Dev VenId DevId Class Int
        00  1a  1057  5809  0680  00
In:    serial
Out:   serial
Err:   serial
Net:   FEC ETHERNET
IDE:   Bus 0: OK
  Device 0: Model: TRANSCEND Firm: 20070418 Ser#: 0           521143E8
            Type: Hard Disk
            Capacity: 971.5 MB = 0.9 GB (1989792 x 512)
  Device 1: Model:  Firm:  Ser#:
            Type: # 1F #
            Capacity: not available
Hit any key to stop autoboot:  0
=> boot
Using FEC ETHERNET device
TFTP from server 192.168.0.200; our IP address is 192.168.0.70
Filename 'mpc5200/uImage.gcl'.
Load address: 0x400000
Loading: #################################################################
         #############################
done
Bytes transferred = 1376680 (1501a8 hex)
Using FEC ETHERNET device
TFTP from server 192.168.0.200; our IP address is 192.168.0.70
Filename 'mpc5200/lite5200b.dtb'.
Load address: 0x3f0000
Loading: #
done
Bytes transferred = 8192 (2000 hex)
## Booting kernel from Legacy Image at 00400000 ...
   Image Name:   Linux-2.6.27-rc6-00038-gc03fbd9
   Created:      2008-09-14   3:16:24 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1376616 Bytes =  1.3 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
## Flattened Device Tree blob at 003f0000
   Booting using the fdt blob at 0x3f0000
[    0.000000] Using lite5200 machine description
[    0.000000] Linux version 2.6.27-rc6-00038-gc03fbd9
(grant@trillian) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #465 Sat
Sep 13 21:15:54 MDT 2008
[    0.000000] PCI host bridge /pci@f0000d00 (primary) ranges:
[    0.000000]  MEM 0x0000000080000000..0x000000009fffffff ->
0x0000000080000000 Prefetch
[    0.000000]  MEM 0x00000000a0000000..0x00000000afffffff ->
0x00000000a0000000
[    0.000000]   IO 0x00000000b0000000..0x00000000b0ffffff -> 0x0000000000000000
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA      0x00000000 -> 0x00010000
[    0.000000]   Normal   0x00010000 -> 0x00010000
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[1] active PFN ranges
[    0.000000]     0: 0x00000000 -> 0x00010000
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.
Total pages: 65024
[    0.000000] Kernel command line: root=/dev/nfs rw
nfsroot=192.168.0.200:/home/srv/nfs/gdc/lite5200-1
ip=192.168.0.70:192.168.0.200:192.168.0.1:255.255.255.0:lite5200-1:eth0:off
console=ttyPSC0,115200
[    0.000000] MPC52xx PIC is up and running!
[    0.000000] PID hash table entries: 1024 (order: 10, 4096 bytes)
[    0.000000] clocksource: timebase mult[79364d9] shift[22] registered
[    0.000194] console [ttyPSC0] enabled
[    0.120005] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.128964] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.166748] Memory: 256572k/262144k available (2740k kernel code,
5272k reserved, 108k data, 108k bss, 168k init)
[    0.177420] SLUB: Genslabs=12, HWalign=32, Order=0-3, MinObjects=0,
CPUs=1, Nodes=1
[    0.185307] Calibrating delay loop... 65.79 BogoMIPS (lpj=131584)
[    0.280159] Mount-cache hash table entries: 512
[    0.288690] net_namespace: 288 bytes
[    0.293054] NET: Registered protocol family 16
[    0.314694] PCI: Probing PCI hardware
[    0.319804] bus: 00 index 0 io port: [ffffff, 100c03f2000]
[    0.325470] bus: 00 index 1 mmio: [800000009fffffff, a0b]
[    0.331081] bus: 00 index 2 mmio: [a0000000afffffff, a4b]
[    0.336808] DMA: MPC52xx BestComm driver
[    0.341125] DMA: MPC52xx BestComm engine @f0001200 ok !
[    0.355586] SCSI subsystem initialized
[    0.376841] NET: Registered protocol family 2
[    0.415732] IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.423336] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[    0.431208] TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
[    0.438151] TCP: Hash tables configured (established 8192 bind 8192)
[    0.444701] TCP reno registered
[    0.459823] NET: Registered protocol family 1
[    0.504368] msgmni has been set to 501
[    0.508420] io scheduler noop registered
[    0.512499] io scheduler anticipatory registered (default)
[    0.518146] io scheduler deadline registered
[    0.522741] io scheduler cfq registered
[    0.984815] Generic RTC Driver v1.07
[    0.989504] Serial: MPC52xx PSC UART driver
[    0.994153] f0002000.serial: ttyPSC0 at MMIO 0xf0002000 (irq = 129)
is a MPC52xx PSC
[    1.021517] brd: module loaded
[    1.033964] loop: module loaded
[    1.057979] mpc52xx MII bus: probed
[    1.063689] net eth0: Using PHY at MDIO address 0
[    1.069486] Driver 'sd' needs updating - please use bus_type methods
[    1.076496] ata: MPC52xx IDE/ATA libata driver
[    1.081946] scsi0 : mpc52xx_ata
[    1.086095] ata1: PATA max UDMA/33 ata_regs 0xf0003a00 irq 135
[    1.255960] ata1.00: ATA-4: TRANSCEND, 20070418, max UDMA/66
[    1.261807] ata1.00: 1989792 sectors, multi 0: LBA
[    1.279847] ata1.00: configured for UDMA/33
[    1.284902] scsi 0:0:0:0: Direct-Access     ATA      TRANSCEND
  2007 PQ: 0 ANSI: 5
[    1.294794] sd 0:0:0:0: [sda] 1989792 512-byte hardware sectors (1019 MB)
[    1.302014] sd 0:0:0:0: [sda] Write Protect is off
[    1.307411] sd 0:0:0:0: [sda] Write cache: disabled, read cache:
enabled, doesn't support DPO or FUA
[    1.317467] sd 0:0:0:0: [sda] 1989792 512-byte hardware sectors (1019 MB)
[    1.324683] sd 0:0:0:0: [sda] Write Protect is off
[    1.330081] sd 0:0:0:0: [sda] Write cache: disabled, read cache:
enabled, doesn't support DPO or FUA
[    1.339489]  sda:<3>ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0
action 0x6 frozen
[   31.345893] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
dma 4096 in
[   31.345905]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[   31.360881] ata1.00: status: { DRDY }
[   31.364705] ata1: soft resetting link
[   31.547846] ata1.00: configured for UDMA/33
[   31.552225] ata1: EH complete
[   61.551658] ata1.00: limiting speed to UDMA/25:PIO4
[   61.556708] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[   61.563983] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
dma 4096 in
[   61.563993]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[   61.578959] ata1.00: status: { DRDY }
[   61.582776] ata1: soft resetting link
[   61.763845] ata1.00: configured for UDMA/25
[   61.768223] ata1: EH complete
[   91.767668] ata1.00: limiting speed to PIO4
[   91.772012] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[   91.779287] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
dma 4096 in
[   91.779297]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[   91.794272] ata1.00: status: { DRDY }
[   91.798094] ata1: soft resetting link
[   91.979846] ata1.00: configured for PIO4
[   91.983958] ata1: EH complete
[   91.988286]  sda1 sda2
[   91.992885] sd 0:0:0:0: [sda] Attached SCSI disk
[   91.998678] i2c /dev entries driver
[   92.008333] TCP cubic registered
[   92.011711] NET: Registered protocol family 17
[   92.017539] RPC: Registered udp transport module.
[   92.022418] RPC: Registered tcp transport module.
[   92.536899] net eth0: attached phy 0 to driver LXT971
[   93.543913] IP-Config: Complete:
[   93.547047]      device=eth0, addr=192.168.0.70,
mask=255.255.255.0, gw=192.168.0.1,
[   93.554973]      host=lite5200-1, domain=, nis-domain=(none),
[   93.560881]      bootserver=192.168.0.200,
rootserver=192.168.0.200, rootpath=
[   93.568846] Looking up port of RPC 100003/2 on 192.168.0.200
[   95.535725] PHY: f0003000:00 - Link is Up - 100/Full
[  103.576944] Looking up port of RPC 100005/1 on 192.168.0.200
[  108.628289] VFS: Mounted root (nfs filesystem).
[  108.633152] Freeing unused kernel memory: 168k init
Mount failed for selinuxfs on /selinux:  No such file or directory
modprobe: FATAL: Could not load
/lib/modules/2.6.27-rc6-00038-gc03fbd9/modules.dep: No such file or
directory

modprobe: FATAL: Could not load
/lib/modules/2.6.27-rc6-00038-gc03fbd9/modules.dep: No such file or
directory

INIT: version 2.86 booting
Setting the system clock.
Timed out waiting for time change.
Unable to set System Clock to: Thu Jan 1 00:01:51 UTC 1970 (warning).
Activating swap...done.
Setting the system clock.
Timed out waiting for time change.
Unable to set System Clock to: Thu Jan 1 00:01:53 UTC 1970 (warning).
Cleaning up ifupdown....
Loading kernel modules...FATAL: Could not load
/lib/modules/2.6.27-rc6-00038-gc03fbd9/modules.dep: No such file or
directory
Checking file systems...fsck 1.41.1 (01-Sep-2008)
dosfsck 2.11, 12 Mar 2005, FAT32, LFN
/dev/sda1: 12 files, 5665/15569 clusters
done.
Setting kernel variables (/etc/sysctl.conf)...done.
Mounting local filesystems...done.
Activating swapfile swap...done.
Setting up networking....
Configuring network interfaces...done.
Starting portmap daemon....
Starting NFS common utilities: statd.
INIT: Entering runlevel: 2
Starting system log daemon....
Starting kernel log daemon....
Starting OpenBSD Secure Shell server: sshd.
Starting NFS common utilities: statd.
Starting NTP server: ntpd.
Starting periodic command scheduler: crond.
[  122.655831] warning: `ntpd' uses 32-bit capabilities (legacy support in use)

Debian GNU/Linux lenny/sid lite5200-1 ttyPSC0

lite5200-1 login: Connection closed by foreign host.
grant@gdc-sandbox:~$


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
@ 2008-09-05 18:29 WITTROCK
  0 siblings, 0 replies; 24+ messages in thread
From: WITTROCK @ 2008-09-05 18:29 UTC (permalink / raw)
  To: linuxppc-dev



Tim Yamin-2 wrote:
> 
> On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely <grant.likely@secretlab.ca>
> wrote:
>> Sounds good to me.  You will get more testers that way.  I can pick it
>> up for -next if everything else looks good.
> 
> Here are the new patches; tested against 2.6.27-rc3.
> 
> Thanks,
> 
> Tim
> 



I have been trying this patch against 2.6.26.3 on our own MPC5200B based
board.  I am using a seagate  ST980815A.  The drive mounts O.K, and I can
transfer small files, but during large transfers there is the following
problem.

.....

## Booting kernel from Legacy Image at 00500000 ...
   Image Name:   Linux-2.6.26.3
   Created:      2008-09-05  17:01:31 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1409558 Bytes =  1.3 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
## Flattened Device Tree blob at 00400000
   Booting using the fdt blob at 0x400000
[    0.000000] Using m9000 machine description
[    0.000000] Linux version 2.6.26.3 (developer@usi-dev-linux) (gcc version
4.1.2) #2 Fri Sep 5 13:01:26 EDT 2008
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA             0 ->    32767
[    0.000000]   Normal      32767 ->    32767

........

[    0.796907] Driver 'sd' needs updating - please use bus_type methods
[    0.803944] ata: MPC52xx IDE/ATA libata driver
[    0.809300] scsi0 : mpc52xx_ata
[    0.813246] ata1: PATA max UDMA/33 ata_regs 0xf0003a00 irq 135
[    0.980196] ata1.00: ATA-6: ST980815A, 3.ALC, max UDMA/100
[    0.985864] ata1.00: 156301488 sectors, multi 0: LBA48 
[    1.004074] ata1.00: configured for UDMA/33
[    1.009047] scsi 0:0:0:0: Direct-Access     ATA      ST980815A       
3.AL PQ: 0 ANSI: 5
[    1.018652] sd 0:0:0:0: [sda] 156301488 512-byte hardware sectors (80026
MB)
[    1.026104] sd 0:0:0:0: [sda] Write Protect is off
[    1.031419] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled,
doesn't support DPO or FUA
[    1.041235] sd 0:0:0:0: [sda] 156301488 512-byte hardware sectors (80026
MB)
[    1.048681] sd 0:0:0:0: [sda] Write Protect is off
[    1.053994] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled,
doesn't support DPO or FUA
[    1.063308]  sda: unknown partition table
[    1.077092] sd 0:0:0:0: [sda] Attached SCSI disk

.......

-sh-2.05b# 
-sh-2.05b# cp test.txt > /mnt/hd/writetest
-sh-2.05b# cp test2.txt > /mnt/hd/writetest
-sh-2.05b# cp -R  /test /mnt/hd/writetest
[  170.239726] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6
frozen
[  170.247020] ata1.00: cmd ca/00:18:30:00:00/00:00:00:00:00/e0 tag 0 dma
12288 out
[  170.247033]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4
(timeout)
[  170.262180] ata1.00: status: { DRDY }
[  170.265995] ata1: soft resetting link
[  170.423867] ata1.00: revalidation failed (errno=-2)
[  170.428902] ata1: failed to recover some devices, retrying in 5 secs
[  175.435694] ata1: soft resetting link
[  175.591873] ata1.00: revalidation failed (errno=-2)
[  175.596909] ata1: failed to recover some devices, retrying in 5 secs
[  180.603697] ata1: soft resetting link
[  180.759873] ata1.00: revalidation failed (errno=-2)
[  180.764907] ata1.00: disabled
[  181.271725] ata1: soft resetting link
[  181.427741] ata1: EH complete
[  181.430856] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.437358] end_request: I/O error, dev sda, sector 48
[  181.442652] Buffer I/O error on device sda, logical block 6
[  181.448386] lost page write due to I/O error on sda
[  181.453429] Buffer I/O error on device sda, logical block 7
[  181.459165] lost page write due to I/O error on sda
[  181.464205] Buffer I/O error on device sda, logical block 8
[  181.469939] lost page write due to I/O error on sda
[  181.475076] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.481580] end_request: I/O error, dev sda, sector 8
[  181.486782] Buffer I/O error on device sda, logical block 1
[  181.492515] lost page write due to I/O error on sda
[  181.497653] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.504158] end_request: I/O error, dev sda, sector 0
[  181.509361] Buffer I/O error on device sda, logical block 0
[  181.515091] lost page write due to I/O error on sda
[  181.520252] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.526762] end_request: I/O error, dev sda, sector 180232
[  181.532441] Buffer I/O error on device sda, logical block 22540
[  181.538534] lost page write due to I/O error on sda
[  181.543784] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.550259] end_request: I/O error, dev sda, sector 180328
[  181.556223] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.562707] end_request: I/O error, dev sda, sector 181352
[  181.568659] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.575144] end_request: I/O error, dev sda, sector 182376
[  181.581094] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.587579] end_request: I/O error, dev sda, sector 183400
[  181.593483] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  181.599997] end_request: I/O error, dev sda, sector 184424
[  185.268091] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  185.274573] end_request: I/O error, dev sda, sector 180224
[  185.280329] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  185.286803] end_request: I/O error, dev sda, sector 64
[  185.292100] Buffer I/O error on device sda, logical block 8
[  185.297830] lost page write due to I/O error on sda
[  185.302957] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  185.309462] end_request: I/O error, dev sda, sector 48
[  185.314756] Buffer I/O error on device sda, logical block 6
[  185.320493] lost page write due to I/O error on sda
[  185.325593] sd 0:0:0:0: [sda] Result: hostbyte=0x04 driverbyte=0x00
[  185.332095] end_request: I/O error, dev sda, sector 0
[  185.337299] Buffer I/O error on device sda, logical block 0
[  185.343028] lost page write due to I/O error on sda
[  185.348067] Buffer I/O error on device sda, logical block 1
[  185.353805] lost page write due to I/O error on sda

With PATA_MPC52xx_DMA not set, it works fine.  To help eliminate our
hardware, I also tried this on a lite5200b development board, and had the
same results.  I also tried this with a compact flash card, and then the
problem occurs, but it happens during bootup.  I can't be certain my cf card
works with DMA though, as I don't have anything else handy to test it with.

I do have a driver which communicates with an FPGA using the LocalPlus bus,
but for the purpose of testing I don't have it installed, and the FPGA I/O
is tristated.

I recall reading somewhere that the lite5200B board had some problem with
IDE signal integrity when using a regular IDE cable, so I used an ultra-IDE
cable with the same results.  On our own hardware, there is no cable as the
drive mounts directly to a connector on our board within ~3" of the
processor.

Any thoughts.....

Thanks,
-Jeff
-- 
View this message in context: http://www.nabble.com/-PATCH-%3A--MPC5200--Add-ATA-DMA-support-tp17880454p19336474.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-13  6:11                             ` Grant Likely
@ 2008-08-13  9:07                               ` Tim Yamin
  2008-09-15  5:54                                 ` Grant Likely
  2008-11-11 14:04                                 ` Lehmann, Hans (Ritter Elektronik)
  0 siblings, 2 replies; 24+ messages in thread
From: Tim Yamin @ 2008-08-13  9:07 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 268 bytes --]

On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> Sounds good to me.  You will get more testers that way.  I can pick it
> up for -next if everything else looks good.

Here are the new patches; tested against 2.6.27-rc3.

Thanks,

Tim

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bestcomm-ata-fixes.patch --]
[-- Type: text/x-diff; name=bestcomm-ata-fixes.patch, Size: 4212 bytes --]

1) ata.h has dst_pa in the wrong place (needs to match what the BestComm
   task microcode in bcom_ata_task.c expects); fix it.

2) The BestComm ATA task priority was changed to maximum in bestcomm_priv.h;
   this fixes a deadlock issue I was experiencing when heavy DMA was
   occuring on both the ATA and Ethernet BestComm tasks, e.g. when
   downloading a large file over a LAN to disk.

3) The ATA BestComm driver uses bcom_ata_bd which is bigger than bcom_bd
   and this causes problems because the various bcom_... functions do not
   dereference the correct location. I've introduced bcom_get_bd which
   uses bcom_task.bd_size and this fixes the problem.

Signed-off-by: Tim Yamin <plasm@roo.me.uk>

diff -urp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/ata.h linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/ata.h	2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h	2008-07-03 16:17:05.000000000 +0100
@@ -16,8 +16,8 @@
 
 struct bcom_ata_bd {
 	u32	status;
-	u32	dst_pa;
 	u32	src_pa;
+	u32	dst_pa;
 };
 
 extern struct bcom_task *
diff -urp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.h linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-07-03 16:17:05.000000000 +0100
@@ -38,7 +38,7 @@ struct bcom_task {
 	unsigned int	flags;
 	int		irq;
 
-	struct bcom_bd	*bd;
+	void		*bd;
 	phys_addr_t	bd_pa;
 	void		**cookie;
 	unsigned short	index;
@@ -140,15 +140,29 @@ bcom_queue_full(struct bcom_task *tsk)
 }
 
 /**
+ * bcom_get_bd - Get a BD from the queue
+ * @tsk: The BestComm task structure
+ * index: Index of the BD to fetch
+ */
+static inline struct bcom_bd
+*bcom_get_bd(struct bcom_task *tsk, unsigned int index)
+{
+	return tsk->bd + index * tsk->bd_size;
+}
+
+/**
  * bcom_buffer_done - Checks if a BestComm 
  * @tsk: The BestComm task structure
  */
 static inline int
 bcom_buffer_done(struct bcom_task *tsk)
 {
+	struct bcom_bd *bd;
 	if (bcom_queue_empty(tsk))
 		return 0;
-	return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
+
+	bd = bcom_get_bd(tsk, tsk->outdex);
+	return !(bd->status & BCOM_BD_READY);
 }
 
 /**
@@ -160,16 +174,21 @@ bcom_buffer_done(struct bcom_task *tsk)
 static inline struct bcom_bd *
 bcom_prepare_next_buffer(struct bcom_task *tsk)
 {
-	tsk->bd[tsk->index].status = 0;	/* cleanup last status */
-	return &tsk->bd[tsk->index];
+	struct bcom_bd *bd;
+
+	bd = bcom_get_bd(tsk, tsk->index);
+	bd->status = 0;	/* cleanup last status */
+	return bd;
 }
 
 static inline void
 bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
 {
+	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
+
 	tsk->cookie[tsk->index] = cookie;
 	mb();	/* ensure the bd is really up-to-date */
-	tsk->bd[tsk->index].status |= BCOM_BD_READY;
+	bd->status |= BCOM_BD_READY;
 	tsk->index = _bcom_next_index(tsk);
 	if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
 		bcom_enable(tsk);
@@ -179,10 +198,12 @@ static inline void *
 bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
 {
 	void *cookie = tsk->cookie[tsk->outdex];
+	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
+
 	if (p_status)
-		*p_status = tsk->bd[tsk->outdex].status;
+		*p_status = bd->status;
 	if (p_bd)
-		*p_bd = &tsk->bd[tsk->outdex];
+		*p_bd = bd;
 	tsk->outdex = _bcom_next_outdex(tsk);
 	return cookie;
 }
diff -urp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h	2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h	2008-07-03 16:17:05.000000000 +0100
@@ -198,8 +198,8 @@ struct bcom_task_header {
 #define BCOM_IPR_SCTMR_1	2
 #define BCOM_IPR_FEC_RX		6
 #define BCOM_IPR_FEC_TX		5
-#define BCOM_IPR_ATA_RX		4
-#define BCOM_IPR_ATA_TX		3
+#define BCOM_IPR_ATA_RX		7
+#define BCOM_IPR_ATA_TX		7
 #define BCOM_IPR_SCPCI_RX	2
 #define BCOM_IPR_SCPCI_TX	2
 #define BCOM_IPR_PSC3_RX	2

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: pata_mpc52xx-add-dma.patch --]
[-- Type: text/x-diff; name=pata_mpc52xx-add-dma.patch, Size: 18055 bytes --]

This patch adds MDMA/UDMA support (using BestComm for DMA) on the MPC5200
platform. Patch requires the ATA BestComm fixes to function properly.

Based heavily on previous work by Freescale (Bernard Kuhn, John Rigby)
and Domen Puncer.

Using a SanDisk Extreme IV CF card I get read speeds of approximately
26.70 MB/sec.

Comments and testing would of course be very welcome.

Thanks,

Signed-off-by: Tim Yamin <plasm@roo.me.uk>

diff -urp linux-2.6.27-rc3/arch/powerpc/sysdev/bestcomm/bestcomm.c linux-2.6.27-rc3-ata/arch/powerpc/sysdev/bestcomm/bestcomm.c
--- linux-2.6.27-rc3/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.27-rc3-ata/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-07-03 16:17:05.000000000 +0100
@@ -330,11 +330,16 @@ bcom_engine_init(void)
 	/* Init 'always' initiator */
 	out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
 
+	/* If ATA DMA is enabled, always turn prefetch off (it breaks things) */
+#ifndef CONFIG_PATA_MPC52xx_DMA
 	/* Disable COMM Bus Prefetch on the original 5200; it's broken */
 	if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
+#endif
 		regval = in_be16(&bcom_eng->regs->PtdCntrl);
 		out_be16(&bcom_eng->regs->PtdCntrl,  regval | 1);
+#ifndef CONFIG_PATA_MPC52xx_DMA
 	}
+#endif
 
 	/* Init lock */
 	spin_lock_init(&bcom_eng->lock);
diff -urp linux-2.6.27-rc3/drivers/ata/Kconfig linux-2.6.27-rc3-ata/drivers/ata/Kconfig
--- linux-2.6.27-rc3/drivers/ata/Kconfig	2008-07-03 13:06:35.000000000 +0100
+++ linux-2.6.27-rc3-ata/drivers/ata/Kconfig	2008-07-03 16:16:32.000000000 +0100
@@ -462,6 +462,15 @@ config PATA_MPC52xx
 
 	  If unsure, say N.
 
+config PATA_MPC52xx_DMA
+	bool "Freescale MPC52xx SoC internal IDE DMA (Experimental)"
+	depends on PATA_MPC52xx
+	help
+	  This option enables support for DMA on the MPC52xx SoC PATA
+	  controller.
+
+	  If unsure, say N.
+
 config PATA_MPIIX
 	tristate "Intel PATA MPIIX support"
 	depends on PCI
diff -urp linux-2.6.27-rc3/drivers/ata/pata_mpc52xx.c linux-2.6.27-rc3-ata/drivers/ata/pata_mpc52xx.c
--- linux-2.6.27-rc3/drivers/ata/pata_mpc52xx.c	2008-07-03 13:06:35.000000000 +0100
+++ linux-2.6.27-rc3-ata/drivers/ata/pata_mpc52xx.c	2008-07-03 16:16:32.000000000 +0100
@@ -6,6 +6,9 @@
  * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
  * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
  *
+ * UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
+ * Domen Puncer and Tim Yamin.
+ *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
  * kind, whether express or implied.
@@ -17,28 +20,47 @@
 #include <linux/delay.h>
 #include <linux/libata.h>
 #include <linux/of_platform.h>
 
+#include <asm/cacheflush.h>
 #include <asm/types.h>
 #include <asm/prom.h>
 #include <asm/mpc52xx.h>
 
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/bestcomm_priv.h>
+#include <sysdev/bestcomm/ata.h>
 
 #define DRV_NAME	"mpc52xx_ata"
 #define DRV_VERSION	"0.1.2"
 
-
 /* Private structures used by the driver */
 struct mpc52xx_ata_timings {
 	u32	pio1;
 	u32	pio2;
+	u32	mdma1;
+	u32	mdma2;
+	u32	udma1;
+	u32	udma2;
+	u32	udma3;
+	u32	udma4;
+	u32	udma5;
+	int	using_udma;
 };
 
 struct mpc52xx_ata_priv {
 	unsigned int			ipb_period;
 	struct mpc52xx_ata __iomem *	ata_regs;
+	phys_addr_t			ata_regs_pa;
 	int				ata_irq;
 	struct mpc52xx_ata_timings	timings[2];
 	int				csel;
+
+	/* DMA */
+	struct bcom_task		*dmatsk;
+	const struct udmaspec		*udmaspec;
+	const struct mdmaspec		*mdmaspec;
+	int 				mpc52xx_ata_dma_last_write;
+	int				waiting_for_dma;
 };
 
 
@@ -53,6 +75,107 @@ static const int ataspec_ta[5]    = { 35
 
 #define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
 
+/* ======================================================================== */
+
+/* ATAPI-4 MDMA specs (in clocks) */
+struct mdmaspec {
+	u32 t0M;
+	u32 td;
+	u32 th;
+	u32 tj;
+	u32 tkw;
+	u32 tm;
+	u32 tn;
+};
+
+static const struct mdmaspec mdmaspec66[3] = {
+	{ .t0M = 32, .td = 15, .th = 2, .tj = 2, .tkw = 15, .tm = 4, .tn = 1 },
+	{ .t0M = 10, .td = 6,  .th = 1, .tj = 1, .tkw = 4,  .tm = 2, .tn = 1 },
+	{ .t0M = 8,  .td = 5,  .th = 1, .tj = 1, .tkw = 2,  .tm = 2, .tn = 1 },
+};
+
+static const struct mdmaspec mdmaspec132[3] = {
+	{ .t0M = 64, .td = 29, .th = 3, .tj = 3, .tkw = 29, .tm = 7, .tn = 2 },
+	{ .t0M = 20, .td = 11, .th = 2, .tj = 1, .tkw = 7,  .tm = 4, .tn = 1 },
+	{ .t0M = 16, .td = 10, .th = 2, .tj = 1, .tkw = 4,  .tm = 4, .tn = 1 },
+};
+
+/* ATAPI-4 UDMA specs (in clocks) */
+struct udmaspec {
+	u32 tcyc;
+	u32 t2cyc;
+	u32 tds;
+	u32 tdh;
+	u32 tdvs;
+	u32 tdvh;
+	u32 tfs;
+	u32 tli;
+	u32 tmli;
+	u32 taz;
+	u32 tzah;
+	u32 tenv;
+	u32 tsr;
+	u32 trfs;
+	u32 trp;
+	u32 tack;
+	u32 tss;
+};
+
+static const struct udmaspec udmaspec66[6] = {
+	{ .tcyc = 8,  .t2cyc = 16, .tds  = 1,  .tdh  = 1, .tdvs = 5,  .tdvh = 1,
+	  .tfs  = 16, .tli   = 10, .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 3,  .trfs  = 5,  .trp  = 11, .tack = 2, .tss  = 4,
+	},
+	{ .tcyc = 5,  .t2cyc = 11, .tds  = 1,  .tdh  = 1, .tdvs = 4,  .tdvh = 1,
+	  .tfs  = 14, .tli   = 10, .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 2,  .trfs  = 5,  .trp  = 9,  .tack = 2, .tss  = 4,
+	},
+	{ .tcyc = 4,  .t2cyc = 8,  .tds  = 1,  .tdh  = 1, .tdvs = 3,  .tdvh = 1,
+	  .tfs  = 12, .tli   = 10, .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 2,  .trfs  = 4,  .trp  = 7,  .tack = 2, .tss  = 4,
+	},
+	{ .tcyc = 3,  .t2cyc = 6,  .tds  = 1,  .tdh  = 1, .tdvs = 2,  .tdvh = 1,
+	  .tfs  = 9,  .tli   = 7,  .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 2,  .trfs  = 4,  .trp  = 7,  .tack = 2, .tss  = 4,
+	},
+	{ .tcyc = 2,  .t2cyc = 4,  .tds  = 1,  .tdh  = 1, .tdvs = 1,  .tdvh = 1,
+	  .tfs  = 8,  .tli   = 8,  .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 2,  .trfs  = 4,  .trp  = 7,  .tack = 2, .tss  = 4,
+	},
+	{ .tcyc = 2,  .t2cyc = 2,  .tds  = 1,  .tdh  = 1, .tdvs = 1,  .tdvh = 1,
+	  .tfs  = 6,  .tli   = 5,  .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 2,  .trfs  = 4,  .trp  = 6,  .tack = 2, .tss  = 4,
+	},
+};
+
+static const struct udmaspec udmaspec132[6] = {
+	{ .tcyc = 15, .t2cyc = 31, .tds  = 2,  .tdh  = 1, .tdvs = 10, .tdvh = 1,
+	  .tfs  = 30, .tli   = 20, .tmli = 3,  .taz  = 2, .tzah = 3,  .tenv = 3,
+	  .tsr  = 7,  .trfs  = 10, .trp  = 22, .tack = 3, .tss  = 7,
+	},
+	{ .tcyc = 10, .t2cyc = 21, .tds  = 2,  .tdh  = 1, .tdvs = 7,  .tdvh = 1,
+	  .tfs  = 27, .tli   = 20, .tmli = 3,  .taz  = 2, .tzah = 3,  .tenv = 3,
+	  .tsr  = 4,  .trfs  = 10, .trp  = 17, .tack = 3, .tss  = 7,
+	},
+	{ .tcyc = 6,  .t2cyc = 12, .tds  = 1,  .tdh  = 1, .tdvs = 5,  .tdvh = 1,
+	  .tfs  = 23, .tli   = 20, .tmli = 3,  .taz  = 2, .tzah = 3,  .tenv = 3,
+	  .tsr  = 3,  .trfs  = 8,  .trp  = 14, .tack = 3, .tss  = 7,
+	},
+	{ .tcyc = 7,  .t2cyc = 12, .tds  = 1,  .tdh  = 1, .tdvs = 3,  .tdvh = 1,
+	  .tfs  = 15, .tli   = 13, .tmli = 3,  .taz  = 2, .tzah = 3,  .tenv = 3,
+	  .tsr  = 3,  .trfs  = 8,  .trp  = 14, .tack = 3, .tss  = 7,
+	},
+	{ .tcyc = 2,  .t2cyc = 5,  .tds  = 0,  .tdh  = 0, .tdvs = 1,  .tdvh = 1,
+	  .tfs  = 16, .tli   = 14, .tmli = 2,  .taz  = 1, .tzah = 2,  .tenv = 2,
+	  .tsr  = 2,  .trfs  = 7,  .trp  = 13, .tack = 2, .tss  = 6,
+	},
+	{ .tcyc = 3,  .t2cyc = 6,  .tds  = 1,  .tdh  = 1, .tdvs = 1,  .tdvh = 1,
+	  .tfs  = 12, .tli   = 10, .tmli = 3,  .taz  = 2, .tzah = 3,  .tenv = 3,
+	  .tsr  = 3,  .trfs  = 7,  .trp  = 12, .tack = 3, .tss  = 7,
+	},
+};
+
+/* ======================================================================== */
 
 /* Bit definitions inside the registers */
 #define MPC52xx_ATA_HOSTCONF_SMR	0x80000000UL /* State machine reset */
@@ -66,6 +189,7 @@ static const int ataspec_ta[5]    = { 35
 #define MPC52xx_ATA_HOSTSTAT_WERR	0x01000000UL /* Write Error */
 
 #define MPC52xx_ATA_FIFOSTAT_EMPTY	0x01 /* FIFO Empty */
+#define MPC52xx_ATA_FIFOSTAT_ERROR	0x40 /* FIFO Error */
 
 #define MPC52xx_ATA_DMAMODE_WRITE	0x01 /* Write DMA */
 #define MPC52xx_ATA_DMAMODE_READ	0x02 /* Read DMA */
@@ -75,6 +199,8 @@ static const int ataspec_ta[5]    = { 35
 #define MPC52xx_ATA_DMAMODE_FR		0x20 /* FIFO Reset */
 #define MPC52xx_ATA_DMAMODE_HUT		0x40 /* Host UDMA burst terminate */
 
+#define MAX_DMA_BUFFERS 128
+#define MAX_DMA_BUFFER_SIZE 0x20000u
 
 /* Structure of the hardware registers */
 struct mpc52xx_ata {
@@ -165,6 +294,41 @@ mpc52xx_ata_compute_pio_timings(struct m
 	return 0;
 }
 
+static int
+mpc52xx_ata_compute_mdma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+	struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+	const struct mdmaspec *s = &priv->mdmaspec[speed];
+
+	if (speed < 0 || speed > 2)
+		return -EINVAL;
+
+	timing->mdma1 = (s->t0M << 24) | (s->td << 16) | (s->tkw << 8) | (s->tm);
+	timing->mdma2 = (s->th << 24) | (s->tj << 16) | (s->tn << 8);
+	timing->using_udma = 0;
+
+	return 0;
+}
+
+static int
+mpc52xx_ata_compute_udma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+	struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+	const struct udmaspec *s = &priv->udmaspec[speed];
+
+	if (speed < 0 || speed > 2)
+		return -EINVAL;
+
+	timing->udma1 = (s->t2cyc << 24) | (s->tcyc << 16) | (s->tds << 8) | (s->tdh);
+	timing->udma2 = (s->tdvs << 24) | (s->tdvh << 16) | (s->tfs << 8) | (s->tli);
+	timing->udma3 = (s->tmli << 24) | (s->taz << 16) | (s->tenv << 8) | (s->tsr);
+	timing->udma4 = (s->tss << 24) | (s->trfs << 16) | (s->trp << 8) | (s->tack);
+	timing->udma5 = (s->tzah << 24);
+	timing->using_udma = 1;
+
+	return 0;
+}
+
 static void
 mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
 {
@@ -173,14 +337,13 @@ mpc52xx_ata_apply_timings(struct mpc52xx
 
 	out_be32(&regs->pio1,  timing->pio1);
 	out_be32(&regs->pio2,  timing->pio2);
-	out_be32(&regs->mdma1, 0);
-	out_be32(&regs->mdma2, 0);
-	out_be32(&regs->udma1, 0);
-	out_be32(&regs->udma2, 0);
-	out_be32(&regs->udma3, 0);
-	out_be32(&regs->udma4, 0);
-	out_be32(&regs->udma5, 0);
-
+	out_be32(&regs->mdma1, timing->mdma1);
+	out_be32(&regs->mdma2, timing->mdma2);
+	out_be32(&regs->udma1, timing->udma1);
+	out_be32(&regs->udma2, timing->udma2);
+	out_be32(&regs->udma3, timing->udma3);
+	out_be32(&regs->udma4, timing->udma4);
+	out_be32(&regs->udma5, timing->udma5);
 	priv->csel = device;
 }
 
@@ -245,6 +408,29 @@ mpc52xx_ata_set_piomode(struct ata_port 
 	mpc52xx_ata_apply_timings(priv, adev->devno);
 }
 static void
+mpc52xx_ata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	int rv;
+
+	if (adev->dma_mode >= XFER_UDMA_0) {
+		int dma = adev->dma_mode - XFER_UDMA_0;
+		rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma);
+	} else {
+		int dma = adev->dma_mode - XFER_MW_DMA_0;
+		rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma);
+	}
+
+	if (rv) {
+		dev_alert(ap->dev,
+			"Trying to select invalid DMA mode %d\n",
+			adev->dma_mode);
+		return;
+	}
+
+	mpc52xx_ata_apply_timings(priv, adev->devno);
+}
+static void
 mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
 {
 	struct mpc52xx_ata_priv *priv = ap->host->private_data;
@@ -255,16 +441,187 @@ mpc52xx_ata_dev_select(struct ata_port *
 	ata_sff_dev_select(ap,device);
 }
 
+static int
+mpc52xx_ata_build_dmatable(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE), si;
+	struct scatterlist *sg;
+	int count = 0;
+
+	if (read)
+		bcom_ata_rx_prepare(priv->dmatsk);
+	else
+		bcom_ata_tx_prepare(priv->dmatsk);
+
+	for_each_sg(qc->sg, sg, qc->n_elem, si) {
+		dma_addr_t cur_addr = sg_dma_address(sg);
+		u32 cur_len = sg_dma_len(sg);
+
+		while (cur_len) {
+			unsigned int tc = min(cur_len, MAX_DMA_BUFFER_SIZE);
+			struct bcom_ata_bd *bd = (struct bcom_ata_bd *) bcom_prepare_next_buffer(priv->dmatsk);
+
+			if (read) {
+				bd->status = tc;
+				bd->src_pa = (__force u32) priv->ata_regs_pa +
+					offsetof(struct mpc52xx_ata, fifo_data);
+				bd->dst_pa = (__force u32) cur_addr;
+			} else {
+				bd->status = tc;
+				bd->src_pa = (__force u32) cur_addr;
+				bd->dst_pa = (__force u32) priv->ata_regs_pa +
+					offsetof(struct mpc52xx_ata, fifo_data);
+			}
+
+			bcom_submit_next_buffer(priv->dmatsk, NULL);
+
+			cur_addr += tc;
+			cur_len -= tc;
+			count++;
+
+			if (count > MAX_DMA_BUFFERS) {
+				dev_alert(ap->dev, "dma table"
+					"too small\n");
+				goto use_pio_instead;
+			}
+		}
+	}
+	return 1;
+
+ use_pio_instead:
+	bcom_ata_reset_bd(priv->dmatsk);
+	return 0;
+}
+
+static void
+mpc52xx_bmdma_setup(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+
+	unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
+	u8 dma_mode;
+
+	if (!mpc52xx_ata_build_dmatable(qc))
+		dev_alert(ap->dev, "%s: %i, return 1?\n",
+			__func__, __LINE__);
+
+	/* Check FIFO is OK... */
+	if(in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
+		dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
+			__func__, in_8(&priv->ata_regs->fifo_status));
+
+	if (read) {
+		dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_READ |
+				MPC52xx_ATA_DMAMODE_FE;
+
+		/* Setup FIFO if direction changed */
+		if (priv->mpc52xx_ata_dma_last_write != 0) {
+			priv->mpc52xx_ata_dma_last_write = 0;
+
+			/* Configure FIFO with granularity to 7 */
+			out_8(&regs->fifo_control, 7);
+			out_be16(&regs->fifo_alarm, 128);
+
+			/* Set FIFO Reset bit (FR) */
+			out_8(&regs->dma_mode, MPC52xx_ATA_DMAMODE_FR);
+		}
+	} else {
+		dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_WRITE;
+
+		/* Setup FIFO if direction changed */
+		if (priv->mpc52xx_ata_dma_last_write != 1) {
+			priv->mpc52xx_ata_dma_last_write = 1;
+
+			/* Configure FIFO with granularity to 4 */
+			out_8(&regs->fifo_control, 4);
+			out_be16(&regs->fifo_alarm, 128);
+		}
+	}
+
+	if (priv->timings[qc->dev->devno].using_udma)
+		dma_mode |= MPC52xx_ATA_DMAMODE_UDMA;
+
+	out_8(&regs->dma_mode, dma_mode);
+	priv->waiting_for_dma = ATA_DMA_ACTIVE;
+
+	ata_wait_idle(ap);
+	ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+static void
+mpc52xx_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+	bcom_set_task_auto_start(priv->dmatsk->tasknum, priv->dmatsk->tasknum);
+	bcom_enable(priv->dmatsk);
+}
+
+static void
+mpc52xx_bmdma_stop(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+	bcom_disable(priv->dmatsk);
+	bcom_ata_reset_bd(priv->dmatsk);
+	priv->waiting_for_dma = 0;
+
+	/* Check FIFO is OK... */
+	if(in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
+		dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
+			__func__, in_8(&priv->ata_regs->fifo_status));
+}
+
+static u8
+mpc52xx_bmdma_status(struct ata_port *ap)
+{
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+	/* Check FIFO is OK... */
+	if(in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) {
+		dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
+			__func__, in_8(&priv->ata_regs->fifo_status));
+		return priv->waiting_for_dma | ATA_DMA_ERR;
+	}
+
+	return priv->waiting_for_dma;
+}
+
+static irqreturn_t
+mpc52xx_ata_task_irq(int irq, void *vpriv)
+{
+	struct mpc52xx_ata_priv *priv = vpriv;
+	while (bcom_buffer_done(priv->dmatsk))
+		bcom_retrieve_buffer(priv->dmatsk, NULL, NULL);
+	
+	priv->waiting_for_dma |= ATA_DMA_INTR;
+
+	return IRQ_HANDLED;
+}
+
 static struct scsi_host_template mpc52xx_ata_sht = {
 	ATA_PIO_SHT(DRV_NAME),
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
 	.inherits		= &ata_sff_port_ops,
-	.sff_dev_select		= mpc52xx_ata_dev_select,
-	.cable_detect		= ata_cable_40wire,
+
 	.set_piomode		= mpc52xx_ata_set_piomode,
-	.post_internal_cmd	= ATA_OP_NULL,
+	.set_dmamode		= mpc52xx_ata_set_dmamode,
+	.sff_dev_select		= mpc52xx_ata_dev_select,
+
+	.bmdma_setup		= mpc52xx_bmdma_setup,
+	.bmdma_start		= mpc52xx_bmdma_start,
+	.bmdma_stop		= mpc52xx_bmdma_stop,
+	.bmdma_status		= mpc52xx_bmdma_status,
+
+	.qc_prep		= ata_noop_qc_prep,
 };
 
 static int __devinit
@@ -281,9 +643,11 @@ mpc52xx_ata_init_one(struct device *dev,
 
 	ap = host->ports[0];
 	ap->flags		|= ATA_FLAG_SLAVE_POSS;
-	ap->pio_mask		= 0x1f;	/* Up to PIO4 */
-	ap->mwdma_mask		= 0x00;	/* No MWDMA   */
-	ap->udma_mask		= 0x00;	/* No UDMA    */
+	ap->pio_mask		= ATA_PIO4;	/* Up to PIO4 */
+#ifdef CONFIG_PATA_MPC52xx_DMA
+	ap->mwdma_mask		= ATA_MWDMA2;	/* Up to MWDMA2 */
+	ap->udma_mask		= ATA_UDMA2;	/* Up to UDMA2 */
+#endif
 	ap->ops			= &mpc52xx_ata_port_ops;
 	host->private_data	= priv;
 
@@ -333,7 +697,7 @@ mpc52xx_ata_probe(struct of_device *op, 
 	int ata_irq;
 	struct mpc52xx_ata __iomem *ata_regs;
 	struct mpc52xx_ata_priv *priv;
-	int rv;
+	int rv, ret, task_irq;
 
 	/* Get ipb frequency */
 	ipb_freq = mpc52xx_find_ipb_freq(op->node);
@@ -389,8 +753,32 @@ mpc52xx_ata_probe(struct of_device *op, 
 
 	priv->ipb_period = 1000000000 / (ipb_freq / 1000);
 	priv->ata_regs = ata_regs;
+	priv->ata_regs_pa = res_mem.start;
 	priv->ata_irq = ata_irq;
 	priv->csel = -1;
+	priv->mpc52xx_ata_dma_last_write = -1;
+
+	if (ipb_freq/1000000 == 66) {
+		priv->mdmaspec = mdmaspec66;
+		priv->udmaspec = udmaspec66;
+	} else {
+		priv->mdmaspec = mdmaspec132;
+		priv->udmaspec = udmaspec132;
+	}
+
+	priv->dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
+	if (!priv->dmatsk) {
+		dev_alert(&op->dev, "Failed to initialize BestComm task!\n");
+		rv = -ENOMEM;
+		goto err;
+	}
+
+	task_irq = bcom_get_task_irq(priv->dmatsk);
+	ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED,
+				"ATA task", priv);
+	if (ret)
+		dev_alert(&op->dev, "request_irq failed with: "
+					"%i\n", ret);
 
 	/* Init the hw */
 	rv = mpc52xx_ata_hw_init(priv);

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-13  6:06                           ` Tim Yamin
@ 2008-08-13  6:11                             ` Grant Likely
  2008-08-13  9:07                               ` Tim Yamin
  0 siblings, 1 reply; 24+ messages in thread
From: Grant Likely @ 2008-08-13  6:11 UTC (permalink / raw)
  To: Tim Yamin; +Cc: linuxppc-dev

On Wed, Aug 13, 2008 at 07:06:27AM +0100, Tim Yamin wrote:
> On Wed, Aug 13, 2008 at 7:02 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> > While on this topic; have you had a chance to address the comments you
> > received on v2 of your patch?  I'm keen to get your change merged in,
> > but there are a few more things that need to be sorted out.
> 
> I'm still trying to determine whether the locking stuff is needed or
> not. I think ultimately it might be a bug caused by hardware problems
> at this end as opposed to silicon problems affecting everybody, but I
> won't have an answer regarding this for a while because new hardware
> needs to be prototyped to test out this theory.
> 
> I think the patch can probably be resubmitted with the locking stuff
> removed, and the driver can be marked as experimental for everybody to
> try out: if people experience any corruption problems I'm sure they
> can speak up :-)
> 
> Any objections?

Sounds good to me.  You will get more testers that way.  I can pick it
up for -next if everything else looks good.

g.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-13  6:02                         ` Grant Likely
@ 2008-08-13  6:06                           ` Tim Yamin
  2008-08-13  6:11                             ` Grant Likely
  0 siblings, 1 reply; 24+ messages in thread
From: Tim Yamin @ 2008-08-13  6:06 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev

On Wed, Aug 13, 2008 at 7:02 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> While on this topic; have you had a chance to address the comments you
> received on v2 of your patch?  I'm keen to get your change merged in,
> but there are a few more things that need to be sorted out.

I'm still trying to determine whether the locking stuff is needed or
not. I think ultimately it might be a bug caused by hardware problems
at this end as opposed to silicon problems affecting everybody, but I
won't have an answer regarding this for a while because new hardware
needs to be prototyped to test out this theory.

I think the patch can probably be resubmitted with the locking stuff
removed, and the driver can be marked as experimental for everybody to
try out: if people experience any corruption problems I'm sure they
can speak up :-)

Any objections?

Tim

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-13  5:57                       ` Tim Yamin
@ 2008-08-13  6:02                         ` Grant Likely
  2008-08-13  6:06                           ` Tim Yamin
  0 siblings, 1 reply; 24+ messages in thread
From: Grant Likely @ 2008-08-13  6:02 UTC (permalink / raw)
  To: Tim Yamin; +Cc: linuxppc-dev

On Tue, Aug 12, 2008 at 11:57 PM, Tim Yamin <plasm@roo.me.uk> wrote:
> On Tue, Aug 12, 2008 at 6:30 PM, Daniel Schnell
> <daniel.schnell@marel.com> wrote:
>> Hi Tim,
>>
>> Continuing the discussion on the mailing list ...
>>
>> Looking at the original patch I don't undestand why you had to duplicate
>> the bestcomm data structures and functions. The only apparent difference
>> is that you have a minimal data length of 2 bytes instead of 1. Does
>> this make any difference as the bd_size will be filled with the correct
>> length value anyway ?
>
> The "new" version of the patch does this the correct way. I just
> haven't back ported this to the 2.6.24 version that I sent you.

While on this topic; have you had a chance to address the comments you
received on v2 of your patch?  I'm keen to get your change merged in,
but there are a few more things that need to be sorted out.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-12 17:30                     ` Daniel Schnell
@ 2008-08-13  5:57                       ` Tim Yamin
  2008-08-13  6:02                         ` Grant Likely
  0 siblings, 1 reply; 24+ messages in thread
From: Tim Yamin @ 2008-08-13  5:57 UTC (permalink / raw)
  To: Daniel Schnell; +Cc: linuxppc-dev

On Tue, Aug 12, 2008 at 6:30 PM, Daniel Schnell
<daniel.schnell@marel.com> wrote:
> Hi Tim,
>
> Continuing the discussion on the mailing list ...
>
> Looking at the original patch I don't undestand why you had to duplicate
> the bestcomm data structures and functions. The only apparent difference
> is that you have a minimal data length of 2 bytes instead of 1. Does
> this make any difference as the bd_size will be filled with the correct
> length value anyway ?

The "new" version of the patch does this the correct way. I just
haven't back ported this to the 2.6.24 version that I sent you.

Tim

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

* RE: [PATCH]: [MPC5200] Add ATA DMA support
       [not found]                   ` <792f5f410808120830v311e0446kc8fddfb97d0b9ea6@mail.gmail.com>
@ 2008-08-12 17:30                     ` Daniel Schnell
  2008-08-13  5:57                       ` Tim Yamin
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Schnell @ 2008-08-12 17:30 UTC (permalink / raw)
  To: Tim Yamin; +Cc: linuxppc-dev

Hi Tim,

Continuing the discussion on the mailing list ...


Looking at the original patch I don't undestand why you had to duplicate
the bestcomm data structures and functions. The only apparent difference
is that you have a minimal data length of 2 bytes instead of 1. Does
this make any difference as the bd_size will be filled with the correct
length value anyway ?

Moreover what is the difference between bcom_submit_next_buffer() and
bcom_submit_next_buffer2() ? The same with bcom_retrieve_buffer() and
bcom_retrieve_buffer2(). Why are these functions implemented unequally ?


Best regards,

Daniel Schnell.

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

* RE: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-06 13:26     ` Daniel Schnell
@ 2008-08-06 14:31       ` Daniel Schnell
  0 siblings, 0 replies; 24+ messages in thread
From: Daniel Schnell @ 2008-08-06 14:31 UTC (permalink / raw)
  To: Tim Yamin; +Cc: linuxppc-dev

Hi,

Daniel Schnell wrote:
> Tim Yamin wrote:
>> On Wed, Aug 6, 2008 at 12:58 PM, Daniel Schnell
>> <daniel.schnell@marel.com> wrote:
>>> Hi,
>>>=20
>>> Sorry for testing this patch so late, but I get these if I apply
>>> your patch to 2.6.24.7 and use it with my Sandisk Extreme IV 4GB
>>> card:=20
>>=20
>> Hi,
>>=20
>> What board are you using? DMA requires a few more signals to be
>> routed through correctly to the CF card slot so maybe that's your
>> problem...=20
>>=20
>=20
> Hi,
>=20
> We are using our own MPC5200B based board. Can you be a bit more
> specific about which signals have to be routed ?=20
>=20

After checking our schematics with Tim Yamin, we found that our board
has not the DMA lines connected. It seems I have to wait some time
before I get an updated board and can test UDMA again ....


Sorry for the noise, although this was important for us to know.


Best regards,

Daniel.

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

* RE: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-06 12:18   ` Tim Yamin
@ 2008-08-06 13:26     ` Daniel Schnell
  2008-08-06 14:31       ` Daniel Schnell
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Schnell @ 2008-08-06 13:26 UTC (permalink / raw)
  To: Tim Yamin; +Cc: linuxppc-dev

Tim Yamin wrote:
> On Wed, Aug 6, 2008 at 12:58 PM, Daniel Schnell
> <daniel.schnell@marel.com> wrote:=20
>> Hi,
>>=20
>> Sorry for testing this patch so late, but I get these if I apply your
>> patch to 2.6.24.7 and use it with my Sandisk Extreme IV 4GB card:
>=20
> Hi,
>=20
> What board are you using? DMA requires a few more signals to be
> routed through correctly to the CF card slot so maybe that's your
> problem... =20
>=20

Hi,

We are using our own MPC5200B based board. Can you be a bit more
specific about which signals have to be routed ?


Best regards,

Daniel Schnell.

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

* Re: [PATCH]: [MPC5200] Add ATA DMA support
  2008-08-06 11:58 ` Daniel Schnell
@ 2008-08-06 12:18   ` Tim Yamin
  2008-08-06 13:26     ` Daniel Schnell
  0 siblings, 1 reply; 24+ messages in thread
From: Tim Yamin @ 2008-08-06 12:18 UTC (permalink / raw)
  To: Daniel Schnell; +Cc: linuxppc-dev

On Wed, Aug 6, 2008 at 12:58 PM, Daniel Schnell
<daniel.schnell@marel.com> wrote:
> Hi,
>
> Sorry for testing this patch so late, but I get these if I apply your
> patch to 2.6.24.7 and use it with my Sandisk Extreme IV 4GB card:

Hi,

What board are you using? DMA requires a few more signals to be routed
through correctly to the CF card slot so maybe that's your problem...

Tim

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

* RE: [PATCH]: [MPC5200] Add ATA DMA support
  2008-06-17  8:28 Tim Yamin
@ 2008-08-06 11:58 ` Daniel Schnell
  2008-08-06 12:18   ` Tim Yamin
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Schnell @ 2008-08-06 11:58 UTC (permalink / raw)
  To: Tim Yamin, linuxppc-dev

Hi,

Tim Yamin wrote:
> This patch adds MDMA/UDMA support (using BestComm for DMA) on the
> MPC5200 platform.=20
>=20
> Based heavily on previous work by Freescale (Bernard Kuhn, John
> Rigby) and Domen Puncer.=20
>=20
> Using a SanDisk Extreme IV CF card I get read speeds of approximately
> 26.70 MB/sec.=20
>=20
> The BestComm ATA task priority was changed to maximum in
> bestcomm_priv.h; this fixes a deadlock issue I was experiencing when
> heavy DMA was occuring on both the ATA and Ethernet BestComm tasks,
> e.g. when downloading a large file over a LAN to disk.  =20
>=20
> There's also what I believe to be a hardware bug if you have high
> levels of BestComm ATA DMA activity along with heavy LocalPlus Bus
> activity; the address bus seems to sometimes get corrupted with ATA
> commands while the LocalPlus Bus operation is still active (i.e. Chip
> Select is asserted).   =20
>=20
> I've asked Freescale about this but have not received a reply yet --
> if anybody from Freescale has any ideas please contact me; I can
> supply some analyzer traces if needed. Therefore, for now, do not
> enable DMA if you need reliable LocalPlus Bus unless you do a fixup
> in your driver as follows:  =20
>=20
> Locking example:
>=20
>         while (test_and_set_bit(0, &pata_mpc52xx_ata_dma_lock) !=3D 0)
>         {
>                 struct bcom_task_2 *tsk =3D pata_mpc52xx_ata_dma_task;
>=20
>                 if(bcom_buffer_done_2(tsk))
>                         return 1;
>         }
>=20
> 	return 0;
>=20
> (Save the return value to `flags`)
>=20
> Unlocking example:
>=20
>         if(flags =3D=3D 0)
>                 clear_bit(0, &pata_mpc52xx_ata_dma_lock);
>=20
> Comments and testing would of course be very welcome.
>=20
> Thanks,
>=20
> Signed-off-by: Tim Yamin <plasm@roo.me.uk>

Sorry for testing this patch so late, but I get these if I apply your
patch to 2.6.24.7 and use it with my Sandisk Extreme IV 4GB card:

...
[    0.999514] ata: MPC52xx IDE/ATA libata driver
[    1.006666] scsi0 : mpc52xx_ata
[    1.010969] ata1: PATA max UDMA/33 ata_regs 0xf0003a00 irq 135
[    1.168588] ata1.00: CFA: SanDisk SDCFX3-4096, HDX 4.31, max MWDMA2
[    1.175156] ata1.00: 8027712 sectors, multi 0: LBA
[    1.181098] ata1.00: configured for MWDMA2
[    1.196589] scsi 0:0:0:0: Direct-Access     ATA      SanDisk SDCFX3-4
HDX  PQ: 0 ANSI: 5
[    1.206949] sd 0:0:0:0: [sda] 8027712 512-byte hardware sectors (4110
MB)
[    1.214281] sd 0:0:0:0: [sda] Write Protect is off
[    1.219803] sd 0:0:0:0: [sda] Write cache: disabled, read cache:
enabled, doesn't support DPO or FUA
[    1.230407] sd 0:0:0:0: [sda] 8027712 512-byte hardware sectors (4110
MB)
[    1.237678] sd 0:0:0:0: [sda] Write Protect is off
[    1.243129] sd 0:0:0:0: [sda] Write cache: disabled, read cache:
enabled, doesn't support DPO or FUA
[    1.252684]  sda:<3>ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0
action 0x2 frozen
[   31.260361] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
dma 4096 in
[   31.260377]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[   31.275689] ata1.00: status: { DRDY }
[   31.279545] ata1: soft resetting link
[   31.435535] ata1.00: configured for MWDMA2
[   31.439933] ata1: EH complete
[   61.443060] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x2
frozen
[   61.450451] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
dma 4096 in
[   61.450467]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[   61.465777] ata1.00: status: { DRDY }
[   61.469632] ata1: soft resetting link
[   61.625541] ata1.00: configured for MWDMA2
[   61.629938] ata1: EH complete

...
[  363.394140] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x2
frozen
[  363.401534] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
dma 4096 in
[  363.401550]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[  363.416889] ata1.00: status: { DRDY }
[  363.420717] ata1: soft resetting link
[  363.576538] ata1.00: configured for MWDMA1
[  363.580927] sd 0:0:0:0: [sda] Result: hostbyte=3D0x00 =
driverbyte=3D0x08
[  363.587499] sd 0:0:0:0: [sda] Sense Key : 0xb [current] [descriptor]
[  363.594157] Descriptor sense data with sense descriptors (in hex):
[  363.600593]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00
[  363.607248]         00 00 00 00
[  363.610615] sd 0:0:0:0: [sda] ASC=3D0x0 ASCQ=3D0x0
[  363.615334] end_request: I/O error, dev sda, sector 0
[  363.620600] Buffer I/O error on device sda, logical block 0
[  363.626475]  unable to read partition table
[  363.631014] ata1: EH complete
[  363.635081] sd 0:0:0:0: [sda] Attached SCSI removable disk


And if I boot via NFS, the kernel can continue to boot after that point.

With a non-DMA card everything is fine.


Best regards,

Daniel.

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

* [PATCH]: [MPC5200] Add ATA DMA support
@ 2008-06-17  8:28 Tim Yamin
  2008-08-06 11:58 ` Daniel Schnell
  0 siblings, 1 reply; 24+ messages in thread
From: Tim Yamin @ 2008-06-17  8:28 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1612 bytes --]

This patch adds MDMA/UDMA support (using BestComm for DMA) on the MPC5200
platform.

Based heavily on previous work by Freescale (Bernard Kuhn, John Rigby)
and Domen Puncer.

Using a SanDisk Extreme IV CF card I get read speeds of approximately
26.70 MB/sec.

The BestComm ATA task priority was changed to maximum in bestcomm_priv.h;
this fixes a deadlock issue I was experiencing when heavy DMA was
occuring on both the ATA and Ethernet BestComm tasks, e.g. when
downloading a large file over a LAN to disk.

There's also what I believe to be a hardware bug if you have high levels
of BestComm ATA DMA activity along with heavy LocalPlus Bus activity;
the address bus seems to sometimes get corrupted with ATA commands while
the LocalPlus Bus operation is still active (i.e. Chip Select is asserted).

I've asked Freescale about this but have not received a reply yet -- if
anybody from Freescale has any ideas please contact me; I can supply some
analyzer traces if needed. Therefore, for now, do not enable DMA if you
need reliable LocalPlus Bus unless you do a fixup in your driver as
follows:

Locking example:

        while (test_and_set_bit(0, &pata_mpc52xx_ata_dma_lock) != 0)
        {
                struct bcom_task_2 *tsk = pata_mpc52xx_ata_dma_task;

                if(bcom_buffer_done_2(tsk))
                        return 1;
        }

	return 0;

(Save the return value to `flags`)

Unlocking example:

        if(flags == 0)
                clear_bit(0, &pata_mpc52xx_ata_dma_lock);

Comments and testing would of course be very welcome.

Thanks,

Signed-off-by: Tim Yamin <plasm@roo.me.uk>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 1050-mpc5200-add-ATA-DMA.patch --]
[-- Type: text/x-patch; name=1050-mpc5200-add-ATA-DMA.patch, Size: 23417 bytes --]

This patch adds MDMA/UDMA support (using BestComm for DMA) on the MPC5200
platform.

Based heavily on previous work by Freescale (Bernard Kuhn, John Rigby)
and Domen Puncer.

Using a SanDisk Extreme IV CF card I get read speeds of approximately
26.70 MB/sec.

The BestComm ATA task priority was changed to maximum in bestcomm_priv.h;
this fixes a deadlock issue I was experiencing when heavy DMA was
occuring on both the ATA and Ethernet BestComm tasks, e.g. when
downloading a large file over a LAN to disk.

There's also what I believe to be a hardware bug if you have high levels
of BestComm ATA DMA activity along with heavy LocalPlus Bus activity;
the address bus seems to sometimes get corrupted with ATA commands while
the LocalPlus Bus operation is still active (i.e. Chip Select is asserted).

I've asked Freescale about this but have not received a reply yet -- if
anybody from Freescale has any ideas please contact me; I can supply some
analyzer traces if needed. Therefore, for now, do not enable DMA if you
need reliable LocalPlus Bus unless you do a fixup in your driver as
follows:

Locking example:

        while (test_and_set_bit(0, &pata_mpc52xx_ata_dma_lock) != 0)
        {
                struct bcom_task_2 *tsk = pata_mpc52xx_ata_dma_task;

                if(bcom_buffer_done_2(tsk))
                        return 1;
        }

	return 0;

(Save the return value to `flags`)

Unlocking example:

        if(flags == 0)
                clear_bit(0, &pata_mpc52xx_ata_dma_lock);

Comments and testing would of course be very welcome.

Thanks,

Signed-off-by: Tim Yamin <plasm@roo.me.uk>

diff -Nurp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/ata.h linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/ata.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/ata.h	2008-03-18 15:49:53.000000000 +0000
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/ata.h	2008-04-15 10:42:38.000000000 +0100
@@ -16,8 +16,8 @@
 
 struct bcom_ata_bd {
 	u32	status;
-	u32	dst_pa;
 	u32	src_pa;
+	u32	dst_pa;
 };
 
 extern struct bcom_task *
diff -Nurp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.c linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.c
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-03-18 15:49:53.000000000 +0000
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-04-15 10:42:38.000000000 +0100
@@ -330,11 +330,10 @@
 	/* Init 'always' initiator */
 	out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
 
-	/* Disable COMM Bus Prefetch on the original 5200; it's broken */
-	if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
-		regval = in_be16(&bcom_eng->regs->PtdCntrl);
-		out_be16(&bcom_eng->regs->PtdCntrl,  regval | 1);
-	}
+	/* Disable COMM Bus Prefetch; ATA DMA does not work properly with it
+	   enabled. */
+	regval = in_be16(&bcom_eng->regs->PtdCntrl);
+	out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
 
 	/* Init lock */
 	spin_lock_init(&bcom_eng->lock);
diff -Nurp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.h linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-03-18 15:49:53.000000000 +0000
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-04-15 10:42:38.000000000 +0100
@@ -17,6 +17,7 @@
 #define __BESTCOMM_H__
 
 struct bcom_bd; /* defined later on ... */
+struct bcom_bd_2;
 
 
 /* ======================================================================== */
@@ -49,6 +50,22 @@
 	void*		priv;
 };
 
+struct bcom_task_2 {
+	unsigned int	tasknum;
+	unsigned int	flags;
+	int		irq;
+
+	struct bcom_bd_2	*bd;
+	phys_addr_t	bd_pa;
+	void		**cookie;
+	unsigned short	index;
+	unsigned short	outdex;
+	unsigned int	num_bd;
+	unsigned int	bd_size;
+
+	void*		priv;
+};
+
 #define BCOM_FLAGS_NONE         0x00000000ul
 #define BCOM_FLAGS_ENABLE_TASK  (1ul <<  0)
 
@@ -95,6 +112,11 @@
 	u32	data[1];	/* variable, but at least 1 */
 };
 
+struct bcom_bd_2 {
+	u32	status;
+	u32	data[2];	/* variable, but at least 2 */
+};
+
 #define BCOM_BD_READY	0x40000000ul
 
 /** _bcom_next_index - Get next input index.
@@ -108,6 +130,12 @@
 	return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
 }
 
+static inline int
+_bcom_next_index_2(struct bcom_task_2 *tsk)
+{
+	return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
+}
+
 /** _bcom_next_outdex - Get next output index.
  * @tsk: pointer to task structure
  *
@@ -129,6 +157,12 @@
 	return tsk->index == tsk->outdex;
 }
 
+static inline int
+bcom_queue_empty_2(struct bcom_task_2 *tsk)
+{
+	return tsk->index == tsk->outdex;
+}
+
 /**
  * bcom_queue_full - Checks if a BestComm task BD queue is full
  * @tsk: The BestComm task structure
@@ -151,6 +185,14 @@
 	return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
 }
 
+static inline int
+bcom_buffer_done_2(struct bcom_task_2 *tsk)
+{
+	if (bcom_queue_empty_2(tsk))
+		return 0;
+	return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
+}
+
 /**
  * bcom_prepare_next_buffer - clear status of next available buffer.
  * @tsk: The BestComm task structure
@@ -175,6 +217,22 @@
 		bcom_enable(tsk);
 }
 
+static inline struct bcom_bd_2 *
+bcom_prepare_next_buffer_2(struct bcom_task_2 *tsk)
+{
+	tsk->bd[tsk->index].status = 0;	/* cleanup last status */
+	return &tsk->bd[tsk->index];
+}
+
+static inline void
+bcom_submit_next_buffer_2(struct bcom_task_2 *tsk, void *cookie)
+{
+	tsk->cookie[tsk->index] = cookie;
+	mb();	/* ensure the bd is really up-to-date */
+	tsk->bd[tsk->index].status |= BCOM_BD_READY;
+	tsk->index = _bcom_next_index_2(tsk);
+}
+
 static inline void *
 bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
 {
diff -Nurp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h	2008-03-18 15:49:53.000000000 +0000
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h	2008-04-15 10:42:38.000000000 +0100
@@ -198,8 +198,8 @@ struct bcom_task_header {
 #define BCOM_IPR_SCTMR_1	2
 #define BCOM_IPR_FEC_RX		6
 #define BCOM_IPR_FEC_TX		5
-#define BCOM_IPR_ATA_RX		4
-#define BCOM_IPR_ATA_TX		3
+#define BCOM_IPR_ATA_RX		7
+#define BCOM_IPR_ATA_TX		7
 #define BCOM_IPR_SCPCI_RX	2
 #define BCOM_IPR_SCPCI_TX	2
 #define BCOM_IPR_PSC3_RX	2
diff -Nurp linux-2.6.26-rc6/drivers/ata/Kconfig linux-2.6.26-rc6.new/drivers/ata/Kconfig
--- linux-2.6.26-rc6/drivers/ata/Kconfig	2008-03-18 15:49:33.000000000 +0000
+++ linux-2.6.26-rc6.new/drivers/ata/Kconfig	2008-04-15 10:41:51.000000000 +0100
@@ -462,6 +462,15 @@
 
 	  If unsure, say N.
 
+config PATA_MPC52xx_DMA
+	tristate "Freescale MPC52xx SoC internal IDE DMA"
+	depends on PATA_MPC52xx
+	help
+	  This option enables support for DMA on the MPC52xx SoC PATA
+	  controller.
+
+	  If unsure, say N.
+
 config PATA_MPIIX
 	tristate "Intel PATA MPIIX support"
 	depends on PCI
diff -Nurp linux-2.6.26-rc6/drivers/ata/pata_mpc52xx.c linux-2.6.26-rc6.new/drivers/ata/pata_mpc52xx.c
--- linux-2.6.26-rc6/drivers/ata/pata_mpc52xx.c	2008-03-18 15:49:33.000000000 +0000
+++ linux-2.6.26-rc6.new/drivers/ata/pata_mpc52xx.c	2008-04-15 10:41:49.000000000 +0100
@@ -6,6 +6,9 @@
  * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
  * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
  *
+ * UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
+ * Domen Puncer and Tim Yamin.
+ *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
  * kind, whether express or implied.
@@ -17,28 +20,47 @@
 #include <linux/delay.h>
 #include <linux/libata.h>
 
+#include <asm/cacheflush.h>
 #include <asm/types.h>
 #include <asm/prom.h>
 #include <asm/of_platform.h>
 #include <asm/mpc52xx.h>
 
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/bestcomm_priv.h>
+#include <sysdev/bestcomm/ata.h>
 
 #define DRV_NAME	"mpc52xx_ata"
 #define DRV_VERSION	"0.1.2"
 
-
 /* Private structures used by the driver */
 struct mpc52xx_ata_timings {
 	u32	pio1;
 	u32	pio2;
+	u32	mdma1;
+	u32	mdma2;
+	u32	udma1;
+	u32	udma2;
+	u32	udma3;
+	u32	udma4;
+	u32	udma5;
+	int	using_udma;
 };
 
 struct mpc52xx_ata_priv {
 	unsigned int			ipb_period;
 	struct mpc52xx_ata __iomem *	ata_regs;
+	struct mpc52xx_ata __iomem *	ata_regs_pa;
 	int				ata_irq;
 	struct mpc52xx_ata_timings	timings[2];
 	int				csel;
+
+	/* DMA */
+	struct bcom_task *		dmatsk;
+	const struct udmaspec *		udmaspec;
+	const struct mdmaspec *		mdmaspec;
+	int 				mpc52xx_ata_dma_last_write;
+	int				waiting_for_dma;
 };
 
 
@@ -53,6 +75,102 @@
 
 #define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
 
+/* ATAPI-4 MDMA specs (in clocks) */
+struct mdmaspec {
+	u32 t0M[3];
+	u32 td[3];
+	u32 th[3];
+	u32 tj[3];
+	u32 tkw[3];
+	u32 tm[3];
+	u32 tn[3];
+};
+
+// -----------------------------------------------------------------------------------------------
+
+static const struct mdmaspec mdmaspec66 = {
+	{32,  10,  8},
+	{15,  6,   5},
+	{2,   1,   1},
+	{2,   1,   1},
+	{15,  4,   2},
+	{4,   2,   2},
+	{1,   1,   1}
+};
+
+static const struct mdmaspec mdmaspec132 = {
+	{64,  20,  16},
+	{29,  11,  10},
+	{3,   2,   2},
+	{3,   1,   1},
+	{29,  7,   4},
+	{7,   4,   4},
+	{2,   1,   1}
+};
+
+
+/* ATAPI-4 UDMA specs (in clocks) */
+struct udmaspec {
+	u32 tcyc[6];
+	u32 t2cyc[6];
+	u32 tds[6];
+	u32 tdh[6];
+	u32 tdvs[6];
+	u32 tdvh[6];
+	u32 tfs_min[6];
+	u32 tli_max[6];
+	u32 tmli[6];
+	u32 taz[6];
+	u32 tzah[6];
+	u32 tenv_min[6];
+	u32 tsr[6];
+	u32 trfs[6];
+	u32 trp[6];
+	u32 tack[6];
+	u32 tss[6];
+};
+
+static const struct udmaspec udmaspec66 = {
+	{ 8,  5,  4,  3,  2,  2},
+	{16, 11,  8,  6,  4 , 2},
+	{ 1,  1,  1,  1,  1,  1},
+	{ 1,  1,  1,  1,  1,  1},
+	{ 5,  4,  3,  2,  1,  1},
+	{ 1,  1,  1,  1,  1,  1},
+	{16, 14, 12,  9,  8,  6},
+	{10, 10, 10,  7,  8,  5},
+	{ 2,  2,  2,  2,  2,  2},
+	{ 1,  1,  1,  1,  1,  1},
+	{ 2,  2,  2,  2,  2,  2},
+	{ 2,  2,  2,  2,  2,  2},
+	{ 3,  2,  2,  2,  2,  2},
+	{ 5,  5,  4,  4,  4,  4},
+	{11,  9,  7,  7,  7,  6},
+	{ 2,  2,  2,  2,  2,  2},
+	{ 4,  4,  4,  4,  4,  4}
+};
+
+static const struct udmaspec udmaspec132 = {
+	{15, 10,  6,  7,  2,  3},
+	{31, 21, 12, 12,  5,  6},
+	{ 2,  2,  1,  1,  0,  1},
+	{ 1,  1,  1,  1,  0,  1},
+	{10,  7,  5,  3,  1,  1},
+	{ 1,  1,  1,  1,  1,  1},
+	{30, 27, 23, 15, 16, 12},
+	{20, 20, 20, 13, 14, 10},
+	{ 3,  3,  3,  3,  2,  3},
+	{ 2,  2,  2,  2,  1,  2},
+	{ 3,  3,  3,  3,  2,  3},
+	{ 3,  3,  3,  3,  2,  3},
+	{ 7,  4,  3,  3,  2,  3},
+	{10, 10,  8,  8,  7,  7},
+	{22, 17, 14, 14, 13, 12},
+	{ 3,  3,  3,  3,  2,  3},
+	{ 7,  7,  7,  7,  6,  7},
+};
+
+// -----------------------------------------------------------------------------------------------
 
 /* Bit definitions inside the registers */
 #define MPC52xx_ATA_HOSTCONF_SMR	0x80000000UL /* State machine reset */
@@ -75,6 +193,8 @@
 #define MPC52xx_ATA_DMAMODE_FR		0x20 /* FIFO Reset */
 #define MPC52xx_ATA_DMAMODE_HUT		0x40 /* Host UDMA burst terminate */
 
+#define MAX_DMA_BUFFERS 128
+#define MAX_DMA_BUFFER_SIZE 0x20000u
 
 /* Structure of the hardware registers */
 struct mpc52xx_ata {
@@ -133,6 +253,9 @@
 	u8  reserved21[2];
 };
 
+/* BestComm locking */
+unsigned long pata_mpc52xx_ata_dma_lock = 0;
+struct bcom_task_2 *pata_mpc52xx_ata_dma_task;
 
 /* ======================================================================== */
 /* Aux fns                                                                  */
@@ -141,6 +264,19 @@
 
 /* MPC52xx low level hw control */
 
+static inline void
+mpc52xx_ata_wait_tip_bit_clear(struct mpc52xx_ata __iomem *regs)
+{
+	int timeout = 1000;
+
+	while (in_be32(&regs->host_status) & MPC52xx_ATA_HOSTSTAT_TIP)
+		if (timeout-- == 0) {
+			printk(KERN_ERR "mpc52xx-ide: Timeout waiting for TIP clear\n");
+			break;
+		}
+	udelay(10);     /* FIXME: Necessary ??? */
+}
+
 static int
 mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
 {
@@ -165,6 +301,95 @@
 	return 0;
 }
 
+static int
+mpc52xx_ata_compute_mdma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+	struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+	u32 t0M, td, tkw, tm, th, tj, tn;
+
+	if (speed < 0 || speed > 2)
+		return -EINVAL;
+
+	t0M = priv->mdmaspec->t0M[speed];
+	td = priv->mdmaspec->td[speed];
+	tkw = priv->mdmaspec->tkw[speed];
+	tm = priv->mdmaspec->tm[speed];
+	th = priv->mdmaspec->th[speed];
+	tj = priv->mdmaspec->tj[speed];
+	tn = priv->mdmaspec->tn[speed];
+
+	DPRINTK ("t0M = %d\n", t0M);
+	DPRINTK ("td  = %d\n", td);
+	DPRINTK ("tkw = %d\n", tkw);
+	DPRINTK ("tm  = %d\n", tm);
+	DPRINTK ("th  = %d\n", th);
+	DPRINTK ("tj  = %d\n", tj);
+	DPRINTK ("tn  = %d\n", tn);
+
+	timing->mdma1 = (t0M << 24) | (td << 16) | (tkw << 8) | (tm);
+	timing->mdma2 = (th << 24) | (tj << 16) | (tn << 8);
+
+	timing->using_udma = 0;
+
+	return 0;
+}
+
+static int
+mpc52xx_ata_compute_udma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+	struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+	u32 t2cyc, tcyc, tds, tdh, tdvs, tdvh, tfs, tli, tmli, taz, tenv, tsr, tss, trfs, trp, tack, tzah;
+
+	if (speed < 0 || speed > 2)
+		return -EINVAL;
+
+	t2cyc = priv->udmaspec->t2cyc[speed];
+	tcyc = priv->udmaspec->tcyc[speed];
+	tds = priv->udmaspec->tds[speed];
+	tdh = priv->udmaspec->tdh[speed];
+	tdvs = priv->udmaspec->tdvs[speed];
+	tdvh = priv->udmaspec->tdvh[speed];
+	tfs = priv->udmaspec->tfs_min[speed];
+	tmli = priv->udmaspec->tmli[speed];
+	tenv = priv->udmaspec->tenv_min[speed];
+	tss = priv->udmaspec->tss[speed];
+	trp = priv->udmaspec->trp[speed];
+	tack = priv->udmaspec->tack[speed];
+	tzah = priv->udmaspec->tzah[speed];
+	taz = priv->udmaspec->taz[speed];
+	trfs = priv->udmaspec->trfs[speed];
+	tsr = priv->udmaspec->tsr[speed];
+	tli = priv->udmaspec->tli_max[speed];
+
+	DPRINTK ("UDMA t2cyc = %d\n", t2cyc);
+	DPRINTK ("UDMA tcyc  = %d\n", tcyc);
+	DPRINTK ("UDMA tds   = %d\n", tds);
+	DPRINTK ("UDMA tdh   = %d\n", tdh);
+	DPRINTK ("UDMA tdvs  = %d\n", tdvs);
+	DPRINTK ("UDMA tdvh  = %d\n", tdvh);
+	DPRINTK ("UDMA tfs   = %d\n", tfs);
+	DPRINTK ("UDMA tli   = %d\n", tli);
+	DPRINTK ("UDMA tmli  = %d\n", tmli);
+	DPRINTK ("UDMA taz   = %d\n", taz);
+	DPRINTK ("UDMA tenv  = %d\n", tenv);
+	DPRINTK ("UDMA tsr   = %d\n", tsr);
+	DPRINTK ("UDMA tss   = %d\n", tss);
+	DPRINTK ("UDMA trfs  = %d\n", trfs);
+	DPRINTK ("UDMA trp   = %d\n", trp);
+	DPRINTK ("UDMA tack  = %d\n", tack);
+	DPRINTK ("UDMA tzah  = %d\n", tzah);
+
+	timing->udma1 = (t2cyc << 24) | (tcyc << 16) | (tds << 8) | (tdh);
+	timing->udma2 = (tdvs << 24) | (tdvh << 16) | (tfs << 8) | (tli);
+	timing->udma3 = (tmli << 24) | (taz << 16) | (tenv << 8) | (tsr);
+	timing->udma4 = (tss << 24) | (trfs << 16) | (trp << 8) | (tack);
+	timing->udma5 = (tzah << 24);
+
+	timing->using_udma = 1;
+
+	return 0;
+}
+
 static void
 mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
 {
@@ -173,14 +398,13 @@
 
 	out_be32(&regs->pio1,  timing->pio1);
 	out_be32(&regs->pio2,  timing->pio2);
-	out_be32(&regs->mdma1, 0);
-	out_be32(&regs->mdma2, 0);
-	out_be32(&regs->udma1, 0);
-	out_be32(&regs->udma2, 0);
-	out_be32(&regs->udma3, 0);
-	out_be32(&regs->udma4, 0);
-	out_be32(&regs->udma5, 0);
-
+	out_be32(&regs->mdma1, timing->mdma1);
+	out_be32(&regs->mdma2, timing->mdma2);
+	out_be32(&regs->udma1, timing->udma1);
+	out_be32(&regs->udma2, timing->udma2);
+	out_be32(&regs->udma3, timing->udma3);
+	out_be32(&regs->udma4, timing->udma4);
+	out_be32(&regs->udma5, timing->udma5);
 	priv->csel = device;
 }
 
@@ -245,6 +469,28 @@
 	mpc52xx_ata_apply_timings(priv, adev->devno);
 }
 static void
+mpc52xx_ata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	int rv;
+
+	if (adev->dma_mode >= XFER_UDMA_0) {
+		int dma = adev->dma_mode - XFER_UDMA_0;
+		rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma);
+	} else {
+		int dma = adev->dma_mode - XFER_MW_DMA_0;
+		rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma);
+	}
+
+	if (rv) {
+		printk(KERN_ERR DRV_NAME
+			": Trying to select invalid DMA mode %d\n", adev->dma_mode);
+		return;
+	}
+
+	mpc52xx_ata_apply_timings(priv, adev->devno);
+}
+static void
 mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
 {
 	struct mpc52xx_ata_priv *priv = ap->host->private_data;
@@ -255,16 +501,192 @@
 	ata_sff_dev_select(ap,device);
 }
 
+static void
+mpc52xx_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+	mpc52xx_ata_wait_tip_bit_clear(priv->ata_regs);
+	ata_sff_exec_command(ap, tf);
+}
+
+static int
+mpc52xx_ata_build_dmatable(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	struct mpc52xx_ata __iomem *regs_pa = priv->ata_regs_pa;
+	unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE), si;
+	struct scatterlist *sg;
+	int count = 0;
+
+	if (read)
+		bcom_ata_rx_prepare(priv->dmatsk);
+	else
+		bcom_ata_tx_prepare(priv->dmatsk);
+
+	for_each_sg(qc->sg, sg, qc->n_elem, si) {
+		u32 cur_addr = sg_dma_address(sg);
+		u32 cur_len = sg_dma_len(sg);
+
+		while (cur_len) {
+			unsigned int tc = min(cur_len, MAX_DMA_BUFFER_SIZE);
+			struct bcom_ata_bd *bd = (struct bcom_ata_bd *) bcom_prepare_next_buffer_2((struct bcom_task_2 *) priv->dmatsk);
+
+			if (read) {
+				bd->status = tc;
+				bd->src_pa = (__force u32) &regs_pa->fifo_data;
+				bd->dst_pa = cur_addr;
+
+				invalidate_dcache_range((__force u32) phys_to_virt(cur_addr), (__force u32) phys_to_virt(cur_addr) + (__force u32) cur_len);
+			} else {
+				bd->status = tc;
+				bd->src_pa = cur_addr;
+				bd->dst_pa = (__force u32) &regs_pa->fifo_data;
+
+				flush_dcache_range((__force u32) phys_to_virt(cur_addr), (__force u32) phys_to_virt(cur_addr) + (__force u32) cur_len);
+			}
+
+			bcom_submit_next_buffer_2((struct bcom_task_2 *) priv->dmatsk, NULL);
+
+			cur_addr += tc;
+			cur_len -= tc;
+			count++;
+
+			if (count == MAX_DMA_BUFFERS) {
+				printk(KERN_ALERT "%s: %i dma table too small\n", __func__, __LINE__);
+				goto use_pio_instead;
+			}
+		}
+	}
+	return 1;
+
+use_pio_instead:
+	bcom_ata_reset_bd(priv->dmatsk);
+
+	return 0;
+}
+
+static void
+mpc52xx_bmdma_setup(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+
+	unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
+	u8 dma_mode;
+
+	if (!mpc52xx_ata_build_dmatable(qc)) {
+		printk(KERN_ALERT "%s: %i, return 1?\n", __func__, __LINE__);
+	}
+
+	if (read) {
+		dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_READ |
+				MPC52xx_ATA_DMAMODE_FE;
+
+		/* Setup FIFO if direction changed */
+		if (priv->mpc52xx_ata_dma_last_write != 0) {
+			priv->mpc52xx_ata_dma_last_write = 0;
+			mpc52xx_ata_wait_tip_bit_clear(regs);
+
+			/* Configure FIFO with granularity to 7 like sample code */
+			out_8(&regs->fifo_control, 7);
+			out_be16(&regs->fifo_alarm, 128);
+
+			/* Set FIFO Reset bit (FR) */
+			out_8(&regs->dma_mode, MPC52xx_ATA_DMAMODE_FR);
+		}
+	} else {
+		dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_WRITE;
+
+		/* Setup FIFO if direction changed */
+		if (priv->mpc52xx_ata_dma_last_write != 1) {
+			priv->mpc52xx_ata_dma_last_write = 1;
+			mpc52xx_ata_wait_tip_bit_clear(regs);
+
+			/* Configure FIFO with granularity to 4 like sample code */
+			out_8(&regs->fifo_control, 4);
+			out_be16(&regs->fifo_alarm, 128);
+		}
+	}
+
+	if (priv->timings[qc->dev->devno].using_udma)
+		dma_mode |= MPC52xx_ATA_DMAMODE_UDMA;
+
+	mpc52xx_ata_wait_tip_bit_clear(regs);
+	out_8(&regs->dma_mode, dma_mode);
+
+	priv->waiting_for_dma = ATA_DMA_ACTIVE;
+
+	ata_wait_idle(ap);
+	ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+static void
+mpc52xx_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+	/* LocalBus lock */
+	while (test_and_set_bit(0, &pata_mpc52xx_ata_dma_lock) != 0)
+		;
+
+	bcom_set_task_auto_start(priv->dmatsk->tasknum, priv->dmatsk->tasknum | 0x40);
+	bcom_enable(priv->dmatsk);
+}
+
+static void
+mpc52xx_bmdma_stop(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+	bcom_disable(priv->dmatsk);
+	bcom_ata_reset_bd(priv->dmatsk);
+
+	/* LocalBus unlock*/
+	clear_bit(0, &pata_mpc52xx_ata_dma_lock);
+
+	priv->waiting_for_dma = 0;
+}
+
+static u8
+mpc52xx_bmdma_status(struct ata_port *ap)
+{
+	struct mpc52xx_ata_priv *priv = ap->host->private_data;
+	return priv->waiting_for_dma;
+}
+
+static irqreturn_t
+mpc52xx_ata_task_irq(int irq, void *vpriv)
+{
+	struct mpc52xx_ata_priv *priv = vpriv;
+	priv->waiting_for_dma |= ATA_DMA_INTR;
+
+	return IRQ_HANDLED;
+}
+
 static struct scsi_host_template mpc52xx_ata_sht = {
 	ATA_PIO_SHT(DRV_NAME),
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
 	.inherits		= &ata_sff_port_ops,
-	.sff_dev_select		= mpc52xx_ata_dev_select,
-	.cable_detect		= ata_cable_40wire,
+
 	.set_piomode		= mpc52xx_ata_set_piomode,
-	.post_internal_cmd	= ATA_OP_NULL,
+	.set_dmamode		= mpc52xx_ata_set_dmamode,
+
+	.sff_exec_command	= mpc52xx_sff_exec_command,
+	.sff_dev_select		= mpc52xx_ata_dev_select,
+
+	.bmdma_setup		= mpc52xx_bmdma_setup,
+	.bmdma_start		= mpc52xx_bmdma_start,
+	.bmdma_stop		= mpc52xx_bmdma_stop,
+	.bmdma_status		= mpc52xx_bmdma_status,
+
+	.qc_prep		= ata_noop_qc_prep,
 };
 
 static int __devinit
@@ -281,9 +703,14 @@
 
 	ap = host->ports[0];
 	ap->flags		|= ATA_FLAG_SLAVE_POSS;
-	ap->pio_mask		= 0x1f;	/* Up to PIO4 */
-	ap->mwdma_mask		= 0x00;	/* No MWDMA   */
-	ap->udma_mask		= 0x00;	/* No UDMA    */
+	ap->pio_mask		= ATA_PIO4;	/* Up to PIO4 */
+#ifdef CONFIG_PATA_MPC52xx_DMA
+	ap->mwdma_mask		= 0x07;		/* Up to MWDMA2 */
+	ap->udma_mask		= ATA_UDMA2;	/* Up to UDMA2 */
+#else
+	ap->mwdma_mask		= 0x00;		/* No MWDMA */
+	ap->udma_mask		= 0x00;		/* No UDMA */
+#endif
 	ap->ops			= &mpc52xx_ata_port_ops;
 	host->private_data	= priv;
 
@@ -333,7 +760,7 @@
 	int ata_irq;
 	struct mpc52xx_ata __iomem *ata_regs;
 	struct mpc52xx_ata_priv *priv;
-	int rv;
+	int rv, ret, task_irq;
 
 	/* Get ipb frequency */
 	ipb_freq = mpc52xx_find_ipb_freq(op->node);
@@ -389,8 +816,31 @@
 
 	priv->ipb_period = 1000000000 / (ipb_freq / 1000);
 	priv->ata_regs = ata_regs;
+	priv->ata_regs_pa = (struct mpc52xx_ata __iomem *) res_mem.start;
 	priv->ata_irq = ata_irq;
 	priv->csel = -1;
+	priv->mpc52xx_ata_dma_last_write = -1;
+
+	if (ipb_freq/1000000 == 66) {
+		priv->mdmaspec = &mdmaspec66;
+		priv->udmaspec = &udmaspec66;
+	} else {
+		priv->mdmaspec = &mdmaspec132;
+		priv->udmaspec = &udmaspec132;
+	}
+
+	priv->dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
+	pata_mpc52xx_ata_dma_task = (struct bcom_task_2 *) priv->dmatsk;
+	if (!priv->dmatsk) {
+		printk(KERN_ALERT "%s: %i\n", __func__, __LINE__);
+		rv = -ENOMEM;
+		goto err;
+	}
+
+	task_irq = bcom_get_task_irq(priv->dmatsk);
+	ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED, "ATA task", priv);
+	if (ret)
+		printk(KERN_ALERT "%s: request_irq failed with: %i\n", __func__, ret);
 
 	/* Init the hw */
 	rv = mpc52xx_ata_hw_init(priv);

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

end of thread, other threads:[~2009-07-09 14:24 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <AclPDG6qSkF9cHawTOKR6zBfDIjvgg==>
2008-11-25 14:45 ` AW: [PATCH]: [MPC5200] Add ATA DMA support Lehmann, Hans (Ritter Elektronik)
2008-11-25 15:19   ` Matt Sealey
2008-11-25 15:35     ` AW: " Lehmann, Hans (Ritter Elektronik)
2008-12-20  7:15     ` Grant Likely
2008-12-20  7:18   ` Grant Likely
2009-01-05  9:25     ` AW: " Lehmann, Hans (Ritter Elektronik)
2009-01-05 15:31       ` Grant Likely
2009-07-09 14:24         ` Roman Fietze
2008-09-05 18:29 WITTROCK
     [not found] <DD39B5C3F4963040ADC9768BE7E430CB03202F4F@is-hdq-exchange.marel.net>
     [not found] ` <DD39B5C3F4963040ADC9768BE7E430CB03203863@is-hdq-exchange.marel.net>
     [not found]   ` <792f5f410808111319m20d6e09bi8e9782da1fdd4aab@mail.gmail.com>
     [not found]     ` <DD39B5C3F4963040ADC9768BE7E430CB0320387D@is-hdq-exchange.marel.net>
     [not found]       ` <792f5f410808111431g8fafba1n3b10468da0d165bf@mail.gmail.com>
     [not found]         ` <DD39B5C3F4963040ADC9768BE7E430CB03203A7B@is-hdq-exchange.marel.net>
     [not found]           ` <792f5f410808120643md72e679o39692c4bfa3f285e@mail.gmail.com>
     [not found]             ` <DD39B5C3F4963040ADC9768BE7E430CB03203A94@is-hdq-exchange.marel.net>
     [not found]               ` <792f5f410808120730j7b4be4f2n7a40de880178ccca@mail.gmail.com>
     [not found]                 ` <DD39B5C3F4963040ADC9768BE7E430CB03203ADC@is-hdq-exchange.marel.net>
     [not found]                   ` <792f5f410808120830v311e0446kc8fddfb97d0b9ea6@mail.gmail.com>
2008-08-12 17:30                     ` Daniel Schnell
2008-08-13  5:57                       ` Tim Yamin
2008-08-13  6:02                         ` Grant Likely
2008-08-13  6:06                           ` Tim Yamin
2008-08-13  6:11                             ` Grant Likely
2008-08-13  9:07                               ` Tim Yamin
2008-09-15  5:54                                 ` Grant Likely
2008-10-29 15:34                                   ` Matt Sealey
2008-11-11 14:04                                 ` Lehmann, Hans (Ritter Elektronik)
2008-11-11 14:35                                   ` Matt Sealey
  -- strict thread matches above, loose matches on Subject: below --
2008-06-17  8:28 Tim Yamin
2008-08-06 11:58 ` Daniel Schnell
2008-08-06 12:18   ` Tim Yamin
2008-08-06 13:26     ` Daniel Schnell
2008-08-06 14:31       ` Daniel Schnell

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).