[U-Boot] [RFC/PATCH] 83xx: Add support for using the fsl_dma driver

Peter Tyser ptyser at xes-inc.com
Fri May 22 22:24:31 CEST 2009


Signed-off-by: Peter Tyser <ptyser at xes-inc.com>
---

I don't have any 83xx boards to try this on, but I verified the dma code
still works on an 86xx board.  An easy way to test this change (Ira?)
would be to enable CONFIG_FSL_DMA and CONFIG_SYS_DMA_MEMTEST after the
"85xx/86xx dma updates" and "Add optional dma transfers to mtest"
patch series have been applied.

This patch dirties up the fsl_dma code a bit and no one is currently
using the 83xx dma code, so its value is debatable.  Maybe others will
find it useful or want to include it to support the 83xx down the road.

Best,
Peter

 cpu/mpc83xx/cpu.c            |   85 ------------------------------------------
 cpu/mpc83xx/spd_sdram.c      |   40 ++------------------
 drivers/dma/fsl_dma.c        |   59 +++++++++++++++++++++-------
 include/asm-ppc/fsl_dma.h    |   36 ++++++++++++++++++
 include/asm-ppc/immap_83xx.h |   49 ++----------------------
 include/mpc83xx.h            |   16 --------
 6 files changed, 88 insertions(+), 197 deletions(-)

diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index 3b93a32..a03fcd4 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -276,91 +276,6 @@ void watchdog_reset (void)
 }
 #endif
 
-#if defined(CONFIG_DDR_ECC)
-void dma_init(void)
-{
-	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
-	volatile dma83xx_t *dma = &immap->dma;
-	volatile u32 status = swab32(dma->dmasr0);
-	volatile u32 dmamr0 = swab32(dma->dmamr0);
-
-	debug("DMA-init\n");
-
-	/* initialize DMASARn, DMADAR and DMAABCRn */
-	dma->dmadar0 = (u32)0;
-	dma->dmasar0 = (u32)0;
-	dma->dmabcr0 = 0;
-
-	__asm__ __volatile__ ("sync");
-	__asm__ __volatile__ ("isync");
-
-	/* clear CS bit */
-	dmamr0 &= ~DMA_CHANNEL_START;
-	dma->dmamr0 = swab32(dmamr0);
-	__asm__ __volatile__ ("sync");
-	__asm__ __volatile__ ("isync");
-
-	/* while the channel is busy, spin */
-	while(status & DMA_CHANNEL_BUSY) {
-		status = swab32(dma->dmasr0);
-	}
-
-	debug("DMA-init end\n");
-}
-
-uint dma_check(void)
-{
-	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
-	volatile dma83xx_t *dma = &immap->dma;
-	volatile u32 status = swab32(dma->dmasr0);
-	volatile u32 byte_count = swab32(dma->dmabcr0);
-
-	/* while the channel is busy, spin */
-	while (status & DMA_CHANNEL_BUSY) {
-		status = swab32(dma->dmasr0);
-	}
-
-	if (status & DMA_CHANNEL_TRANSFER_ERROR) {
-		printf ("DMA Error: status = %x @ %d\n", status, byte_count);
-	}
-
-	return status;
-}
-
-int dmacpy(void *dest, const void *src, size_t count)
-{
-	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
-	volatile dma83xx_t *dma = &immap->dma;
-	volatile u32 dmamr0;
-
-	/* initialize DMASARn, DMADAR and DMAABCRn */
-	dma->dmadar0 = swab32((u32)dest);
-	dma->dmasar0 = swab32((u32)src);
-	dma->dmabcr0 = swab32((u32)count);
-
-	__asm__ __volatile__ ("sync");
-	__asm__ __volatile__ ("isync");
-
-	/* init direct transfer, clear CS bit */
-	dmamr0 = (DMA_CHANNEL_TRANSFER_MODE_DIRECT |
-			DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B |
-			DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN);
-
-	dma->dmamr0 = swab32(dmamr0);
-
-	__asm__ __volatile__ ("sync");
-	__asm__ __volatile__ ("isync");
-
-	/* set CS to start DMA transfer */
-	dmamr0 |= DMA_CHANNEL_START;
-	dma->dmamr0 = swab32(dmamr0);
-	__asm__ __volatile__ ("sync");
-	__asm__ __volatile__ ("isync");
-
-	return ((int)dma_check());
-}
-#endif /*CONFIG_DDR_ECC*/
-
 /*
  * Initializes on-chip ethernet controllers.
  * to override, implement board_eth_init()
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index 12dad75..c1fbcce 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -64,13 +64,6 @@ void board_add_ram_info(int use_default)
 }
 
 #ifdef CONFIG_SPD_EEPROM
-
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
-extern void dma_init(void);
-extern uint dma_check(void);
-extern int dmacpy(void *dest, const void *src, size_t n);
-#endif
-
 #ifndef	CONFIG_SYS_READ_SPD
 #define CONFIG_SYS_READ_SPD	i2c_read
 #endif
@@ -863,7 +856,6 @@ static __inline__ unsigned long get_tbms (void)
 /*
  * Initialize all of memory for ECC, then enable errors.
  */
