Re: [PATCH]: [MPC5200] Add ATA DMA support

2008-08-13 Thread Tim Yamin
On Wed, Aug 13, 2008 at 7:02 AM, Grant Likely [EMAIL PROTECTED] 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
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH]: [MPC5200] Add ATA DMA support

2008-08-13 Thread Tim Yamin
On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely [EMAIL PROTECTED] 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
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 [EMAIL PROTECTED]

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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h	2008-07-03 16:17:05.0 +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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-07-03 16:17:05.0 +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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h	2008-07-03 16:17:05.0 +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
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 [EMAIL PROTECTED]

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

Re: [PATCH]: [MPC5200] Add ATA DMA support

2008-08-12 Thread Tim Yamin
On Tue, Aug 12, 2008 at 6:30 PM, Daniel Schnell
[EMAIL PROTECTED] 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
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH]: [MPC5200] Add ATA DMA support

2008-08-06 Thread Tim Yamin
On Wed, Aug 6, 2008 at 12:58 PM, Daniel Schnell
[EMAIL PROTECTED] 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
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH]: [MPC5200] (v2) Add ATA DMA support

2008-07-03 Thread Tim Yamin
On Wed, Jul 2, 2008 at 6:30 PM, Grant Likely [EMAIL PROTECTED] wrote:
 I know that only ATA uses this; but it is nice to have fixes to things
 that are obviously wrong in existing code to be split into their own
 patches.  That way, even if the ATA patch gets backed out, the bug fix
 will remain.

Ok, so I've split the patch up into two pieces now...

 +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)
 + ;

 Need to be able to bail on timeout.

A deadlock can't occur within the PATA driver because you won't have
two DMA requests happening at once, so there is no point in adding a
timeout. And even if you do have a timeout, you'd have to drop the I/O
request somehow, so it's not really a good idea. If anything else
needs to touch the DMA lock, it should do so in a sensible fashion...

Thanks,

Tim
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 [EMAIL PROTECTED]

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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h	2008-07-03 16:17:05.0 +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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-07-03 16:17:05.0 +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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h	2008-07-03 16:17:05.0 +0100
@@ -198,8 +198,8 @@ struct bcom_task_header {
 #define BCOM_IPR_SCTMR_1	2
 #define BCOM_IPR_FEC_RX		6
 #define

Re: [PATCH] powerpc/mpc5200: Fix lite5200b suspend/resume

2008-07-02 Thread Tim Yamin
Hi Grant,

This patch works fine for me.

Cheers,

Tim

On Tue, Jul 1, 2008 at 10:12 PM, Grant Likely [EMAIL PROTECTED] wrote:
 From: Tim Yamin [EMAIL PROTECTED]

 Suspend/resume (echo mem  /sys/power/state) does not work with
 vanilla kernels -- the system does not suspend correctly and just
 hangs. This patch fixes this so suspend/resume works:

 1) of_iomap does not map the whole 0xC000 of the MPC5200 immr so
 saving registers does not work.
 2) PCI registers need to be saved and restored.

 Signed-off-by: Tim Yamin [EMAIL PROTECTED]
 Signed-off-by: Grant Likely [EMAIL PROTECTED]
 ---

 Tim, please test this version.  I fixed a couple of bugs and want to make
 sure I haven't broken anything.  Once you ack it I'll ask Paul to pull it
 into 2.6.26.

 g.

  arch/powerpc/platforms/52xx/lite5200_pm.c |   14 +-
  1 files changed, 13 insertions(+), 1 deletions(-)

 diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c 
 b/arch/powerpc/platforms/52xx/lite5200_pm.c
 index 41c7fd9..fe92e65 100644
 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c
 +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
 @@ -14,6 +14,7 @@ static struct mpc52xx_sdma __iomem *bes;
  static struct mpc52xx_xlb __iomem *xlb;
  static struct mpc52xx_gpio __iomem *gps;
  static struct mpc52xx_gpio_wkup __iomem *gpw;
 +static void __iomem *pci;
  static void __iomem *sram;
  static const int sram_size = 0x4000;   /* 16 kBytes */
  static void __iomem *mbar;
 @@ -50,6 +51,8 @@ static int lite5200_pm_prepare(void)
{ .type = builtin, .compatible = mpc5200, }, /* efika */
{}
};
 +   u64 regaddr64 = 0;
 +   const u32 *regaddr_p;

/* deep sleep? let mpc52xx code handle that */
if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
 @@ -60,8 +63,12 @@ static int lite5200_pm_prepare(void)

