[U-Boot] [PATCH 00/11] 85xx/86xx dma updates

This patch series attempts to clean up the DMA implementation for the 85xx and 86xx architectures. The changes include: - consolidate 85xx and 86xx structures and code - add defines for bitfields - use proper IO accessors - add support for arbitrarily large transfer sizes - rename dma_xfer() to dmacpy() and make dmacpy's prototype similar to memcpy()
The patches are based on the mainline "next" branch.
I've tested the code on MPC8572 and MPC8640-based boards.
I'm not initimately familar with the 83xx platform, but at a glance it looked like the fsl_dma driver could be extended to support it with some ifdeffery.
Peter Tyser (11): fsl: Create common fsl_dma.h for 85xx and 86xx cpus 85xx, 86xx: Sync up DMA code 85xx, 86xx: Break out DMA code to a common file fsl_dma: Add bitfield definitions for common registers fsl_dma: Update to use proper I/O accessor functions fsl_dma: Add support for arbitrarily large transfers fsl_dma: Fix Channel Start bug in dma_check() 8xxx: Rename dma_xfer() dmacpy() fsl_dma: Move dma function prototypes to common header file 85xx, 86xx: Move dma_init() call to common code fsl_dma: Break out common memory initialization function
board/mpc8540eval/mpc8540eval.c | 35 +--------- board/sbc8560/sbc8560.c | 33 +--------- cpu/mpc83xx/cpu.c | 4 +- cpu/mpc83xx/spd_sdram.c | 24 +++--- cpu/mpc85xx/cpu.c | 44 ------------ cpu/mpc85xx/cpu_init.c | 4 +- cpu/mpc85xx/ddr-gen1.c | 33 +--------- cpu/mpc86xx/cpu.c | 50 ------------- cpu/mpc86xx/cpu_init.c | 3 + drivers/dma/Makefile | 1 + drivers/dma/fsl_dma.c | 146 +++++++++++++++++++++++++++++++++++++++ include/asm-ppc/fsl_dma.h | 105 ++++++++++++++++++++++++++++ include/asm-ppc/immap_85xx.h | 76 +------------------- include/asm-ppc/immap_86xx.h | 78 ++------------------- include/configs/PM854.h | 1 + include/configs/PM856.h | 1 + 16 files changed, 286 insertions(+), 352 deletions(-) create mode 100644 drivers/dma/fsl_dma.c create mode 100644 include/asm-ppc/fsl_dma.h

Break out DMA structures for the Freescale MPC85xx and MPC86xx cpus to reduce a large amount of code duplication
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- cpu/mpc85xx/cpu.c | 31 +++++++++-------- cpu/mpc86xx/cpu.c | 27 ++++++++------- include/asm-ppc/fsl_dma.h | 51 ++++++++++++++++++++++++++++ include/asm-ppc/immap_85xx.h | 76 ++---------------------------------------- include/asm-ppc/immap_86xx.h | 76 ++---------------------------------------- 5 files changed, 89 insertions(+), 172 deletions(-) create mode 100644 include/asm-ppc/fsl_dma.h
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index ef976a4..8c57404 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -260,26 +260,28 @@ reset_85xx_watchdog(void)
#if defined(CONFIG_DDR_ECC) void dma_init(void) { - volatile ccsr_dma_t *dma = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); + volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); + volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr0 = 0x02c40000; - dma->datr0 = 0x02c40000; - dma->sr0 = 0xfffffff; /* clear any errors */ + dma->satr = 0x02c40000; + dma->datr = 0x02c40000; + dma->sr = 0xfffffff; /* clear any errors */ asm("sync; isync; msync"); return; }
uint dma_check(void) { - volatile ccsr_dma_t *dma = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); - volatile uint status = dma->sr0; + volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); + volatile fsl_dma_t *dma = &dma_base->dma[0]; + volatile uint status = dma->sr;
/* While the channel is busy, spin */ while((status & 4) == 4) { - status = dma->sr0; + status = dma->sr; }
/* clear MR0[CS] channel start bit */ - dma->mr0 &= 0x00000001; + dma->mr &= 0x00000001; asm("sync;isync;msync");
if (status != 0) { @@ -289,14 +291,15 @@ uint dma_check(void) { }
int dma_xfer(void *dest, uint count, void *src) { - volatile ccsr_dma_t *dma = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); + volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); + volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->dar0 = (uint) dest; - dma->sar0 = (uint) src; - dma->bcr0 = count; - dma->mr0 = 0xf000004; + dma->dar = (uint) dest; + dma->sar = (uint) src; + dma->bcr = count; + dma->mr = 0xf000004; asm("sync;isync;msync"); - dma->mr0 = 0xf000005; + dma->mr = 0xf000005; asm("sync;isync;msync"); return dma_check(); } diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index 653a137..f35323a 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -183,10 +183,11 @@ void dma_init(void) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_dma_t *dma = &immap->im_dma; + volatile ccsr_dma_t *dma_base = &immap->im_dma; + volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr0 = 0x00040000; - dma->datr0 = 0x00040000; + dma->satr = 0x00040000; + dma->datr = 0x00040000; asm("sync; isync"); }
@@ -194,12 +195,13 @@ uint dma_check(void) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_dma_t *dma = &immap->im_dma; - volatile uint status = dma->sr0; + volatile ccsr_dma_t *dma_base = &immap->im_dma; + volatile fsl_dma_t *dma = &dma_base->dma[0]; + volatile uint status = dma->sr;
/* While the channel is busy, spin */ while ((status & 4) == 4) { - status = dma->sr0; + status = dma->sr; }
if (status != 0) { @@ -212,14 +214,15 @@ int dma_xfer(void *dest, uint count, void *src) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_dma_t *dma = &immap->im_dma; + volatile ccsr_dma_t *dma_base = &immap->im_dma; + volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->dar0 = (uint) dest; - dma->sar0 = (uint) src; - dma->bcr0 = count; - dma->mr0 = 0xf000004; + dma->dar = (uint) dest; + dma->sar = (uint) src; + dma->bcr = count; + dma->mr = 0xf000004; asm("sync;isync"); - dma->mr0 = 0xf000005; + dma->mr = 0xf000005; asm("sync;isync"); return dma_check(); } diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h new file mode 100644 index 0000000..aab8720 --- /dev/null +++ b/include/asm-ppc/fsl_dma.h @@ -0,0 +1,51 @@ +/* + * Freescale DMA Controller + * + * Copyright 2006 Freescale Semiconductor, Inc. + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_FSL_DMA_H_ +#define _ASM_FSL_DMA_H_ + +#include <asm/types.h> + +typedef struct fsl_dma { + uint mr; /* DMA mode register */ + uint sr; /* DMA status register */ + char res0[4]; + uint clndar; /* DMA current link descriptor address register */ + uint satr; /* DMA source attributes register */ + uint sar; /* DMA source address register */ + uint datr; /* DMA destination attributes register */ + uint dar; /* DMA destination address register */ + uint bcr; /* DMA byte count register */ + char res1[4]; + uint nlndar; /* DMA next link descriptor address register */ + char res2[8]; + uint clabdar; /* DMA current List - alternate base descriptor address Register */ + char res3[4]; + uint nlsdar; /* DMA next list descriptor address register */ + uint ssr; /* DMA source stride register */ + uint dsr; /* DMA destination stride register */ + char res4[56]; +} fsl_dma_t; + +#endif /* _ASM_DMA_H_ */ diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index d3c6b86..2231177 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -12,6 +12,7 @@ #define __IMMAP_85xx__
#include <asm/types.h> +#include <asm/fsl_dma.h> #include <asm/fsl_i2c.h> #include <asm/fsl_lbc.h>
@@ -406,80 +407,9 @@ typedef struct ccsr_l2cache { */ typedef struct ccsr_dma { char res1[256]; - uint mr0; /* 0x21100 - DMA 0 Mode Register */ - uint sr0; /* 0x21104 - DMA 0 Status Register */ - char res2[4]; - uint clndar0; /* 0x2110c - DMA 0 Current Link Descriptor Address Register */ - uint satr0; /* 0x21110 - DMA 0 Source Attributes Register */ - uint sar0; /* 0x21114 - DMA 0 Source Address Register */ - uint datr0; /* 0x21118 - DMA 0 Destination Attributes Register */ - uint dar0; /* 0x2111c - DMA 0 Destination Address Register */ - uint bcr0; /* 0x21120 - DMA 0 Byte Count Register */ - char res3[4]; - uint nlndar0; /* 0x21128 - DMA 0 Next Link Descriptor Address Register */ - char res4[8]; - uint clabdar0; /* 0x21134 - DMA 0 Current List - Alternate Base Descriptor Address Register */ - char res5[4]; - uint nlsdar0; /* 0x2113c - DMA 0 Next List Descriptor Address Register */ - uint ssr0; /* 0x21140 - DMA 0 Source Stride Register */ - uint dsr0; /* 0x21144 - DMA 0 Destination Stride Register */ - char res6[56]; - uint mr1; /* 0x21180 - DMA 1 Mode Register */ - uint sr1; /* 0x21184 - DMA 1 Status Register */ - char res7[4]; - uint clndar1; /* 0x2118c - DMA 1 Current Link Descriptor Address Register */ - uint satr1; /* 0x21190 - DMA 1 Source Attributes Register */ - uint sar1; /* 0x21194 - DMA 1 Source Address Register */ - uint datr1; /* 0x21198 - DMA 1 Destination Attributes Register */ - uint dar1; /* 0x2119c - DMA 1 Destination Address Register */ - uint bcr1; /* 0x211a0 - DMA 1 Byte Count Register */ - char res8[4]; - uint nlndar1; /* 0x211a8 - DMA 1 Next Link Descriptor Address Register */ - char res9[8]; - uint clabdar1; /* 0x211b4 - DMA 1 Current List - Alternate Base Descriptor Address Register */ - char res10[4]; - uint nlsdar1; /* 0x211bc - DMA 1 Next List Descriptor Address Register */ - uint ssr1; /* 0x211c0 - DMA 1 Source Stride Register */ - uint dsr1; /* 0x211c4 - DMA 1 Destination Stride Register */ - char res11[56]; - uint mr2; /* 0x21200 - DMA 2 Mode Register */ - uint sr2; /* 0x21204 - DMA 2 Status Register */ - char res12[4]; - uint clndar2; /* 0x2120c - DMA 2 Current Link Descriptor Address Register */ - uint satr2; /* 0x21210 - DMA 2 Source Attributes Register */ - uint sar2; /* 0x21214 - DMA 2 Source Address Register */ - uint datr2; /* 0x21218 - DMA 2 Destination Attributes Register */ - uint dar2; /* 0x2121c - DMA 2 Destination Address Register */ - uint bcr2; /* 0x21220 - DMA 2 Byte Count Register */ - char res13[4]; - uint nlndar2; /* 0x21228 - DMA 2 Next Link Descriptor Address Register */ - char res14[8]; - uint clabdar2; /* 0x21234 - DMA 2 Current List - Alternate Base Descriptor Address Register */ - char res15[4]; - uint nlsdar2; /* 0x2123c - DMA 2 Next List Descriptor Address Register */ - uint ssr2; /* 0x21240 - DMA 2 Source Stride Register */ - uint dsr2; /* 0x21244 - DMA 2 Destination Stride Register */ - char res16[56]; - uint mr3; /* 0x21280 - DMA 3 Mode Register */ - uint sr3; /* 0x21284 - DMA 3 Status Register */ - char res17[4]; - uint clndar3; /* 0x2128c - DMA 3 Current Link Descriptor Address Register */ - uint satr3; /* 0x21290 - DMA 3 Source Attributes Register */ - uint sar3; /* 0x21294 - DMA 3 Source Address Register */ - uint datr3; /* 0x21298 - DMA 3 Destination Attributes Register */ - uint dar3; /* 0x2129c - DMA 3 Destination Address Register */ - uint bcr3; /* 0x212a0 - DMA 3 Byte Count Register */ - char res18[4]; - uint nlndar3; /* 0x212a8 - DMA 3 Next Link Descriptor Address Register */ - char res19[8]; - uint clabdar3; /* 0x212b4 - DMA 3 Current List - Alternate Base Descriptor Address Register */ - char res20[4]; - uint nlsdar3; /* 0x212bc - DMA 3 Next List Descriptor Address Register */ - uint ssr3; /* 0x212c0 - DMA 3 Source Stride Register */ - uint dsr3; /* 0x212c4 - DMA 3 Destination Stride Register */ - char res21[56]; + struct fsl_dma dma[4]; uint dgsr; /* 0x21300 - DMA General Status Register */ - char res22[11516]; + char res2[11516]; } ccsr_dma_t;
/* diff --git a/include/asm-ppc/immap_86xx.h b/include/asm-ppc/immap_86xx.h index 470385f..689c720 100644 --- a/include/asm-ppc/immap_86xx.h +++ b/include/asm-ppc/immap_86xx.h @@ -11,6 +11,7 @@ #define __IMMAP_86xx__
#include <asm/types.h> +#include <asm/fsl_dma.h> #include <asm/fsl_i2c.h>
/* Local-Access Registers and MCM Registers(0x0000-0x2000) */ @@ -386,80 +387,9 @@ typedef struct ccsr_ht { /* DMA Registers(0x2_1000-0x2_2000) */ typedef struct ccsr_dma { char res1[256]; - uint mr0; /* 0x21100 - DMA 0 Mode Register */ - uint sr0; /* 0x21104 - DMA 0 Status Register */ - char res2[4]; - uint clndar0; /* 0x2110c - DMA 0 Current Link Descriptor Address Register */ - uint satr0; /* 0x21110 - DMA 0 Source Attributes Register */ - uint sar0; /* 0x21114 - DMA 0 Source Address Register */ - uint datr0; /* 0x21118 - DMA 0 Destination Attributes Register */ - uint dar0; /* 0x2111c - DMA 0 Destination Address Register */ - uint bcr0; /* 0x21120 - DMA 0 Byte Count Register */ - char res3[4]; - uint nlndar0; /* 0x21128 - DMA 0 Next Link Descriptor Address Register */ - char res4[8]; - uint clabdar0; /* 0x21134 - DMA 0 Current List - Alternate Base Descriptor Address Register */ - char res5[4]; - uint nlsdar0; /* 0x2113c - DMA 0 Next List Descriptor Address Register */ - uint ssr0; /* 0x21140 - DMA 0 Source Stride Register */ - uint dsr0; /* 0x21144 - DMA 0 Destination Stride Register */ - char res6[56]; - uint mr1; /* 0x21180 - DMA 1 Mode Register */ - uint sr1; /* 0x21184 - DMA 1 Status Register */ - char res7[4]; - uint clndar1; /* 0x2118c - DMA 1 Current Link Descriptor Address Register */ - uint satr1; /* 0x21190 - DMA 1 Source Attributes Register */ - uint sar1; /* 0x21194 - DMA 1 Source Address Register */ - uint datr1; /* 0x21198 - DMA 1 Destination Attributes Register */ - uint dar1; /* 0x2119c - DMA 1 Destination Address Register */ - uint bcr1; /* 0x211a0 - DMA 1 Byte Count Register */ - char res8[4]; - uint nlndar1; /* 0x211a8 - DMA 1 Next Link Descriptor Address Register */ - char res9[8]; - uint clabdar1; /* 0x211b4 - DMA 1 Current List - Alternate Base Descriptor Address Register */ - char res10[4]; - uint nlsdar1; /* 0x211bc - DMA 1 Next List Descriptor Address Register */ - uint ssr1; /* 0x211c0 - DMA 1 Source Stride Register */ - uint dsr1; /* 0x211c4 - DMA 1 Destination Stride Register */ - char res11[56]; - uint mr2; /* 0x21200 - DMA 2 Mode Register */ - uint sr2; /* 0x21204 - DMA 2 Status Register */ - char res12[4]; - uint clndar2; /* 0x2120c - DMA 2 Current Link Descriptor Address Register */ - uint satr2; /* 0x21210 - DMA 2 Source Attributes Register */ - uint sar2; /* 0x21214 - DMA 2 Source Address Register */ - uint datr2; /* 0x21218 - DMA 2 Destination Attributes Register */ - uint dar2; /* 0x2121c - DMA 2 Destination Address Register */ - uint bcr2; /* 0x21220 - DMA 2 Byte Count Register */ - char res13[4]; - uint nlndar2; /* 0x21228 - DMA 2 Next Link Descriptor Address Register */ - char res14[8]; - uint clabdar2; /* 0x21234 - DMA 2 Current List - Alternate Base Descriptor Address Register */ - char res15[4]; - uint nlsdar2; /* 0x2123c - DMA 2 Next List Descriptor Address Register */ - uint ssr2; /* 0x21240 - DMA 2 Source Stride Register */ - uint dsr2; /* 0x21244 - DMA 2 Destination Stride Register */ - char res16[56]; - uint mr3; /* 0x21280 - DMA 3 Mode Register */ - uint sr3; /* 0x21284 - DMA 3 Status Register */ - char res17[4]; - uint clndar3; /* 0x2128c - DMA 3 Current Link Descriptor Address Register */ - uint satr3; /* 0x21290 - DMA 3 Source Attributes Register */ - uint sar3; /* 0x21294 - DMA 3 Source Address Register */ - uint datr3; /* 0x21298 - DMA 3 Destination Attributes Register */ - uint dar3; /* 0x2129c - DMA 3 Destination Address Register */ - uint bcr3; /* 0x212a0 - DMA 3 Byte Count Register */ - char res18[4]; - uint nlndar3; /* 0x212a8 - DMA 3 Next Link Descriptor Address Register */ - char res19[8]; - uint clabdar3; /* 0x212b4 - DMA 3 Current List - Alternate Base Descriptor Address Register */ - char res20[4]; - uint nlsdar3; /* 0x212bc - DMA 3 Next List Descriptor Address Register */ - uint ssr3; /* 0x212c0 - DMA 3 Source Stride Register */ - uint dsr3; /* 0x212c4 - DMA 3 Destination Stride Register */ - char res21[56]; + struct fsl_dma dma[4]; uint dgsr; /* 0x21300 - DMA General Status Register */ - char res22[3324]; + char res2[3324]; } ccsr_dma_t;
/* tsec1-4: 24000-28000 */

On May 21, 2009, at 12:09 PM, Peter Tyser wrote:
Break out DMA structures for the Freescale MPC85xx and MPC86xx cpus to reduce a large amount of code duplication
Signed-off-by: Peter Tyser ptyser@xes-inc.com
cpu/mpc85xx/cpu.c | 31 +++++++++-------- cpu/mpc86xx/cpu.c | 27 ++++++++------- include/asm-ppc/fsl_dma.h | 51 ++++++++++++++++++++++++++++ include/asm-ppc/immap_85xx.h | 76 + +---------------------------------------- include/asm-ppc/immap_86xx.h | 76 + +---------------------------------------- 5 files changed, 89 insertions(+), 172 deletions(-) create mode 100644 include/asm-ppc/fsl_dma.h
applied to next
- k

The following changes were made to sync up the DMA code between the 85xx and 86xx architectures which will make it easier to break out common 8xxx DMA code:
85xx: - Don't set STRANSINT and SPCIORDER fields in SATR register. These bits only have an affect when the SBPATMU bit is set. - Write 0xffffffff instead of 0xfffffff to clear errors in the DMA status register. We may as well clear all 32 bits of the register...
86xx: - Add CONFIG_SYS_MPC86xx_DMA_ADDR define to address DMA registers - Add clearing of errors in the DMA status register when initializing the controller - Clear the channel start bit in the DMA mode register after a transfer
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- cpu/mpc85xx/cpu.c | 8 ++++---- cpu/mpc86xx/cpu.c | 14 ++++++++------ include/asm-ppc/immap_86xx.h | 2 ++ 3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 8c57404..86b19a6 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -263,9 +263,9 @@ void dma_init(void) { volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr = 0x02c40000; - dma->datr = 0x02c40000; - dma->sr = 0xfffffff; /* clear any errors */ + dma->satr = 0x00040000; + dma->datr = 0x00040000; + dma->sr = 0xffffffff; /* clear any errors */ asm("sync; isync; msync"); return; } @@ -280,7 +280,7 @@ uint dma_check(void) { status = dma->sr; }
- /* clear MR0[CS] channel start bit */ + /* clear MR[CS] channel start bit */ dma->mr &= 0x00000001; asm("sync;isync;msync");
diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index f35323a..d47cc5e 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -182,20 +182,19 @@ watchdog_reset(void) void dma_init(void) { - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_dma_t *dma_base = &immap->im_dma; + volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); volatile fsl_dma_t *dma = &dma_base->dma[0];
dma->satr = 0x00040000; dma->datr = 0x00040000; + dma->sr = 0xffffffff; /* clear any errors */ asm("sync; isync"); }
uint dma_check(void) { - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_dma_t *dma_base = &immap->im_dma; + volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); volatile fsl_dma_t *dma = &dma_base->dma[0]; volatile uint status = dma->sr;
@@ -204,6 +203,10 @@ dma_check(void) status = dma->sr; }
+ /* clear MR[CS] channel start bit */ + dma->mr &= 0x00000001; + asm("sync;isync"); + if (status != 0) { printf("DMA Error: status = %x\n", status); } @@ -213,8 +216,7 @@ dma_check(void) int dma_xfer(void *dest, uint count, void *src) { - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_dma_t *dma_base = &immap->im_dma; + volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); volatile fsl_dma_t *dma = &dma_base->dma[0];
dma->dar = (uint) dest; diff --git a/include/asm-ppc/immap_86xx.h b/include/asm-ppc/immap_86xx.h index 689c720..a839834 100644 --- a/include/asm-ppc/immap_86xx.h +++ b/include/asm-ppc/immap_86xx.h @@ -1295,5 +1295,7 @@ extern immap_t *immr; #define CONFIG_SYS_MPC86xx_DDR_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DDR_OFFSET) #define CONFIG_SYS_MPC86xx_DDR2_OFFSET (0x6000) #define CONFIG_SYS_MPC86xx_DDR2_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DDR2_OFFSET) +#define CONFIG_SYS_MPC86xx_DMA_OFFSET (0x21000) +#define CONFIG_SYS_MPC86xx_DMA_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DMA_OFFSET)
#endif /*__IMMAP_86xx__*/

On May 21, 2009, at 12:10 PM, Peter Tyser wrote:
The following changes were made to sync up the DMA code between the 85xx and 86xx architectures which will make it easier to break out common 8xxx DMA code:
85xx:
- Don't set STRANSINT and SPCIORDER fields in SATR register. These
bits only have an affect when the SBPATMU bit is set.
- Write 0xffffffff instead of 0xfffffff to clear errors in the DMA
status register. We may as well clear all 32 bits of the register...
86xx:
- Add CONFIG_SYS_MPC86xx_DMA_ADDR define to address DMA registers
- Add clearing of errors in the DMA status register when initializing
the controller
- Clear the channel start bit in the DMA mode register after a
transfer
Signed-off-by: Peter Tyser ptyser@xes-inc.com
cpu/mpc85xx/cpu.c | 8 ++++---- cpu/mpc86xx/cpu.c | 14 ++++++++------ include/asm-ppc/immap_86xx.h | 2 ++ 3 files changed, 14 insertions(+), 10 deletions(-)
applied to next
- k

DMA support is now enabled via the CONFIG_FSL_DMA define instead of the previous CONFIG_DDR_ECC
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- cpu/mpc85xx/cpu.c | 47 ------------------------ cpu/mpc86xx/cpu.c | 55 ---------------------------- drivers/dma/Makefile | 1 + drivers/dma/fsl_dma.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++ include/configs/PM854.h | 1 + include/configs/PM856.h | 1 + 6 files changed, 95 insertions(+), 102 deletions(-) create mode 100644 drivers/dma/fsl_dma.c
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 86b19a6..416ea08 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -258,53 +258,6 @@ reset_85xx_watchdog(void) } #endif /* CONFIG_WATCHDOG */
-#if defined(CONFIG_DDR_ECC) -void dma_init(void) { - volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); - volatile fsl_dma_t *dma = &dma_base->dma[0]; - - dma->satr = 0x00040000; - dma->datr = 0x00040000; - dma->sr = 0xffffffff; /* clear any errors */ - asm("sync; isync; msync"); - return; -} - -uint dma_check(void) { - volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); - volatile fsl_dma_t *dma = &dma_base->dma[0]; - volatile uint status = dma->sr; - - /* While the channel is busy, spin */ - while((status & 4) == 4) { - status = dma->sr; - } - - /* clear MR[CS] channel start bit */ - dma->mr &= 0x00000001; - asm("sync;isync;msync"); - - if (status != 0) { - printf ("DMA Error: status = %x\n", status); - } - return status; -} - -int dma_xfer(void *dest, uint count, void *src) { - volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); - volatile fsl_dma_t *dma = &dma_base->dma[0]; - - dma->dar = (uint) dest; - dma->sar = (uint) src; - dma->bcr = count; - dma->mr = 0xf000004; - asm("sync;isync;msync"); - dma->mr = 0xf000005; - asm("sync;isync;msync"); - return dma_check(); -} -#endif - /* * Configures a UPM. The function requires the respective MxMR to be set * before calling this function. "size" is the number or entries, not a sizeof. diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index d47cc5e..1f26ba1 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -177,61 +177,6 @@ watchdog_reset(void) } #endif /* CONFIG_WATCHDOG */
- -#if defined(CONFIG_DDR_ECC) -void -dma_init(void) -{ - volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); - volatile fsl_dma_t *dma = &dma_base->dma[0]; - - dma->satr = 0x00040000; - dma->datr = 0x00040000; - dma->sr = 0xffffffff; /* clear any errors */ - asm("sync; isync"); -} - -uint -dma_check(void) -{ - volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); - volatile fsl_dma_t *dma = &dma_base->dma[0]; - volatile uint status = dma->sr; - - /* While the channel is busy, spin */ - while ((status & 4) == 4) { - status = dma->sr; - } - - /* clear MR[CS] channel start bit */ - dma->mr &= 0x00000001; - asm("sync;isync"); - - if (status != 0) { - printf("DMA Error: status = %x\n", status); - } - return status; -} - -int -dma_xfer(void *dest, uint count, void *src) -{ - volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); - volatile fsl_dma_t *dma = &dma_base->dma[0]; - - dma->dar = (uint) dest; - dma->sar = (uint) src; - dma->bcr = count; - dma->mr = 0xf000004; - asm("sync;isync"); - dma->mr = 0xf000005; - asm("sync;isync"); - return dma_check(); -} - -#endif /* CONFIG_DDR_ECC */ - - /* * Print out the state of various machine registers. * Currently prints out LAWs, BR0/OR0, and BATs diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index cf29efa..36d99f9 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libdma.a
COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o +COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c new file mode 100644 index 0000000..a9989ee --- /dev/null +++ b/drivers/dma/fsl_dma.c @@ -0,0 +1,92 @@ +/* + * Copyright 2004,2007,2008 Freescale Semiconductor, Inc. + * (C) Copyright 2002, 2003 Motorola Inc. + * Xianghua Xiao (X.Xiao@motorola.com) + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/fsl_dma.h> + +#if defined(CONFIG_MPC85xx) +volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); +#elif defined(CONFIG_MPC86xx) +volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); +#else +#error "Freescale DMA engine not supported on your processor" +#endif + +static void dma_sync(void) +{ +#if defined(CONFIG_MPC85xx) + asm("sync; isync; msync"); +#elif defined(CONFIG_MPC86xx) + asm("sync; isync"); +#endif +} + +static uint dma_check(void) { + volatile fsl_dma_t *dma = &dma_base->dma[0]; + volatile uint status = dma->sr; + + /* While the channel is busy, spin */ + while (status & 4) + status = dma->sr; + + /* clear MR[CS] channel start bit */ + dma->mr &= 1; + dma_sync(); + + if (status != 0) + printf ("DMA Error: status = %x\n", status); + + return status; +} + +void dma_init(void) { + volatile fsl_dma_t *dma = &dma_base->dma[0]; + + dma->satr = 0x00040000; + dma->datr = 0x00040000; + dma->sr = 0xffffffff; /* clear any errors */ + dma_sync(); +} + +int dma_xfer(void *dest, uint count, void *src) { + volatile fsl_dma_t *dma = &dma_base->dma[0]; + + dma->dar = (uint) dest; + dma->sar = (uint) src; + dma->bcr = count; + + /* Disable bandwidth control, use direct transfer mode */ + dma->mr = 0xf000004; + dma_sync(); + + /* Start the transfer */ + dma->mr = 0xf000005; + dma_sync(); + + return dma_check(); +} diff --git a/include/configs/PM854.h b/include/configs/PM854.h index 3f943aa..4b9bcca 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -96,6 +96,7 @@ #undef CONFIG_DDR_SPD #define CONFIG_DDR_DLL /* possible DLL fix needed */ #define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_FSL_DMA /* use DMA to init DDR ECC */
#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
diff --git a/include/configs/PM856.h b/include/configs/PM856.h index 43c2873..1db20bc 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -98,6 +98,7 @@ #undef CONFIG_DDR_SPD #define CONFIG_DDR_DLL /* possible DLL fix needed */ #define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_FSL_DMA /* use DMA to init DDR ECC */
#define CONFIG_MEM_INIT_VALUE 0xDeadBeef

On May 21, 2009, at 12:10 PM, Peter Tyser wrote:
DMA support is now enabled via the CONFIG_FSL_DMA define instead of the previous CONFIG_DDR_ECC
Signed-off-by: Peter Tyser ptyser@xes-inc.com
cpu/mpc85xx/cpu.c | 47 ------------------------ cpu/mpc86xx/cpu.c | 55 ---------------------------- drivers/dma/Makefile | 1 + drivers/dma/fsl_dma.c | 92 ++++++++++++++++++++++++++++++++++++++ +++++++++ include/configs/PM854.h | 1 + include/configs/PM856.h | 1 + 6 files changed, 95 insertions(+), 102 deletions(-) create mode 100644 drivers/dma/fsl_dma.c
We should add something to include/asm-ppc/config.h to ensure CONFIG_FSL_DMA is set if CONFIG_DDR_ECC is.
#if defined(CONFIG_DDR_ECC) && (defined(CONFIG_MPC86xx) || defined(CONFIG_MPC85xx)) #define CONFIG_FSL_DMA #endif
- k
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 86b19a6..416ea08 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -258,53 +258,6 @@ reset_85xx_watchdog(void) } #endif /* CONFIG_WATCHDOG */
-#if defined(CONFIG_DDR_ECC) -void dma_init(void) {
- volatile ccsr_dma_t *dma_base = (void *)
(CONFIG_SYS_MPC85xx_DMA_ADDR);
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr = 0x00040000;
- dma->datr = 0x00040000;
- dma->sr = 0xffffffff; /* clear any errors */
- asm("sync; isync; msync");
- return;
-}
-uint dma_check(void) {
- volatile ccsr_dma_t *dma_base = (void *)
(CONFIG_SYS_MPC85xx_DMA_ADDR);
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- volatile uint status = dma->sr;
- /* While the channel is busy, spin */
- while((status & 4) == 4) {
status = dma->sr;
- }
- /* clear MR[CS] channel start bit */
- dma->mr &= 0x00000001;
- asm("sync;isync;msync");
- if (status != 0) {
printf ("DMA Error: status = %x\n", status);
- }
- return status;
-}
-int dma_xfer(void *dest, uint count, void *src) {
- volatile ccsr_dma_t *dma_base = (void *)
(CONFIG_SYS_MPC85xx_DMA_ADDR);
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->dar = (uint) dest;
- dma->sar = (uint) src;
- dma->bcr = count;
- dma->mr = 0xf000004;
- asm("sync;isync;msync");
- dma->mr = 0xf000005;
- asm("sync;isync;msync");
- return dma_check();
-} -#endif
/*
- Configures a UPM. The function requires the respective MxMR to be
set
- before calling this function. "size" is the number or entries,
not a sizeof. diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index d47cc5e..1f26ba1 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -177,61 +177,6 @@ watchdog_reset(void) } #endif /* CONFIG_WATCHDOG */
-#if defined(CONFIG_DDR_ECC) -void -dma_init(void) -{
- volatile ccsr_dma_t *dma_base = (void *)
(CONFIG_SYS_MPC86xx_DMA_ADDR);
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr = 0x00040000;
- dma->datr = 0x00040000;
- dma->sr = 0xffffffff; /* clear any errors */
- asm("sync; isync");
-}
-uint -dma_check(void) -{
- volatile ccsr_dma_t *dma_base = (void *)
(CONFIG_SYS_MPC86xx_DMA_ADDR);
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- volatile uint status = dma->sr;
- /* While the channel is busy, spin */
- while ((status & 4) == 4) {
status = dma->sr;
- }
- /* clear MR[CS] channel start bit */
- dma->mr &= 0x00000001;
- asm("sync;isync");
- if (status != 0) {
printf("DMA Error: status = %x\n", status);
- }
- return status;
-}
-int -dma_xfer(void *dest, uint count, void *src) -{
- volatile ccsr_dma_t *dma_base = (void *)
(CONFIG_SYS_MPC86xx_DMA_ADDR);
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->dar = (uint) dest;
- dma->sar = (uint) src;
- dma->bcr = count;
- dma->mr = 0xf000004;
- asm("sync;isync");
- dma->mr = 0xf000005;
- asm("sync;isync");
- return dma_check();
-}
-#endif /* CONFIG_DDR_ECC */
/*
- Print out the state of various machine registers.
- Currently prints out LAWs, BR0/OR0, and BATs
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index cf29efa..36d99f9 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libdma.a
COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o +COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c new file mode 100644 index 0000000..a9989ee --- /dev/null +++ b/drivers/dma/fsl_dma.c @@ -0,0 +1,92 @@ +/*
- Copyright 2004,2007,2008 Freescale Semiconductor, Inc.
- (C) Copyright 2002, 2003 Motorola Inc.
- Xianghua Xiao (X.Xiao@motorola.com)
- (C) Copyright 2000
- Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <config.h> +#include <common.h> +#include <asm/fsl_dma.h>
+#if defined(CONFIG_MPC85xx) +volatile ccsr_dma_t *dma_base = (void *) (CONFIG_SYS_MPC85xx_DMA_ADDR); +#elif defined(CONFIG_MPC86xx) +volatile ccsr_dma_t *dma_base = (void *) (CONFIG_SYS_MPC86xx_DMA_ADDR); +#else +#error "Freescale DMA engine not supported on your processor" +#endif
+static void dma_sync(void) +{ +#if defined(CONFIG_MPC85xx)
- asm("sync; isync; msync");
+#elif defined(CONFIG_MPC86xx)
- asm("sync; isync");
+#endif +}
+static uint dma_check(void) {
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- volatile uint status = dma->sr;
- /* While the channel is busy, spin */
- while (status & 4)
status = dma->sr;
- /* clear MR[CS] channel start bit */
- dma->mr &= 1;
- dma_sync();
- if (status != 0)
printf ("DMA Error: status = %x\n", status);
- return status;
+}
+void dma_init(void) {
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr = 0x00040000;
- dma->datr = 0x00040000;
- dma->sr = 0xffffffff; /* clear any errors */
- dma_sync();
+}
+int dma_xfer(void *dest, uint count, void *src) {
- volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->dar = (uint) dest;
- dma->sar = (uint) src;
- dma->bcr = count;
- /* Disable bandwidth control, use direct transfer mode */
- dma->mr = 0xf000004;
- dma_sync();
- /* Start the transfer */
- dma->mr = 0xf000005;
- dma_sync();
- return dma_check();
+} diff --git a/include/configs/PM854.h b/include/configs/PM854.h index 3f943aa..4b9bcca 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -96,6 +96,7 @@ #undef CONFIG_DDR_SPD #define CONFIG_DDR_DLL /* possible DLL fix needed */ #define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_FSL_DMA /* use DMA to init DDR ECC */
#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
diff --git a/include/configs/PM856.h b/include/configs/PM856.h index 43c2873..1db20bc 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -98,6 +98,7 @@ #undef CONFIG_DDR_SPD #define CONFIG_DDR_DLL /* possible DLL fix needed */ #define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_FSL_DMA /* use DMA to init DDR ECC */
#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
-- 1.6.2.1
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Signed-off-by: Peter Tyser ptyser@xes-inc.com --- drivers/dma/fsl_dma.c | 12 +++++----- include/asm-ppc/fsl_dma.h | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index a9989ee..baf2942 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -51,11 +51,11 @@ static uint dma_check(void) { volatile uint status = dma->sr;
/* While the channel is busy, spin */ - while (status & 4) + while (status & FSL_DMA_SR_CB) status = dma->sr;
/* clear MR[CS] channel start bit */ - dma->mr &= 1; + dma->mr &= FSL_DMA_MR_CS; dma_sync();
if (status != 0) @@ -67,8 +67,8 @@ static uint dma_check(void) { void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr = 0x00040000; - dma->datr = 0x00040000; + dma->satr = FSL_DMA_SATR_SREAD_NO_SNOOP; + dma->datr = FSL_DMA_DATR_DWRITE_NO_SNOOP; dma->sr = 0xffffffff; /* clear any errors */ dma_sync(); } @@ -81,11 +81,11 @@ int dma_xfer(void *dest, uint count, void *src) { dma->bcr = count;
/* Disable bandwidth control, use direct transfer mode */ - dma->mr = 0xf000004; + dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT; dma_sync();
/* Start the transfer */ - dma->mr = 0xf000005; + dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_CS; dma_sync();
return dma_check(); diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index aab8720..c9ec6b5 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -29,12 +29,58 @@
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_CA 0x00000008 /* Channel abort */ +#define FSL_DMA_MR_CDSM 0x00000010 +#define FSL_DMA_MR_XFE 0x00000020 /* Extended features en */ +#define FSL_DMA_MR_EIE 0x00000040 /* Error interrupt en */ +#define FSL_DMA_MR_EOLSIE 0x00000080 /* End-of-lists interrupt en */ +#define FSL_DMA_MR_EOLNIE 0x00000100 /* End-of-links interrupt en */ +#define FSL_DMA_MR_EOSIE 0x00000200 /* End-of-seg interrupt en */ +#define FSL_DMA_MR_SRW 0x00000400 /* Single register write */ +#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_EMP_EN 0x00200000 /* Ext master pause en */ +#define FSL_DMA_MR_BWC_MASK 0x0f000000 /* Bandwidth/pause ctl */ +#define FSL_DMA_MR_BWC_DIS 0x0f000000 /* Bandwidth/pause ctl disable */ uint sr; /* DMA status register */ +#define FSL_DMA_SR_EOLSI 0x00000001 /* End-of-list interrupt */ +#define FSL_DMA_SR_EOSI 0x00000002 /* End-of-segment interrupt */ +#define FSL_DMA_SR_CB 0x00000004 /* Channel busy */ +#define FSL_DMA_SR_EOLNI 0x00000008 /* End-of-links interrupt */ +#define FSL_DMA_SR_PE 0x00000010 /* Programming error */ +#define FSL_DMA_SR_CH 0x00000020 /* Channel halted */ +#define FSL_DMA_SR_TE 0x00000080 /* Transfer error */ char res0[4]; uint clndar; /* DMA current link descriptor address register */ uint satr; /* DMA source attributes register */ +#define FSL_DMA_SATR_ESAD_MASK 0x000001ff /* Extended source addr */ +#define FSL_DMA_SATR_SREAD_NO_SNOOP 0x00040000 /* Read, don't snoop */ +#define FSL_DMA_SATR_SREAD_SNOOP 0x00050000 /* Read, snoop */ +#define FSL_DMA_SATR_SREAD_UNLOCK 0x00070000 /* Read, unlock l2 */ +#define FSL_DMA_SATR_STRAN_MASK 0x00f00000 /* Source interface */ +#define FSL_DMA_SATR_SSME 0x01000000 /* Source stride en */ +#define FSL_DMA_SATR_SPCIORDER 0x02000000 /* PCI transaction order */ +#define FSL_DMA_SATR_STFLOWLVL_MASK 0x0c000000 /* RIO flow level */ +#define FSL_DMA_SATR_SBPATRMU 0x20000000 /* Bypass ATMU */ uint sar; /* DMA source address register */ uint datr; /* DMA destination attributes register */ +#define FSL_DMA_DATR_EDAD_MASK 0x000001ff /* Extended dest addr */ +#define FSL_DMA_DATR_DWRITE_NO_SNOOP 0x00040000 /* Write, don't snoop */ +#define FSL_DMA_DATR_DWRITE_SNOOP 0x00050000 /* Write, snoop */ +#define FSL_DMA_DATR_DWRITE_ALLOC 0x00060000 /* Write, alloc l2 */ +#define FSL_DMA_DATR_DWRITE_LOCK 0x00070000 /* Write, lock l2 */ +#define FSL_DMA_DATR_DTRAN_MASK 0x00f00000 /* Dest interface */ +#define FSL_DMA_DATR_DSME 0x01000000 /* Dest stride en */ +#define FSL_DMA_DATR_DPCIORDER 0x02000000 /* PCI transaction order */ +#define FSL_DMA_DATR_DTFLOWLVL_MASK 0x0c000000 /* RIO flow level */ +#define FSL_DMA_DATR_DBPATRMU 0x20000000 /* Bypass ATMU */ uint dar; /* DMA destination address register */ uint bcr; /* DMA byte count register */ char res1[4];

Signed-off-by: Peter Tyser ptyser@xes-inc.com --- drivers/dma/fsl_dma.c | 32 ++++++++++++++++++-------------- 1 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index baf2942..33ea828 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -27,12 +27,13 @@
#include <config.h> #include <common.h> +#include <asm/io.h> #include <asm/fsl_dma.h>
#if defined(CONFIG_MPC85xx) -volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); +ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); #elif defined(CONFIG_MPC86xx) -volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); +ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); #else #error "Freescale DMA engine not supported on your processor" #endif @@ -48,14 +49,15 @@ static void dma_sync(void)
static uint dma_check(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - volatile uint status = dma->sr; + uint status;
/* While the channel is busy, spin */ - while (status & FSL_DMA_SR_CB) - status = dma->sr; + do { + status = in_be32(&dma->sr); + } while (status & FSL_DMA_SR_CB);
/* clear MR[CS] channel start bit */ - dma->mr &= FSL_DMA_MR_CS; + out_be32(&dma->mr, in_be32(&dma->mr) & FSL_DMA_MR_CS); dma_sync();
if (status != 0) @@ -67,25 +69,27 @@ static uint dma_check(void) { void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->satr = FSL_DMA_SATR_SREAD_NO_SNOOP; - dma->datr = FSL_DMA_DATR_DWRITE_NO_SNOOP; - dma->sr = 0xffffffff; /* clear any errors */ + out_be32(&dma->satr, FSL_DMA_SATR_SREAD_NO_SNOOP); + out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_NO_SNOOP); + out_be32(&dma->sr, 0xffffffff); /* clear any errors */ dma_sync(); }
int dma_xfer(void *dest, uint count, void *src) { volatile fsl_dma_t *dma = &dma_base->dma[0];
- dma->dar = (uint) dest; - dma->sar = (uint) src; - dma->bcr = count; + out_be32(&dma->dar, (uint) dest); + out_be32(&dma->sar, (uint) src); + out_be32(&dma->bcr, count);
/* Disable bandwidth control, use direct transfer mode */ - dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT; + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); dma_sync();
/* Start the transfer */ - dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_CS; + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | + FSL_DMA_MR_CTM_DIRECT | + FSL_DMA_MR_CS); dma_sync();
return dma_check();

Support DMA transfers larger than the DMA controller's limit of (2 ^ 26 - 1) bytes
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- drivers/dma/fsl_dma.c | 42 ++++++++++++++++++++++++++++++------------ 1 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 33ea828..91a6d84 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -30,6 +30,9 @@ #include <asm/io.h> #include <asm/fsl_dma.h>
+/* Controller can only transfer 2^26 - 1 bytes at a time */ +#define FSL_DMA_MAX_SIZE (0x3ffffff) + #if defined(CONFIG_MPC85xx) ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); #elif defined(CONFIG_MPC86xx) @@ -77,20 +80,35 @@ void dma_init(void) {
int dma_xfer(void *dest, uint count, void *src) { volatile fsl_dma_t *dma = &dma_base->dma[0]; + uint xfer_size;
- out_be32(&dma->dar, (uint) dest); - out_be32(&dma->sar, (uint) src); - out_be32(&dma->bcr, count); + while (count) { + xfer_size = MIN(FSL_DMA_MAX_SIZE, count);
- /* Disable bandwidth control, use direct transfer mode */ - out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); - dma_sync(); + debug("count = 0x%x, xfer_size = 0x%x, src = %p, dest = %p\n", + count, xfer_size, src, dest); + out_be32(&dma->dar, (uint) dest); + out_be32(&dma->sar, (uint) src); + out_be32(&dma->bcr, xfer_size);
- /* Start the transfer */ - out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | - FSL_DMA_MR_CTM_DIRECT | - FSL_DMA_MR_CS); - dma_sync(); + /* Disable bandwidth control, use direct transfer mode */ + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); + dma_sync(); + + /* Start the transfer */ + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | + FSL_DMA_MR_CTM_DIRECT | + FSL_DMA_MR_CS); + + count -= xfer_size; + src += xfer_size; + dest += xfer_size; + + dma_sync(); + + if (dma_check()) + return -1; + }
- return dma_check(); + return 0; }

The Channel Start (CS) bit in the Mode Register (MR) should actually be cleared as the comment in the code suggests. Previously, CS was being set, not cleared.
Assuming normal operation of the DMA engine, this change shouldn't have any real affect.
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- drivers/dma/fsl_dma.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 91a6d84..d41f04c 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -60,7 +60,7 @@ static uint dma_check(void) { } 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_be32(&dma->mr, in_be32(&dma->mr) & ~FSL_DMA_MR_CS); dma_sync();
if (status != 0)

Also update dmacpy()'s argument order and type to match memcpy's for clarity
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- board/mpc8540eval/mpc8540eval.c | 22 +++++++++++----------- board/sbc8560/sbc8560.c | 22 +++++++++++----------- cpu/mpc83xx/cpu.c | 4 ++-- cpu/mpc83xx/spd_sdram.c | 24 ++++++++++++------------ cpu/mpc85xx/ddr-gen1.c | 24 ++++++++++++------------ drivers/dma/fsl_dma.c | 12 ++++++------ 6 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/board/mpc8540eval/mpc8540eval.c b/board/mpc8540eval/mpc8540eval.c index 72a1ad3..3d395c6 100644 --- a/board/mpc8540eval/mpc8540eval.c +++ b/board/mpc8540eval/mpc8540eval.c @@ -148,28 +148,28 @@ phys_size_t initdram (int board_type) }
/* 8K */ - dma_xfer((uint *)0x2000,0x2000,(uint *)0); + dmacpy((uint *)0x2000, (uint *)0, 0x2000); /* 16K */ - dma_xfer((uint *)0x4000,0x4000,(uint *)0); + dmacpy((uint *)0x4000, (uint *)0, 0x4000); /* 32K */ - dma_xfer((uint *)0x8000,0x8000,(uint *)0); + dmacpy((uint *)0x8000, (uint *)0, 0x8000); /* 64K */ - dma_xfer((uint *)0x10000,0x10000,(uint *)0); + dmacpy((uint *)0x10000, (uint *)0, 0x10000); /* 128k */ - dma_xfer((uint *)0x20000,0x20000,(uint *)0); + dmacpy((uint *)0x20000, (uint *)0, 0x20000); /* 256k */ - dma_xfer((uint *)0x40000,0x40000,(uint *)0); + dmacpy((uint *)0x40000, (uint *)0, 0x40000); /* 512k */ - dma_xfer((uint *)0x80000,0x80000,(uint *)0); + dmacpy((uint *)0x80000, (uint *)0, 0x80000); /* 1M */ - dma_xfer((uint *)0x100000,0x100000,(uint *)0); + dmacpy((uint *)0x100000, (uint *)0, 0x100000); /* 2M */ - dma_xfer((uint *)0x200000,0x200000,(uint *)0); + dmacpy((uint *)0x200000, (uint *)0, 0x200000); /* 4M */ - dma_xfer((uint *)0x400000,0x400000,(uint *)0); + dmacpy((uint *)0x400000, (uint *)0, 0x400000);
for (i = 1; i < dram_size / 0x800000; i++) { - dma_xfer((uint *)(0x800000*i),0x800000,(uint *)0); + dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000); }
/* Enable errors for ECC */ diff --git a/board/sbc8560/sbc8560.c b/board/sbc8560/sbc8560.c index 7f032c8..0b8e3e5 100644 --- a/board/sbc8560/sbc8560.c +++ b/board/sbc8560/sbc8560.c @@ -349,28 +349,28 @@ phys_size_t initdram (int board_type) }
/* 8K */ - dma_xfer((uint *)0x2000,0x2000,(uint *)0); + dmacpy((uint *)0x2000, (uint *)0, 0x2000); /* 16K */ - dma_xfer((uint *)0x4000,0x4000,(uint *)0); + dmacpy((uint *)0x4000, (uint *)0, 0x4000); /* 32K */ - dma_xfer((uint *)0x8000,0x8000,(uint *)0); + dmacpy((uint *)0x8000, (uint *)0, 0x8000); /* 64K */ - dma_xfer((uint *)0x10000,0x10000,(uint *)0); + dmacpy((uint *)0x10000, (uint *)0, 0x10000); /* 128k */ - dma_xfer((uint *)0x20000,0x20000,(uint *)0); + dmacpy((uint *)0x20000, (uint *)0, 0x20000); /* 256k */ - dma_xfer((uint *)0x40000,0x40000,(uint *)0); + dmacpy((uint *)0x40000, (uint *)0, 0x40000); /* 512k */ - dma_xfer((uint *)0x80000,0x80000,(uint *)0); + dmacpy((uint *)0x80000, (uint *)0, 0x80000); /* 1M */ - dma_xfer((uint *)0x100000,0x100000,(uint *)0); + dmacpy((uint *)0x100000, (uint *)0, 0x100000); /* 2M */ - dma_xfer((uint *)0x200000,0x200000,(uint *)0); + dmacpy((uint *)0x200000, (uint *)0, 0x200000); /* 4M */ - dma_xfer((uint *)0x400000,0x400000,(uint *)0); + dmacpy((uint *)0x400000, (uint *)0, 0x400000);
for (i = 1; i < dram_size / 0x800000; i++) { - dma_xfer((uint *)(0x800000*i),0x800000,(uint *)0); + dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000); }
/* Enable errors for ECC */ diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 876f5c7..3b93a32 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -327,7 +327,7 @@ uint dma_check(void) return status; }
-int dma_xfer(void *dest, u32 count, void *src) +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; @@ -336,7 +336,7 @@ int dma_xfer(void *dest, u32 count, void *src) /* initialize DMASARn, DMADAR and DMAABCRn */ dma->dmadar0 = swab32((u32)dest); dma->dmasar0 = swab32((u32)src); - dma->dmabcr0 = swab32(count); + dma->dmabcr0 = swab32((u32)count);
__asm__ __volatile__ ("sync"); __asm__ __volatile__ ("isync"); diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 4704d20..12dad75 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -68,7 +68,7 @@ void board_add_ram_info(int use_default) #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) extern void dma_init(void); extern uint dma_check(void); -extern int dma_xfer(void *dest, uint count, void *src); +extern int dmacpy(void *dest, const void *src, size_t n); #endif
#ifndef CONFIG_SYS_READ_SPD @@ -898,19 +898,19 @@ void ddr_enable_ecc(unsigned int dram_size) /* Initialise DMA for direct transfer */ dma_init(); /* Start DMA to transfer */ - dma_xfer((uint *)0x2000, 0x2000, (uint *)0); /* 8K */ - dma_xfer((uint *)0x4000, 0x4000, (uint *)0); /* 16K */ - dma_xfer((uint *)0x8000, 0x8000, (uint *)0); /* 32K */ - dma_xfer((uint *)0x10000, 0x10000, (uint *)0); /* 64K */ - dma_xfer((uint *)0x20000, 0x20000, (uint *)0); /* 128K */ - dma_xfer((uint *)0x40000, 0x40000, (uint *)0); /* 256K */ - dma_xfer((uint *)0x80000, 0x80000, (uint *)0); /* 512K */ - dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */ - dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */ - dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */ + 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++) { - dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); + dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000); } #endif
diff --git a/cpu/mpc85xx/ddr-gen1.c b/cpu/mpc85xx/ddr-gen1.c index e24c9af..7c7a458 100644 --- a/cpu/mpc85xx/ddr-gen1.c +++ b/cpu/mpc85xx/ddr-gen1.c @@ -68,7 +68,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) extern void dma_init(void); extern uint dma_check(void); -extern int dma_xfer(void *dest, uint count, void *src); +extern int dmacpy(void *dest, const void *src, size_t n);
/* * Initialize all of memory for ECC, then enable errors. @@ -93,19 +93,19 @@ ddr_enable_ecc(unsigned int dram_size) } }
- dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */ - dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */ - dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */ - dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */ - dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */ - dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */ - dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */ - dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */ - dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */ - dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */ + dmacpy((uint *)0x002000, (uint *)0, 0x2000); /* 8K */ + dmacpy((uint *)0x004000, (uint *)0, 0x4000); /* 16K */ + dmacpy((uint *)0x008000, (uint *)0, 0x8000); /* 32K */ + dmacpy((uint *)0x010000, (uint *)0, 0x10000); /* 64K */ + dmacpy((uint *)0x020000, (uint *)0, 0x20000); /* 128K */ + dmacpy((uint *)0x040000, (uint *)0, 0x40000); /* 256K */ + dmacpy((uint *)0x080000, (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++) { - dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); + dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000); }
/* diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index d41f04c..90eeef7 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -78,15 +78,15 @@ void dma_init(void) { dma_sync(); }
-int dma_xfer(void *dest, uint count, void *src) { +int dmacpy(void *dest, const void *src, size_t n) { volatile fsl_dma_t *dma = &dma_base->dma[0]; uint xfer_size;
- while (count) { - xfer_size = MIN(FSL_DMA_MAX_SIZE, count); + while (n) { + xfer_size = MIN(FSL_DMA_MAX_SIZE, n);
- debug("count = 0x%x, xfer_size = 0x%x, src = %p, dest = %p\n", - count, xfer_size, src, dest); + 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); @@ -100,7 +100,7 @@ int dma_xfer(void *dest, uint count, void *src) { FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_CS);
- count -= xfer_size; + n -= xfer_size; src += xfer_size; dest += xfer_size;

On Thu, May 21, 2009 at 12:10:06PM -0500, Peter Tyser wrote:
-int dma_xfer(void *dest, uint count, void *src) { +int dmacpy(void *dest, const void *src, size_t n) {
While we're changing this, perhaps it should take phys_addr_t rather than pointers?
-Scott

On Thu, 2009-05-21 at 12:46 -0500, Scott Wood wrote:
On Thu, May 21, 2009 at 12:10:06PM -0500, Peter Tyser wrote:
-int dma_xfer(void *dest, uint count, void *src) { +int dmacpy(void *dest, const void *src, size_t n) {
While we're changing this, perhaps it should take phys_addr_t rather than pointers?
It looks like addresses > 32bits can be used by using a few bits in the SATR/DATR so you're right, using phys_addr_t/phys_size_t makes sense.
Thanks, Peter

Signed-off-by: Peter Tyser ptyser@xes-inc.com --- cpu/mpc85xx/ddr-gen1.c | 4 ---- include/asm-ppc/fsl_dma.h | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/cpu/mpc85xx/ddr-gen1.c b/cpu/mpc85xx/ddr-gen1.c index 7c7a458..6e628bd 100644 --- a/cpu/mpc85xx/ddr-gen1.c +++ b/cpu/mpc85xx/ddr-gen1.c @@ -66,10 +66,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, }
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void dma_init(void); -extern uint dma_check(void); -extern int dmacpy(void *dest, const void *src, size_t n); - /* * Initialize all of memory for ECC, then enable errors. */ diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index c9ec6b5..06ecdcd 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -94,4 +94,9 @@ typedef struct fsl_dma { char res4[56]; } fsl_dma_t;
+#ifdef CONFIG_FSL_DMA +void dma_init(void); +int dmacpy(void *dest, const void *src, size_t n); +#endif + #endif /* _ASM_DMA_H_ */

On May 21, 2009, at 12:10 PM, Peter Tyser wrote:
Signed-off-by: Peter Tyser ptyser@xes-inc.com
cpu/mpc85xx/ddr-gen1.c | 4 ---- include/asm-ppc/fsl_dma.h | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/cpu/mpc85xx/ddr-gen1.c b/cpu/mpc85xx/ddr-gen1.c index 7c7a458..6e628bd 100644 --- a/cpu/mpc85xx/ddr-gen1.c +++ b/cpu/mpc85xx/ddr-gen1.c @@ -66,10 +66,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, }
#if defined(CONFIG_DDR_ECC) && ! defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void dma_init(void); -extern uint dma_check(void); -extern int dmacpy(void *dest, const void *src, size_t n);
/*
- Initialize all of memory for ECC, then enable errors.
*/ diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index c9ec6b5..06ecdcd 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -94,4 +94,9 @@ typedef struct fsl_dma { char res4[56]; } fsl_dma_t;
+#ifdef CONFIG_FSL_DMA +void dma_init(void); +int dmacpy(void *dest, const void *src, size_t n); +#endif
#ifdef protection here seems kinda pointless
- k

Hi Kumar,
diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index c9ec6b5..06ecdcd 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -94,4 +94,9 @@ typedef struct fsl_dma { char res4[56]; } fsl_dma_t;
+#ifdef CONFIG_FSL_DMA +void dma_init(void); +int dmacpy(void *dest, const void *src, size_t n); +#endif
#ifdef protection here seems kinda pointless
Most boards won't have CONFIG_FSL_DMA defined, but this file will still be used in the immap_86xx.h files for padding immap_t. I figured most users won't have dma_init() or dmacpy() so the protection wouldn't hurt.
Peter