-/* #define CONFIG_DDR_ECC_INIT_VIA_DMA */
 void ddr_enable_ecc(unsigned int dram_size)
 {
 	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
@@ -872,46 +864,22 @@ void ddr_enable_ecc(unsigned int dram_size)
 	register u64 *p;
 	register uint size;
 	unsigned int pattern[2];
-#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
-	uint i;
-#endif
+
 	icache_enable();
 	t_start = get_tbms();
 	pattern[0] = 0xdeadbeef;
 	pattern[1] = 0xdeadbeef;
 
-#if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+	dma_meminit(pattern[0], dram_size);
+#else
 	debug("ddr init: CPU FP write method\n");
 	size = dram_size;
 	for (p = 0; p < (u64*)(size); p++) {
 		ppcDWstore((u32*)p, pattern);
 	}
 	__asm__ __volatile__ ("sync");
-#else
-	debug("ddr init: DMA method\n");
-	size = 0x2000;
-	for (p = 0; p < (u64*)(size); p++) {
-		ppcDWstore((u32*)p, pattern);
-	}
-	__asm__ __volatile__ ("sync");
 
-	/* Initialise DMA for direct transfer */
-	dma_init();
-	/* Start DMA to transfer */
-	dmacpy((uint *)0x2000, (uint *)0, 0x2000); /* 8K */
-	dmacpy((uint *)0x4000, (uint *)0, 0x4000); /* 16K */
-	dmacpy((uint *)0x8000, (uint *)0, 0x8000); /* 32K */
-	dmacpy((uint *)0x10000, (uint *)0, 0x10000); /* 64K */
-	dmacpy((uint *)0x20000, (uint *)0, 0x20000); /* 128K */
-	dmacpy((uint *)0x40000, (uint *)0, 0x40000); /* 256K */
-	dmacpy((uint *)0x80000, (uint *)0, 0x80000); /* 512K */
-	dmacpy((uint *)0x100000, (uint *)0, 0x100000); /* 1M */
-	dmacpy((uint *)0x200000, (uint *)0, 0x200000); /* 2M */
-	dmacpy((uint *)0x400000, (uint *)0, 0x400000); /* 4M */
-
-	for (i = 1; i < dram_size / 0x800000; i++) {
-		dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000);
-	}
 #endif
 
 	t_end = get_tbms();
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c
index 572f8b6..1146d5a 100644
--- a/drivers/dma/fsl_dma.c
+++ b/drivers/dma/fsl_dma.c
@@ -33,7 +33,16 @@
 /* Controller can only transfer 2^26 - 1 bytes at a time */
 #define FSL_DMA_MAX_SIZE	(0x3ffffff)
 
-#if defined(CONFIG_MPC85xx)
+#if defined(CONFIG_MPC83XX)
+#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_DMSEN)
+#else
+#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT)
+#endif
+
+
+#if defined(CONFIG_MPC83XX)
+dma83xx_t *dma_base = (void *)(CONFIG_SYS_MPC83xx_DMA_ADDR);
+#elif defined(CONFIG_MPC85xx)
 ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR);
 #elif defined(CONFIG_MPC86xx)
 ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR);
@@ -50,17 +59,35 @@ static void dma_sync(void)
 #endif
 }
 
