Re: [PATCH 2/2] powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver

2008-11-14 Thread Jeff Garzik

ACK


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH 2/2] powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver

2008-11-12 Thread Grant Likely
From: 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.

With this patch, a SanDisk Extreme IV CF card gets read speeds of
approximately 26.70 MB/sec.

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

 arch/powerpc/sysdev/bestcomm/ata.c   |3 
 arch/powerpc/sysdev/bestcomm/bestcomm.c  |7 
 arch/powerpc/sysdev/bestcomm/bestcomm_priv.h |   16 +
 drivers/ata/pata_mpc52xx.c   |  440 +-
 4 files changed, 443 insertions(+), 23 deletions(-)


diff --git a/arch/powerpc/sysdev/bestcomm/ata.c 
b/arch/powerpc/sysdev/bestcomm/ata.c
index 1f5258f..901c9f9 100644
--- a/arch/powerpc/sysdev/bestcomm/ata.c
+++ b/arch/powerpc/sysdev/bestcomm/ata.c
@@ -61,6 +61,9 @@ bcom_ata_init(int queue_len, int maxbufsize)
struct bcom_ata_var *var;
struct bcom_ata_inc *inc;
 
+   /* Prefetch breaks ATA DMA.  Turn it off for ATA DMA */
+   bcom_disable_prefetch();
+
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0);
if (!tsk)
return NULL;
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c 
b/arch/powerpc/sysdev/bestcomm/bestcomm.c
index 446c9ea..378ebd9 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.c
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c
@@ -279,7 +279,6 @@ bcom_engine_init(void)
int task;
phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
unsigned int tdt_size, ctx_size, var_size, fdt_size;
-   u16 regval;
 
/* Allocate  clear SRAM zones for FDT, TDTs, contexts and vars/incs */
tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
@@ -331,10 +330,8 @@ bcom_engine_init(void)
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);
-   }
+   if ((mfspr(SPRN_SVR)  MPC5200_SVR_MASK) == MPC5200_SVR)
+   bcom_disable_prefetch();
 
/* Init lock */
spin_lock_init(bcom_eng-lock);
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h 
b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
index 746f155..eb0d1c8 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
@@ -241,6 +241,22 @@ extern void bcom_set_initiator(int task, int initiator);
 
 #define TASK_ENABLE 0x8000
 
+/**
+ * bcom_disable_prefetch - Hook to disable bus prefetching
+ *
+ * ATA DMA and the original MPC5200 need this due to silicon bugs.  At the
+ * moment disabling prefetch is a one-way street.  There is no mechanism
+ * in place to turn prefetch back on after it has been disabled.  There is
+ * no reason it couldn't be done, it would just be more complex to implement.
+ */
+static inline void bcom_disable_prefetch(void)
+{
+   u16 regval;
+
+   regval = in_be16(bcom_eng-regs-PtdCntrl);
+   out_be16(bcom_eng-regs-PtdCntrl, regval | 1);
+};
+
 static inline void
 bcom_enable_task(int task)
 {
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index a9e8273..09b7fbb 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -6,6 +6,9 @@
  * Copyright (C) 2006 Sylvain Munaut [EMAIL PROTECTED]
  * 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.
@@ -18,27 +21,46 @@
 #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_VERSION0.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 intipb_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;
+