* PPC4XX DMA polarity bug in linuxppc-2.6.9
@ 2004-12-09 10:13 Colin Wernham
2004-12-13 9:48 ` Mark Powell
0 siblings, 1 reply; 5+ messages in thread
From: Colin Wernham @ 2004-12-09 10:13 UTC (permalink / raw)
To: linuxppc-dev
I believe that there is a PPC4xx DMA driver bug in the following kernel,
file and function:
linuxppc-2.6.9,
/arch/ppc/syslib/ppc4xx_dma.c,
ppc4xx_init_dma_channel()
Symptoms are:
DMA does not work as the polarity bits (DMA Req, Ack, EOT) are not set
correctly in the DMA controller using the ppc4xx_init_dma_channel()
function call, but when this is called twice in succession, then it does
work.
Cause is (I believe):
/arch/ppc/syslib/ppc4xx_dma.c:
On line 469 the old polarity bits in p_dma_ch are ORed in when it should
be ORing in the new polarity bits from p_init. p_init is then saved into
p_dma_ch. This means that it only gets correctly programmed when the
function is called twice:
467 /* clear all polarity signals and then "or" in new signal levels */
468 polarity &= ~GET_DMA_POLARITY(dmanr);
469 polarity |= p_dma_ch->polarity;
Fix could be:
469 polarity |= p_init->polarity;
Is there anyone else using the PPC4XX DMA?
Colin Wernham
^ permalink raw reply [flat|nested] 5+ messages in thread
* PPC4XX DMA polarity bug in linuxppc-2.6.9
@ 2004-12-10 9:09 Colin Wernham
2004-12-10 17:09 ` Matt Porter
0 siblings, 1 reply; 5+ messages in thread
From: Colin Wernham @ 2004-12-10 9:09 UTC (permalink / raw)
To: linuxppc-embedded
[a copy of this has also been posted on linuxppc-dev]
I believe that there is a PPC4xx DMA driver bug in the following kernel, =
file and function:
linuxppc-2.6.9,
/arch/ppc/syslib/ppc4xx_dma.c,
ppc4xx_init_dma_channel()
Symptoms are:
DMA does not work as the polarity bits (DMA Req, Ack, EOT) are not set=20
correctly in the DMA controller using the ppc4xx_init_dma_channel()=20
function call, but when this is called twice in succession, then it does =
work.
Cause is (I believe):
/arch/ppc/syslib/ppc4xx_dma.c:
On line 469 the old polarity bits in p_dma_ch are ORed in when it should =
be ORing in the new polarity bits from p_init. p_init is then saved into =
p_dma_ch. This means that it only gets correctly programmed when the=20
function is called twice:
467 /* clear all polarity signals and then "or" in new signal =
levels */
468 polarity &=3D ~GET_DMA_POLARITY(dmanr);
469 polarity |=3D p_dma_ch->polarity;
Fix should be:
469 polarity |=3D p_init->polarity;
Is there anyone else using the PPC4XX DMA?
Colin Wernham
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PPC4XX DMA polarity bug in linuxppc-2.6.9
2004-12-10 9:09 PPC4XX DMA polarity bug in linuxppc-2.6.9 Colin Wernham
@ 2004-12-10 17:09 ` Matt Porter
2004-12-10 17:22 ` Stephen Williams
0 siblings, 1 reply; 5+ messages in thread
From: Matt Porter @ 2004-12-10 17:09 UTC (permalink / raw)
To: Colin Wernham; +Cc: linuxppc-embedded
On Fri, Dec 10, 2004 at 09:09:39AM -0000, Colin Wernham wrote:
> I believe that there is a PPC4xx DMA driver bug in the following kernel,
<snip>
> Cause is (I believe):
> /arch/ppc/syslib/ppc4xx_dma.c:
> On line 469 the old polarity bits in p_dma_ch are ORed in when it should
> be ORing in the new polarity bits from p_init. p_init is then saved into
> p_dma_ch. This means that it only gets correctly programmed when the
> function is called twice:
>
> 467 /* clear all polarity signals and then "or" in new signal levels */
> 468 polarity &= ~GET_DMA_POLARITY(dmanr);
> 469 polarity |= p_dma_ch->polarity;
>
> Fix should be:
> 469 polarity |= p_init->polarity;
Yes, that's a real bug. Can you make a patch according to
Documentation/SubmittingPatches, add your signed off line, and
send to me or this list? This clear bug fix should go in
before 2.6.10.
> Is there anyone else using the PPC4XX DMA?
Yes, I've used this library code for simple memory<->memory DMA
tests to verify that programmed and SG mode work. For more common
setups like peripheral driven DMA from the EBC, I've simply programmed
the DMA engine directly. This library doesn't seem to simplify anything
for me in those cases (it's just a thin wrapper around registers) so
I find it easier to program the DMA engine regs directly within the
driver that is making use of a channel. I've been keeping it around
since apparently a lot of people make use of it in hopes that
somebody might take the time to improve it.
Since the my apps that would exercise the polarity bits in the
init code don't use this library, I guess that's why I've never
run into this problem. :)
-Matt
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PPC4XX DMA polarity bug in linuxppc-2.6.9
2004-12-10 17:09 ` Matt Porter
@ 2004-12-10 17:22 ` Stephen Williams
0 siblings, 0 replies; 5+ messages in thread
From: Stephen Williams @ 2004-12-10 17:22 UTC (permalink / raw)
To: Matt Porter; +Cc: Colin Wernham, linuxppc-embedded
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Matt Porter wrote:
| On Fri, Dec 10, 2004 at 09:09:39AM -0000, Colin Wernham wrote:
|>Is there anyone else using the PPC4XX DMA?
|
|
| Yes, I've used this library code for simple memory<->memory DMA
| tests to verify that programmed and SG mode work. For more common
| setups like peripheral driven DMA from the EBC, I've simply programmed
| the DMA engine directly. This library doesn't seem to simplify anything
| for me in those cases (it's just a thin wrapper around registers) so
| I find it easier to program the DMA engine regs directly within the
| driver that is making use of a channel. I've been keeping it around
| since apparently a lot of people make use of it in hopes that
| somebody might take the time to improve it.
I found the library as thin and undocumented, and didn't seem to
actually solve any problems. Certainly not mine. So I wrote my
own.
I haven't isolated it into its own module yet, as I got to the point
where it's working for my client driver, and didn't submit it as
there is some driver for some oddball hardware that seems to use
the existing library, and this would clash.
Here's the header file for my functions, in case this piques any
interest.
/*
~ * Copyright (c) 2004 Picture Elements, Inc.
~ * Stephen Williams (steve@icarus.com)
~ *
~ * This source code is free software; you can redistribute it
~ * and/or modify it in source code form under the terms of the GNU
~ * General Public License as published by the Free Software
~ * Foundation; either version 2 of the License, or (at your option)
~ * any later version.
~ *
~ * This program is distributed in the hope that it will be useful,
~ * but WITHOUT ANY WARRANTY; without even the implied warranty of
~ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ * GNU General Public License for more details.
~ *
~ * You should have received a copy of the GNU General Public License
~ * along with this program; if not, write to the Free Software
~ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
~ */
#ident "$Id: jsedma.h,v 1.3 2004/08/09 19:04:07 steve Exp $"
# include <linux/module.h>
# include <linux/kernel.h>
# include <asm/uaccess.h>
/*
~ * This module provides a reuseable interface to IBM PPC405GP(r) DMA
~ * controllers. It allows clients to request a suitable controller, to
~ * set up an operation, and see the transaction through. The general
~ * order of events is to:
~ *
~ * map your user data with the map_user_kiobuf function.
~ *
~ * Use jsedma_chain_from_kiobuf to turn that map into a string of DMA
~ * chain cells.
~ *
~ * Select a DMA controller to use with jsedma_alloc_controller().
~ *
~ * Start the operation with jsedma_start_chain(...)
~ *
~ * Wait for it to finish with jsedma_wait_interruptible(...)
~ *
~ * Then release everything when done.
~ */
/*
~ * Allocate an available DMA controller that has been set up for
~ * memory-to-memory transfers. There may be as many as 4 of
~ * these. The return value is >= 0 if a controller is allocated, or <0
~ * on error.
~ *
~ * When done, release the controller.
~ */
extern int jsedma_alloc_controller(void);
extern void jsedma_free_controller(int dmanr);
/*
~ * Allocate a DMA chain based on the mapped kiobuf. Free the chain
~ * when the DMA in use is completed. This may allocate consistent
~ * pages, so be careful where you use it. Free the chain when you are
~ * done with it.
~ *
~ * The direction is either PCI_DMA_TODEVICE or PCI_DMA_FROMDEVICE.
~ *
~ * WARNING: Just like with pci_map_single, the memory of the iobuf
~ * should not be touched between the creation of this chain and the
~ * completion of the transfer. This function flushes caches (if
~ * needed) so if you touch buffers during the transfer, data can be
~ * lost.
~ *
~ * The jsedma_chain is an opaque type.
~ */
extern struct jsedma_chain* jsedma_chain_from_kiobuf(phys_addr_t dest,
struct kiobuf*iobuf,
int direction);
extern void jsedma_chain_free(struct jsedma_chain*chp);
/*
~ * Start a DMA of the chain on the specified DMA controller. The
~ * controller should be allocated, and the target address mapped.
~ */
extern int jsedma_start_chain(int dmanr, struct jsedma_chain*chn);
/*
~ * Wait for the channel to be done. When it is done, this function
~ * returns 0. If there is an error, or the wait is interrupted, return
~ * an error code <0.
~ */
extern int jsedma_wait_interruptible(int dmanr);
/*
~ * $Log: jsedma.h,v $
~ * Revision 1.3 2004/08/09 19:04:07 steve
~ * Use DMA controller to read from frame memory.
~ *
~ * Revision 1.2 2004/05/05 17:39:51 steve
~ * Make sure caching does not get in the way of transfer.
~ *
~ * Revision 1.1 2004/04/17 02:20:42 steve
~ * Make frame output use PPC DMA controllers.
~ *
~ */
- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFBudtprPt1Sc2b3ikRAn2VAJ9zFcfBN5/lBgs/iV++OwQuSwuFGQCgp9CC
c+1dmQF0GoZcuslUCPn23oU=
=cUut
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PPC4XX DMA polarity bug in linuxppc-2.6.9
2004-12-09 10:13 Colin Wernham
@ 2004-12-13 9:48 ` Mark Powell
0 siblings, 0 replies; 5+ messages in thread
From: Mark Powell @ 2004-12-13 9:48 UTC (permalink / raw)
To: cwernham; +Cc: linuxppc-dev
Colin Wernham wrote:
> I believe that there is a PPC4xx DMA driver bug in the following
> kernel, file and function:
> linuxppc-2.6.9,
> /arch/ppc/syslib/ppc4xx_dma.c,
> ppc4xx_init_dma_channel()
>
>
> Is there anyone else using the PPC4XX DMA?
FWIW
I have used the PPC4xx dma on 405GP systems and a 440GP system with
2.4.21 and 2.4.25. I found the ppc4xx_dma.c functions didn't work in the
way I needed. I just read the code very carefully and used a few of the
functions combined with some direct manipulation of the DMA registers.
As I recall, I don't think the polarity is the only problem in that
file. It certainly doesn't support the 440 DMA registers - the COUNT
register is different.
The code in ppc4xx_dma.c is however, very useful as a guide in how to go
about setting up a DMA transfer; just read it carefully with the
processor manual to hand.
--
Mark Powell, Senior Software Engineer
Curtiss-Wright Controls Embedded Computing
Tel: +44 (0) 1763 852222
Email: medp@primagraphics.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-12-13 9:55 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-10 9:09 PPC4XX DMA polarity bug in linuxppc-2.6.9 Colin Wernham
2004-12-10 17:09 ` Matt Porter
2004-12-10 17:22 ` Stephen Williams
-- strict thread matches above, loose matches on Subject: below --
2004-12-09 10:13 Colin Wernham
2004-12-13 9:48 ` Mark Powell
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).