+static void out_dma32(volatile unsigned *addr, int val)
+{
+#if defined(CONFIG_MPC83XX)
+	out_le32(addr, val);
+#else
+	out_be32(addr, val);
+#endif
+}
+
+static uint in_dma32(volatile unsigned *addr)
+{
+#if defined(CONFIG_MPC83XX)
+	return in_le32(addr);
+#else
+	return in_be32(addr);
+#endif
+}
+
 static uint dma_check(void) {
 	volatile fsl_dma_t *dma = &dma_base->dma[0];
 	uint status;
 
 	/* While the channel is busy, spin */
 	do {
-		status = in_be32(&dma->sr);
+		status = in_dma32(&dma->sr);
 	} while (status & FSL_DMA_SR_CB);
 
 	/* clear MR[CS] channel start bit */
-	out_be32(&dma->mr, in_be32(&dma->mr) & ~FSL_DMA_MR_CS);
+	out_dma32(&dma->mr, in_dma32(&dma->mr) & ~FSL_DMA_MR_CS);
 	dma_sync();
 
 	if (status != 0)
@@ -69,14 +96,16 @@ static uint dma_check(void) {
 	return status;
 }
 
+#if !defined(CONFIG_MPC83XX)
 void dma_init(void) {
 	volatile fsl_dma_t *dma = &dma_base->dma[0];
 
-	out_be32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP);
-	out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP);
-	out_be32(&dma->sr, 0xffffffff); /* clear any errors */
+	out_dma32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP);
+	out_dma32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP);
+	out_dma32(&dma->sr, 0xffffffff); /* clear any errors */
 	dma_sync();
 }
+#endif
 
 int dmacpy(void *dest, const void *src, size_t n) {
 	volatile fsl_dma_t *dma = &dma_base->dma[0];
@@ -87,18 +116,17 @@ int dmacpy(void *dest, const void *src, size_t n) {
 
 		debug("size = 0x%x, xfer_size = 0x%x, src = %p, dest = %p\n",
 			n, xfer_size, src, dest);
-		out_be32(&dma->dar, (uint) dest);
-		out_be32(&dma->sar, (uint) src);
-		out_be32(&dma->bcr, xfer_size);
+		out_dma32(&dma->dar, (uint) dest);
+		out_dma32(&dma->sar, (uint) src);
+		out_dma32(&dma->bcr, xfer_size);
+		dma_sync();
 
-		/* Disable bandwidth control, use direct transfer mode */
-		out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT);
+		/* Prepare mode register */
+		out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT);
 		dma_sync();
 
 		/* Start the transfer */
-		out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS |
-				FSL_DMA_MR_CTM_DIRECT |
-				FSL_DMA_MR_CS);
+		out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT | FSL_DMA_MR_CS);
 
 		n -= xfer_size;
 		src += xfer_size;
@@ -113,7 +141,8 @@ int dmacpy(void *dest, const void *src, size_t n) {
 	return 0;
 }
 
-#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER))
+#if (!defined CONFIG_MPC83XX && defined(CONFIG_DDR_ECC) && \
+	!defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER))
 void dma_meminit(uint val, uint size)
 {
 	uint *p = 0;
diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h
index dd92343..5c4893f 100644
--- a/include/asm-ppc/fsl_dma.h
+++ b/include/asm-ppc/fsl_dma.h
@@ -27,6 +27,41 @@
 
 #include <asm/types.h>
 
+#ifdef CONFIG_MPC83XX
+typedef struct fsl_dma {
+	uint	mr;		/* DMA mode register */
+#define FSL_DMA_MR_CS		0x00000001	/* Channel start */
+#define FSL_DMA_MR_CC		0x00000002	/* Channel continue */
+#define FSL_DMA_MR_CTM		0x00000004	/* Channel xfer mode */
+#define FSL_DMA_MR_CTM_DIRECT	0x00000004	/* Direct channel xfer mode */
+#define FSL_DMA_MR_EOTIE	0x00000080	/* End-of-transfer interrupt en */
+#define FSL_DMA_MR_PRC_MASK	0x00000c00	/* PCI read command */
+#define FSL_DMA_MR_SAHE		0x00001000	/* Source addr hold enable */
+#define FSL_DMA_MR_DAHE		0x00002000	/* Dest addr hold enable */
+#define FSL_DMA_MR_SAHTS_MASK	0x0000c000	/* Source addr hold xfer size */
+#define FSL_DMA_MR_DAHTS_MASK	0x00030000	/* Dest addr hold xfer size */
+#define FSL_DMA_MR_EMS_EN	0x00040000	/* Ext master start en */
+#define FSL_DMA_MR_IRQS		0x00080000	/* Interrupt steer */
+#define FSL_DMA_MR_DMSEN	0x00100000	/* Direct mode snooping en */
+#define FSL_DMA_MR_BWC_MASK	0x00e00000	/* Bandwidth/pause ctl */
+#define FSL_DMA_MR_DRCNT	0x0f000000	/* DMA request count */
+	uint	sr;		/* DMA status register */
+#define FSL_DMA_SR_EOCDI	0x00000001	/* End-of-chain/direct interrupt */
+#define FSL_DMA_SR_EOSI		0x00000002	/* End-of-segment interrupt */
+#define FSL_DMA_SR_CB		0x00000004	/* Channel busy */
+#define FSL_DMA_SR_TE		0x00000080	/* Transfer error */
+	uint	cdar;		/* DMA current descriptor address register */
+	char	res0[4];
+	uint	sar;		/* DMA source address register */
+	char	res1[4];
+	uint	dar;		/* DMA destination address register */
+	char	res2[4];
+	uint	bcr;		/* DMA byte count register */
+	uint	ndar;		/* DMA next descriptor address register */
+	uint	gsr;		/* DMA general status register (DMA3 ONLY!) */
+	char	res3[84];
+} fsl_dma_t;
+#else
 typedef struct fsl_dma {
 	uint	mr;		/* DMA mode register */
 #define FSL_DMA_MR_CS		0x00000001	/* Channel start */
@@ -93,6 +128,7 @@ typedef struct fsl_dma {
 	uint	dsr;		/* DMA destination stride register */
 	char	res4[56];
 } fsl_dma_t;
+#endif /* !CONFIG_MPC83XX */
 
 #ifdef CONFIG_FSL_DMA
 void dma_init(void);
diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h
index 7b847f8..89306ca 100644
--- a/include/asm-ppc/immap_83xx.h
+++ b/include/asm-ppc/immap_83xx.h
@@ -32,6 +32,7 @@
 #include <asm/fsl_i2c.h>
 #include <asm/mpc8xxx_spi.h>
 #include <asm/fsl_lbc.h>
+#include <asm/fsl_dma.h>
 
 /*
  * Local Access Window
@@ -367,51 +368,7 @@ typedef struct dma83xx {
 	u32 imisr;		/* 0x80 Inbound message interrupt status register */
 	u32 imimr;		/* 0x84 Inbound message interrupt mask register */
 	u32 res4[0x1E];		/* 0x88-0x99 reserved */
-	u32 dmamr0;		/* 0x100 DMA 0 mode register */
-	u32 dmasr0;		/* 0x104 DMA 0 status register */
-	u32 dmacdar0;		/* 0x108 DMA 0 current descriptor address register */
-	u32 res5;		/* 0x10C reserved */
-	u32 dmasar0;		/* 0x110 DMA 0 source address register */
-	u32 res6;		/* 0x114 reserved */
-	u32 dmadar0;		/* 0x118 DMA 0 destination address register */
-	u32 res7;		/* 0x11C reserved */
-	u32 dmabcr0;		/* 0x120 DMA 0 byte count register */
-	u32 dmandar0;		/* 0x124 DMA 0 next descriptor address register */
-	u32 res8[0x16];		/* 0x128-0x179 reserved */
-	u32 dmamr1;		/* 0x180 DMA 1 mode register */
-	u32 dmasr1;		/* 0x184 DMA 1 status register */
-	u32 dmacdar1;		/* 0x188 DMA 1 current descriptor address register */
-	u32 res9;		/* 0x18C reserved */
-	u32 dmasar1;		/* 0x190 DMA 1 source address register */
-	u32 res10;		/* 0x194 reserved */
-	u32 dmadar1;		/* 0x198 DMA 1 destination address register */
-	u32 res11;		/* 0x19C reserved */
-	u32 dmabcr1;		/* 0x1A0 DMA 1 byte count register */
-	u32 dmandar1;		/* 0x1A4 DMA 1 next descriptor address register */
-	u32 res12[0x16];	/* 0x1A8-0x199 reserved */
-	u32 dmamr2;		/* 0x200 DMA 2 mode register */
-	u32 dmasr2;		/* 0x204 DMA 2 status register */
-	u32 dmacdar2;		/* 0x208 DMA 2 current descriptor address register */
-	u32 res13;		/* 0x20C reserved */
-	u32 dmasar2;		/* 0x210 DMA 2 source address register */
-	u32 res14;		/* 0x214 reserved */
-	u32 dmadar2;		/* 0x218 DMA 2 destination address register */
-	u32 res15;		/* 0x21C reserved */
-	u32 dmabcr2;		/* 0x220 DMA 2 byte count register */
-	u32 dmandar2;		/* 0x224 DMA 2 next descriptor address register */
-	u32 res16[0x16];	/* 0x228-0x279 reserved */
-	u32 dmamr3;		/* 0x280 DMA 3 mode register */
-	u32 dmasr3;		/* 0x284 DMA 3 status register */
-	u32 dmacdar3;		/* 0x288 DMA 3 current descriptor address register */
-	u32 res17;		/* 0x28C reserved */
-	u32 dmasar3;		/* 0x290 DMA 3 source address register */
-	u32 res18;		/* 0x294 reserved */
-	u32 dmadar3;		/* 0x298 DMA 3 destination address register */
-	u32 res19;		/* 0x29C reserved */
-	u32 dmabcr3;		/* 0x2A0 DMA 3 byte count register */
-	u32 dmandar3;		/* 0x2A4 DMA 3 next descriptor address register */
-	u32 dmagsr;		/* 0x2A8 DMA general status register */
-	u32 res20[0x15];	/* 0x2AC-0x2FF reserved */
+	struct fsl_dma dma[4];
 } dma83xx_t;
 
 /*
@@ -895,6 +852,8 @@ typedef struct immap {
 } immap_t;
 #endif
 
+#define CONFIG_SYS_MPC83xx_DMA_OFFSET	(0x8000)
+#define CONFIG_SYS_MPC83xx_DMA_ADDR	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
 #define CONFIG_SYS_MPC83xx_ESDHC_OFFSET	(0x2e000)
 #define CONFIG_SYS_MPC83xx_ESDHC_ADDR	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)
 #endif				/* __IMMAP_83xx__ */
diff --git a/include/mpc83xx.h b/include/mpc83xx.h
index fab3751..fcbbc45 100644
--- a/include/mpc83xx.h
+++ b/include/mpc83xx.h
@@ -1041,22 +1041,6 @@
 #define ECC_ERROR_MAN_SBEC		(0xff000000>>24)	/* Single Bit Error Counter 0..255 */
 #define ECC_ERROR_MAN_SBEC_SHIFT	0
 
-/* DMAMR - DMA Mode Register
- */
-#define DMA_CHANNEL_START			0x00000001	/* Bit - DMAMRn CS */
-#define DMA_CHANNEL_TRANSFER_MODE_DIRECT	0x00000004	/* Bit - DMAMRn CTM */
-#define DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN	0x00001000	/* Bit - DMAMRn SAHE */
-#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_1B	0x00000000	/* 2Bit- DMAMRn SAHTS 1byte */
-#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_2B	0x00004000	/* 2Bit- DMAMRn SAHTS 2bytes */
-#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_4B	0x00008000	/* 2Bit- DMAMRn SAHTS 4bytes */
-#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B	0x0000c000	/* 2Bit- DMAMRn SAHTS 8bytes */
-#define DMA_CHANNEL_SNOOP			0x00010000	/* Bit - DMAMRn DMSEN */
-
-/* DMASR - DMA Status Register
- */
-#define DMA_CHANNEL_BUSY			0x00000004	/* Bit - DMASRn CB */
-#define DMA_CHANNEL_TRANSFER_ERROR		0x00000080	/* Bit - DMASRn TE */
-
 /* CONFIG_ADDRESS - PCI Config Address Register
  */
 #define PCI_CONFIG_ADDRESS_EN		0x80000000
-- 
1.6.2.1



More information about the U-Boot mailing list