[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