/* map registers */
np = of_find_matching_node(NULL, immr_ids);
 -   mbar = of_iomap(np, 0);
 +   regaddr_p = of_get_address(np, 0, NULL, NULL);
 +   if (regaddr_p)
 +   regaddr64 = of_translate_address(np, regaddr_p);
of_node_put(np);
 +
 +   mbar = ioremap((u32) regaddr64, 0xC000);
if (!mbar) {
printk(KERN_ERR %s:%i Error mapping registers\n, __func__, 
 __LINE__);
return -ENOSYS;
 @@ -71,6 +78,7 @@ static int lite5200_pm_prepare(void)
pic = mbar + 0x500;
gps = mbar + 0xb00;
gpw = mbar + 0xc00;
 +   pci = mbar + 0xd00;
bes = mbar + 0x1200;
xlb = mbar + 0x1f00;
sram = mbar + 0x8000;
 @@ -85,6 +93,7 @@ static struct mpc52xx_sdma sbes;
  static struct mpc52xx_xlb sxlb;
  static struct mpc52xx_gpio sgps;
  static struct mpc52xx_gpio_wkup sgpw;
 +static char spci[0x200];

  static void lite5200_save_regs(void)
  {
 @@ -94,6 +103,7 @@ static void lite5200_save_regs(void)
_memcpy_fromio(sxlb, xlb, sizeof(*xlb));
_memcpy_fromio(sgps, gps, sizeof(*gps));
_memcpy_fromio(sgpw, gpw, sizeof(*gpw));
 +   _memcpy_fromio(spci, pci, 0x200);

_memcpy_fromio(saved_sram, sram, sram_size);
  }
 @@ -103,6 +113,8 @@ static void lite5200_restore_regs(void)
int i;
_memcpy_toio(sram, saved_sram, sram_size);

 +   /* PCI Configuration */
 +   _memcpy_toio(pci, spci, 0x200);

/*
 * GPIOs. Interrupt Master Enable has higher address then other
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH]: [MPC5200] (v2) Add ATA DMA support

2008-07-02 Thread Tim Yamin
Hi Grant,

Thanks for the feedback. New version is attached.

 Is this a bug fix?  If so, please put it into a separate patch.

I suppose so, yes. If Ethernet has higher priority than ATA, you can
get a deadlock if you try and download a large file over a LAN to
disk, for example. But given that nothing other than this patch uses
BestComm for ATA do you have any specific reason to split it out into
another patch?

 Good, it can be turned off.  Do you think there is any risk to existing
 ATA users with this patch applied if this is turned off?

With the new version, the only risk if this is turned off is the
change I've made to bestcomm.h. Other than that, you should get no
risk because none of the new
code is executed (mwdma_mask and udma_mask are set to 0 if the option
is turned off).

 Can you find any way to avoid this?  This could be a performance drain.

Previous code had this, so I kept it. Things do seem to work OK
without it, so I've removed it...

 Is there any way to turn on/off DMA at runtime instead of CONFIG time?

You could use libata.dma=0 to force DMA off even if it's enabled at CONFIG time.

   priv-ipb_period = 10 / (ipb_freq / 1000);
   priv-ata_regs = ata_regs;
 + priv-ata_regs_pa = (struct mpc52xx_ata __iomem *) res_mem.start;

 I'm not fond of this.  First off, it is *not* __iomem.  It is physical
 address.  It would be better to use the offset_of macro to add an offset
 to the physical base address.  Doing it this way forces you to cast and
 sidestep the compile time checks for incorrect dereferences.

I'm afraid I'm not quite sure what you have in mind here, could you
please provide a pointer?

Thanks,

Tim
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 [EMAIL PROTECTED]

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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h	2008-07-02 12:48:14.0 +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.c linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.c
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-04-17 03:49:44.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-07-02 12:48:14.0 +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.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.0 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-07-02 12:48:14.0 +0100
@@ -140,15 +140,29

[PATCH]: [MPC5200] (v2) Add ATA DMA support

2008-06-27 Thread Tim Yamin
Changes from previous version:

- Add FIFO status error checking code before a DMA transaction starts
and after it is completed.
- Fix an incorrect check in the previous patch causing spurious dma
table too small errors.

Tim
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 [EMAIL PROTECTED]

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.0 +
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/ata.h	2008-04-15 10:42:38.0 +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.0 +
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-04-15 10:42:38.0 +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.0 +
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-04-15 10:42:38.0 +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 0xul
 #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	0x4000ul
 
 /** _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

[PATCH]: [MPC5200] Add ATA DMA support

2008-06-17 Thread Tim Yamin
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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]

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.0 +
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/ata.h	2008-04-15 10:42:38.0 +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.0 +
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.c	2008-04-15 10:42:38.0 +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.0 +
+++ linux-2.6.26-rc6.new/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-04-15 10:42:38.0 +0100
@@ -17,6 +17,7 @@
 #define __BESTCOMM_H__
 
 struct bcom_bd; /* defined later

[PATCH]: [MPC5200] Fix lite5200b suspend/resume

2008-06-17 Thread Tim Yamin
Hi,

Suspend/resume (echo mem  /sys/power/state) does not work for me
with vanilla kernels -- the system does not suspend correctly and just
hangs. The attached patch fixes this so suspend/resume works:

1) of_iomap does not map the whole 0xC of the MPC5200 for me, so
saving registers does not work. Maybe this is just a bug in my DTB? Or
is this an of_iomap bug?
2) PCI registers need to be saved and restored. Would it make sense to
move struct mpc52xx_pci out of mpc52xx_pci.c and into a header?

If somebody else with a lite5200B board could do some testing this
would be appreciated as would comments on the above two issues.

Thanks,

Tim
- Current memory remapping is wrong; the remapped area does not have
  the correct length (0x100 instead of 0xC000) and the system does
  not power down properly as a result... [of_ioremap bug?]

- Make sure the PCI registers are saved and restored, this fixes a
  kernel panic for me on resume.

Signed-off-by: Tim Yamin [EMAIL PROTECTED]

--- linux-2.6.26-rc6/arch/powerpc/platforms/52xx/lite5200_pm.c~	2008-04-17 03:49:44.0 +0100
+++ linux-2.6.26-rc6/arch/powerpc/platforms/52xx/lite5200_pm.c	2008-06-16 15:40:02.0 +0100
@@ -14,6 +14,7 @@
 static struct mpc52xx_xlb __iomem *xlb;
 static struct mpc52xx_gpio __iomem *gps;
 static struct mpc52xx_gpio_wkup __iomem *gpw;
+static void __iomem *pci;
 static void __iomem *sram;
 static const int sram_size = 0x4000;	/* 16 kBytes */
 static void __iomem *mbar;
@@ -42,6 +43,9 @@
 
 static int lite5200_pm_prepare(void)
 {
+	u64 regaddr64;
+	const u32 *regaddr_p;
+
 	struct device_node *np;
 	const struct of_device_id immr_ids[] = {
 		{ .compatible = fsl,mpc5200-immr, },
@@ -60,8 +64,11 @@
 
 	/* map registers */
 	np = of_find_matching_node(NULL, immr_ids);
-	mbar = of_iomap(np, 0);
+	regaddr_p = of_get_address(np, 0, NULL, NULL);
+	regaddr64 = of_translate_address(np, regaddr_p);
 	of_node_put(np);
+
+	mbar = ioremap((u32) regaddr64, 0xC);
 	if (!mbar) {
 		printk(KERN_ERR %s:%i Error mapping registers\n, __func__, __LINE__);
 		return -ENOSYS;
@@ -71,6 +78,7 @@
 	pic = mbar + 0x500;
 	gps = mbar + 0xb00;
 	gpw = mbar + 0xc00;
+	pci = mbar + 0xd00;
 	bes = mbar + 0x1200;
 	xlb = mbar + 0x1f00;
 	sram = mbar + 0x8000;
@@ -85,6 +93,7 @@
 static struct mpc52xx_xlb sxlb;
 static struct mpc52xx_gpio sgps;
 static struct mpc52xx_gpio_wkup sgpw;
+static char spci[0x200];
 
 static void lite5200_save_regs(void)
 {
@@ -94,6 +103,7 @@
 	_memcpy_fromio(sxlb, xlb, sizeof(*xlb));
 	_memcpy_fromio(sgps, gps, sizeof(*gps));
 	_memcpy_fromio(sgpw, gpw, sizeof(*gpw));
+	_memcpy_fromio(spci, pci, 0x200);
 
 	_memcpy_fromio(saved_sram, sram, sram_size);
 }
@@ -103,6 +113,8 @@
 	int i;
 	_memcpy_toio(sram, saved_sram, sram_size);
 
+	/* PCI Configuration */
+	_memcpy_toio(pci, spci, 0x200);
 
 	/*
 	 * GPIOs. Interrupt Master Enable has higher address then other
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev