[U-Boot] [PATCH v2 12/12] 83xx: Add support for fsl_dma driver

Peter Tyser ptyser at xes-inc.com
Wed Jul 1 00:15:51 CEST 2009


Signed-off-by: Peter Tyser <ptyser at xes-inc.com>
Reviewed-by: Ira W. Snyder <iws at ovro.caltech.edu>
Tested-by: Ira W. Snyder <iws at ovro.caltech.edu>
---
 cpu/mpc83xx/cpu.c            |   85 ------------------------------------------
 cpu/mpc83xx/spd_sdram.c      |   40 ++------------------
 drivers/dma/fsl_dma.c        |   64 ++++++++++++++++++++++++-------
 include/asm-ppc/config.h     |    5 +-
 include/asm-ppc/fsl_dma.h    |   36 ++++++++++++++++++
 include/asm-ppc/immap_83xx.h |   49 ++----------------------
 include/mpc83xx.h            |   16 --------
 7 files changed, 96 insertions(+), 199 deletions(-)

diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index a5c1f00..e38a372 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(phys_addr_t dest, phys_addr_t src, phys_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 8243968..0f61180 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(phys_addr_t dest, phys_addr_t src, phys_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,45 +864,21 @@ 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(0x2000, 0, 0x2000); /* 8K */
-	dmacpy(0x4000, 0, 0x4000); /* 16K */
-	dmacpy(0x8000, 0, 0x8000); /* 32K */
-	dmacpy(0x10000, 0, 0x10000); /* 64K */
-	dmacpy(0x20000, 0, 0x20000); /* 128K */
-	dmacpy(0x40000, 0, 0x40000); /* 256K */
-	dmacpy(0x80000, 0, 0x80000); /* 512K */
-	dmacpy(0x100000, 0, 0x100000); /* 1M */
-	dmacpy(0x200000, 0, 0x200000); /* 2M */
-	dmacpy(0x400000, 0, 0x400000); /* 4M */
-
-	for (i = 1; i < dram_size / 0x800000; i++)
-		dmacpy(0x800000 * i, 0, 0x800000);
 #endif
 
 	t_end = get_tbms();
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c
index cba5d5b..df33e7a 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(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
 	volatile fsl_dma_t *dma = &dma_base->dma[0];
@@ -85,18 +114,17 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
 	while (count) {
 		xfer_size = MIN(FSL_DMA_MAX_SIZE, count);
 
-		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);
 
 		count -= xfer_size;
 		src += xfer_size;
@@ -111,7 +139,13 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
 	return 0;
 }
 
-#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER))
+/*
+ * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER
+ * while 83xx uses dma to initialize SDRAM when CONFIG_DDR_ECC_INIT_VIA_DMA
+ */
+#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&	\
+	!defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) ||		\
+	(defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA)))
 void dma_meminit(uint val, uint size)
 {
 	uint *p = 0;
diff --git a/include/asm-ppc/config.h b/include/asm-ppc/config.h
index 9c358aa..ca143c7 100644
--- a/include/asm-ppc/config.h
+++ b/include/asm-ppc/config.h
@@ -30,8 +30,9 @@
 #endif
 
 #ifndef CONFIG_FSL_DMA
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) && \
-	(defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx))
+#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&	\
+	!defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) ||		\
+	(defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA)))
 #define CONFIG_FSL_DMA
 #endif
 #endif
diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h
index 043669e..1164191 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 8f945a1..7c6a151 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)
 #define CONFIG_SYS_MPC83xx_USB_OFFSET	0x23000
diff --git a/include/mpc83xx.h b/include/mpc83xx.h
index c5bd6cb..fd742c7 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