On Jun 22, 2009, at 6:12 PM, Peter Tyser wrote:
Hi Kumar,
diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index c9ec6b5..06ecdcd 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -94,4 +94,9 @@ typedef struct fsl_dma { char res4[56]; } fsl_dma_t;
+#ifdef CONFIG_FSL_DMA +void dma_init(void); +int dmacpy(void *dest, const void *src, size_t n); +#endif
#ifdef protection here seems kinda pointless
Most boards won't have CONFIG_FSL_DMA defined, but this file will still be used in the immap_86xx.h files for padding immap_t. I figured most users won't have dma_init() or dmacpy() so the protection wouldn't hurt.
Peter
that's fine.. do you plan on respinning the other patches that had comments?
- k

Hi Kumar,
#ifdef protection here seems kinda pointless
Most boards won't have CONFIG_FSL_DMA defined, but this file will still be used in the immap_86xx.h files for padding immap_t. I figured most users won't have dma_init() or dmacpy() so the protection wouldn't hurt.
Peter
that's fine.. do you plan on respinning the other patches that had comments?
Yes, I will resend today.
Peter

Signed-off-by: Peter Tyser ptyser@xes-inc.com --- board/mpc8540eval/mpc8540eval.c | 2 +- board/sbc8560/sbc8560.c | 2 +- cpu/mpc85xx/cpu_init.c | 4 +++- cpu/mpc85xx/ddr-gen1.c | 2 -- cpu/mpc86xx/cpu_init.c | 3 +++ 5 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/board/mpc8540eval/mpc8540eval.c b/board/mpc8540eval/mpc8540eval.c index 3d395c6..27d7a3d 100644 --- a/board/mpc8540eval/mpc8540eval.c +++ b/board/mpc8540eval/mpc8540eval.c @@ -140,7 +140,7 @@ phys_size_t initdram (int board_type) uint *p = 0; uint i = 0; volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); - dma_init(); + for (*p = 0; p < (uint *)(8 * 1024); p++) { if (((unsigned int)p & 0x1f) == 0) { dcbz(p); } *p = (unsigned int)0xdeadbeef; diff --git a/board/sbc8560/sbc8560.c b/board/sbc8560/sbc8560.c index 0b8e3e5..64d4154 100644 --- a/board/sbc8560/sbc8560.c +++ b/board/sbc8560/sbc8560.c @@ -341,7 +341,7 @@ phys_size_t initdram (int board_type) uint *p = 0; uint i = 0; volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); - dma_init(); + for (*p = 0; p < (uint *)(8 * 1024); p++) { if (((unsigned int)p & 0x1f) == 0) { dcbz(p); } *p = (unsigned int)0xdeadbeef; diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index c98dd8d..41de694 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -261,7 +261,9 @@ void cpu_init_f (void) #if defined(CONFIG_MPC8536) fsl_serdes_init(); #endif - +#if defined(CONFIG_FSL_DMA) + dma_init(); +#endif }
diff --git a/cpu/mpc85xx/ddr-gen1.c b/cpu/mpc85xx/ddr-gen1.c index 6e628bd..5529021 100644 --- a/cpu/mpc85xx/ddr-gen1.c +++ b/cpu/mpc85xx/ddr-gen1.c @@ -77,8 +77,6 @@ ddr_enable_ecc(unsigned int dram_size) uint i = 0; volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
- dma_init(); - for (*p = 0; p < (uint *)(8 * 1024); p++) { if (((unsigned int)p & 0x1f) == 0) { ppcDcbz((unsigned long) p); diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c index 49528aa..341e815 100644 --- a/cpu/mpc86xx/cpu_init.c +++ b/cpu/mpc86xx/cpu_init.c @@ -113,6 +113,9 @@ void cpu_init_f(void) memctl->or7 = CONFIG_SYS_OR7_PRELIM; memctl->br7 = CONFIG_SYS_BR7_PRELIM; #endif +#if defined(CONFIG_FSL_DMA) + dma_init(); +#endif
/* enable the timebase bit in HID0 */ set_hid0(get_hid0() | 0x4000000);

Signed-off-by: Peter Tyser ptyser@xes-inc.com --- board/mpc8540eval/mpc8540eval.c | 33 +-------------------------------- board/sbc8560/sbc8560.c | 33 +-------------------------------- cpu/mpc85xx/ddr-gen1.c | 27 +-------------------------- drivers/dma/fsl_dma.c | 32 ++++++++++++++++++++++++++++++++ include/asm-ppc/fsl_dma.h | 3 +++ 5 files changed, 38 insertions(+), 90 deletions(-)
diff --git a/board/mpc8540eval/mpc8540eval.c b/board/mpc8540eval/mpc8540eval.c index 27d7a3d..7c27233 100644 --- a/board/mpc8540eval/mpc8540eval.c +++ b/board/mpc8540eval/mpc8540eval.c @@ -137,40 +137,9 @@ phys_size_t initdram (int board_type) { /* Initialize all of memory for ECC, then * enable errors */ - uint *p = 0; - uint i = 0; volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
- for (*p = 0; p < (uint *)(8 * 1024); p++) { - if (((unsigned int)p & 0x1f) == 0) { dcbz(p); } - *p = (unsigned int)0xdeadbeef; - if (((unsigned int)p & 0x1c) == 0x1c) { dcbf(p); } - } - - /* 8K */ - dmacpy((uint *)0x2000, (uint *)0, 0x2000); - /* 16K */ - dmacpy((uint *)0x4000, (uint *)0, 0x4000); - /* 32K */ - dmacpy((uint *)0x8000, (uint *)0, 0x8000); - /* 64K */ - dmacpy((uint *)0x10000, (uint *)0, 0x10000); - /* 128k */ - dmacpy((uint *)0x20000, (uint *)0, 0x20000); - /* 256k */ - dmacpy((uint *)0x40000, (uint *)0, 0x40000); - /* 512k */ - dmacpy((uint *)0x80000, (uint *)0, 0x80000); - /* 1M */ - dmacpy((uint *)0x100000, (uint *)0, 0x100000); - /* 2M */ - dmacpy((uint *)0x200000, (uint *)0, 0x200000); - /* 4M */ - dmacpy((uint *)0x400000, (uint *)0, 0x400000); - - for (i = 1; i < dram_size / 0x800000; i++) { - dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000); - } + dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
/* Enable errors for ECC */ ddr->err_disable = 0x00000000; diff --git a/board/sbc8560/sbc8560.c b/board/sbc8560/sbc8560.c index 64d4154..c40b5e3 100644 --- a/board/sbc8560/sbc8560.c +++ b/board/sbc8560/sbc8560.c @@ -338,40 +338,9 @@ phys_size_t initdram (int board_type) { /* Initialize all of memory for ECC, then * enable errors */ - uint *p = 0; - uint i = 0; volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
- for (*p = 0; p < (uint *)(8 * 1024); p++) { - if (((unsigned int)p & 0x1f) == 0) { dcbz(p); } - *p = (unsigned int)0xdeadbeef; - if (((unsigned int)p & 0x1c) == 0x1c) { dcbf(p); } - } - - /* 8K */ - dmacpy((uint *)0x2000, (uint *)0, 0x2000); - /* 16K */ - dmacpy((uint *)0x4000, (uint *)0, 0x4000); - /* 32K */ - dmacpy((uint *)0x8000, (uint *)0, 0x8000); - /* 64K */ - dmacpy((uint *)0x10000, (uint *)0, 0x10000); - /* 128k */ - dmacpy((uint *)0x20000, (uint *)0, 0x20000); - /* 256k */ - dmacpy((uint *)0x40000, (uint *)0, 0x40000); - /* 512k */ - dmacpy((uint *)0x80000, (uint *)0, 0x80000); - /* 1M */ - dmacpy((uint *)0x100000, (uint *)0, 0x100000); - /* 2M */ - dmacpy((uint *)0x200000, (uint *)0, 0x200000); - /* 4M */ - dmacpy((uint *)0x400000, (uint *)0, 0x400000); - - for (i = 1; i < dram_size / 0x800000; i++) { - dmacpy((uint *)(0x800000*i), (uint *)0, 0x800000); - } + dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
/* Enable errors for ECC */ ddr->err_disable = 0x00000000; diff --git a/cpu/mpc85xx/ddr-gen1.c b/cpu/mpc85xx/ddr-gen1.c index 5529021..54437dd 100644 --- a/cpu/mpc85xx/ddr-gen1.c +++ b/cpu/mpc85xx/ddr-gen1.c @@ -73,34 +73,9 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, void ddr_enable_ecc(unsigned int dram_size) { - uint *p = 0; - uint i = 0; volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
- for (*p = 0; p < (uint *)(8 * 1024); p++) { - if (((unsigned int)p & 0x1f) == 0) { - ppcDcbz((unsigned long) p); - } - *p = (unsigned int)CONFIG_MEM_INIT_VALUE; - if (((unsigned int)p & 0x1c) == 0x1c) { - ppcDcbf((unsigned long) p); - } - } - - dmacpy((uint *)0x002000, (uint *)0, 0x2000); /* 8K */ - dmacpy((uint *)0x004000, (uint *)0, 0x4000); /* 16K */ - dmacpy((uint *)0x008000, (uint *)0, 0x8000); /* 32K */ - dmacpy((uint *)0x010000, (uint *)0, 0x10000); /* 64K */ - dmacpy((uint *)0x020000, (uint *)0, 0x20000); /* 128K */ - dmacpy((uint *)0x040000, (uint *)0, 0x40000); /* 256K */ - dmacpy((uint *)0x080000, (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); - } + dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
/* * Enable errors for ECC. diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 90eeef7..b7497b5 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -112,3 +112,35 @@ int dmacpy(void *dest, const void *src, size_t n) {
return 0; } + +#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) +void dma_meminit(uint val, uint size) +{ + uint *p = 0; + uint i = 0; + + for (*p = 0; p < (uint *)(8 * 1024); p++) { + if (((uint)p & 0x1f) == 0) + ppcDcbz((ulong)p); + + *p = (uint)CONFIG_MEM_INIT_VALUE; + + if (((uint)p & 0x1c) == 0x1c) + ppcDcbf((ulong)p); + } + + dmacpy((uint *)0x002000, (uint *)0, 0x002000); /* 8K */ + dmacpy((uint *)0x004000, (uint *)0, 0x004000); /* 16K */ + dmacpy((uint *)0x008000, (uint *)0, 0x008000); /* 32K */ + dmacpy((uint *)0x010000, (uint *)0, 0x010000); /* 64K */ + dmacpy((uint *)0x020000, (uint *)0, 0x020000); /* 128K */ + dmacpy((uint *)0x040000, (uint *)0, 0x040000); /* 256K */ + dmacpy((uint *)0x080000, (uint *)0, 0x080000); /* 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 < size / 0x800000; i++) + dmacpy((uint *)(0x800000 * i), (uint *)0, 0x800000); +} +#endif diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index 06ecdcd..dd92343 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -97,6 +97,9 @@ typedef struct fsl_dma { #ifdef CONFIG_FSL_DMA void dma_init(void); int dmacpy(void *dest, const void *src, size_t n); +#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) +void dma_meminit(uint val, uint size); +#endif #endif
#endif /* _ASM_DMA_H_ */

On Thu, May 21, 2009 at 12:09:58PM -0500, Peter Tyser wrote:
This patch series attempts to clean up the DMA implementation for the 85xx and 86xx architectures. The changes include:
- consolidate 85xx and 86xx structures and code
- add defines for bitfields
- use proper IO accessors
- add support for arbitrarily large transfer sizes
- rename dma_xfer() to dmacpy() and make dmacpy's prototype similar to memcpy()
The patches are based on the mainline "next" branch.
I've tested the code on MPC8572 and MPC8640-based boards.
I'm not initimately familar with the 83xx platform, but at a glance it looked like the fsl_dma driver could be extended to support it with some ifdeffery.
I've been doing some Linux work with the 83xx DMA controller. The only real differences between the 83xx/85xx controller are the register endianness and snoop bits. The 83xx controller's registers are all little-endian, while the 85xx is all big-endian.
Also, there are some snoop bits that need to be enabled on 83xx as well, in the control register as well as in each descriptor if you're running in chaining mode.
That's everything that I've noticed that is different. I don't have an 85xx/86xx to test anything with, but I'm happy to run some tests on my mpc8349emds if you want to try adding support for 83xx.
Ira

On Thu, 2009-05-21 at 12:37 -0700, Ira Snyder wrote:
On Thu, May 21, 2009 at 12:09:58PM -0500, Peter Tyser wrote:
This patch series attempts to clean up the DMA implementation for the 85xx and 86xx architectures. The changes include:
- consolidate 85xx and 86xx structures and code
- add defines for bitfields
- use proper IO accessors
- add support for arbitrarily large transfer sizes
- rename dma_xfer() to dmacpy() and make dmacpy's prototype similar to memcpy()
The patches are based on the mainline "next" branch.
I've tested the code on MPC8572 and MPC8640-based boards.
I'm not initimately familar with the 83xx platform, but at a glance it looked like the fsl_dma driver could be extended to support it with some ifdeffery.
I've been doing some Linux work with the 83xx DMA controller. The only real differences between the 83xx/85xx controller are the register endianness and snoop bits. The 83xx controller's registers are all little-endian, while the 85xx is all big-endian.
Also, there are some snoop bits that need to be enabled on 83xx as well, in the control register as well as in each descriptor if you're running in chaining mode.
That's everything that I've noticed that is different. I don't have an 85xx/86xx to test anything with, but I'm happy to run some tests on my mpc8349emds if you want to try adding support for 83xx.
Thanks!
I believe some of the register locations are slightly different too, for example the source address on the 85xx is at offset 0x114 while its at 0x110 on the 83xx.
I don't think any 83xx boards currently use the 83xx DMA implementation in cpu/mpc83xx/cpu.c. Before spending any time on the 83xx, is there any good reason to support the 83xx in U-Boot? There would be no users of the updated implementation as is.
Best, Peter

On Thu, May 21, 2009 at 03:49:29PM -0500, Peter Tyser wrote:
On Thu, 2009-05-21 at 12:37 -0700, Ira Snyder wrote:
On Thu, May 21, 2009 at 12:09:58PM -0500, Peter Tyser wrote:
This patch series attempts to clean up the DMA implementation for the 85xx and 86xx architectures. The changes include:
- consolidate 85xx and 86xx structures and code
- add defines for bitfields
- use proper IO accessors
- add support for arbitrarily large transfer sizes
- rename dma_xfer() to dmacpy() and make dmacpy's prototype similar to memcpy()
The patches are based on the mainline "next" branch.
I've tested the code on MPC8572 and MPC8640-based boards.
I'm not initimately familar with the 83xx platform, but at a glance it looked like the fsl_dma driver could be extended to support it with some ifdeffery.
I've been doing some Linux work with the 83xx DMA controller. The only real differences between the 83xx/85xx controller are the register endianness and snoop bits. The 83xx controller's registers are all little-endian, while the 85xx is all big-endian.
Also, there are some snoop bits that need to be enabled on 83xx as well, in the control register as well as in each descriptor if you're running in chaining mode.
That's everything that I've noticed that is different. I don't have an 85xx/86xx to test anything with, but I'm happy to run some tests on my mpc8349emds if you want to try adding support for 83xx.
Thanks!
I believe some of the register locations are slightly different too, for example the source address on the 85xx is at offset 0x114 while its at 0x110 on the 83xx.
I don't think any 83xx boards currently use the 83xx DMA implementation in cpu/mpc83xx/cpu.c. Before spending any time on the 83xx, is there any good reason to support the 83xx in U-Boot? There would be no users of the updated implementation as is.
I think there is an option for the mpc8349emds to use the DMA controller to initialize the RAM for ECC mode. I tried using it, and it was much slower than using the CPU.
I'll probably end up writing a virtual network driver for U-Boot eventually. In the Linux version, I've used the DMA controller to handle transferring data over PCI. It is much faster than the CPU, but I'll only be transferring a few megabytes from within U-Boot anyway.
In short, having the driver ported to 83xx would make some of my future development easier, but there aren't any serious in-tree users at the moment (to the best of my knowledge).
Ira

On Thu, May 21, 2009 at 2:37 PM, Ira Snyder iws@ovro.caltech.edu wrote:
I've been doing some Linux work with the 83xx DMA controller. The only real differences between the 83xx/85xx controller are the register endianness and snoop bits. The 83xx controller's registers are all little-endian, while the 85xx is all big-endian.
83xx DMA = Elo DMA controller 85xx/86xx DMA = Elo Plus DMA controller
The Elo Plus supports list descriptors in addition to link descriptors. The Elo only supports link descriptors.
participants (5)
-
Ira Snyder
-
Kumar Gala
-
Peter Tyser
-
Scott Wood
-
Timur Tabi