[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