From 017f11f68ef543e866be033bcb7b8058a8a380d8 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:40 -0500 Subject: 8xxx: Break out DMA code to a common file DMA support is now enabled via the CONFIG_FSL_DMA define instead of the previous CONFIG_DDR_ECC Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/Makefile | 1 + drivers/dma/fsl_dma.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 drivers/dma/fsl_dma.c (limited to 'drivers') diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index cf29efa0272..36d99f9b111 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 00000000000..a9989ee5cb7 --- /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 +#include +#include + +#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(); +} -- cgit v1.3.1 From 9c06071a6077ba95e9d43226156e39567d5d064a Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:41 -0500 Subject: fsl_dma: Add bitfield definitions for common registers Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 12 ++++++------ include/asm-ppc/fsl_dma.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index a9989ee5cb7..baf29420f0b 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 aab8720977e..c9ec6b59e69 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]; -- cgit v1.3.1 From a730393a362741c318b21771b8d7b2647e546c3e Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:42 -0500 Subject: fsl_dma: Use proper I/O access functions Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index baf29420f0b..33ea8285eb7 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -27,12 +27,13 @@ #include #include +#include #include #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(); -- cgit v1.3.1 From 51402ac12be9a0025f16db51fbde7c050a54e5fe Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:43 -0500 Subject: fsl_dma: Add support for arbitrarily large transfers Support DMA transfers larger than the DMA controller's limit of (2 ^ 26 - 1) bytes Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 33ea8285eb7..f3575af6d71 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -30,6 +30,9 @@ #include #include +/* 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,33 @@ 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(); + 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; } -- cgit v1.3.1 From 484919cf3351212ebf748b9b13ece1ddaf7e7d1c Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:44 -0500 Subject: fsl_dma: Fix Channel Start bug in dma_check() 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 Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index f3575af6d71..f05880230b4 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) -- cgit v1.3.1 From 7892f619d40f4196e41e7114c5dfee9fad0f572f Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:45 -0500 Subject: 8xxx: Rename dma_xfer() to dmacpy() Also update dmacpy()'s argument order to match memcpy's and use phys_addr_t/phy_size_t for address/size arguments Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- board/mpc8540eval/mpc8540eval.c | 25 ++++++++++++------------- board/sbc8560/sbc8560.c | 25 ++++++++++++------------- cpu/mpc83xx/cpu.c | 4 ++-- cpu/mpc83xx/spd_sdram.c | 29 ++++++++++++++--------------- cpu/mpc85xx/ddr-gen1.c | 29 ++++++++++++++--------------- drivers/dma/fsl_dma.c | 2 +- 6 files changed, 55 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/board/mpc8540eval/mpc8540eval.c b/board/mpc8540eval/mpc8540eval.c index 72a1ad32f7a..ed6bbb46eaa 100644 --- a/board/mpc8540eval/mpc8540eval.c +++ b/board/mpc8540eval/mpc8540eval.c @@ -148,29 +148,28 @@ phys_size_t initdram (int board_type) } /* 8K */ - dma_xfer((uint *)0x2000,0x2000,(uint *)0); + dmacpy(0x2000, 0, 0x2000); /* 16K */ - dma_xfer((uint *)0x4000,0x4000,(uint *)0); + dmacpy(0x4000, 0, 0x4000); /* 32K */ - dma_xfer((uint *)0x8000,0x8000,(uint *)0); + dmacpy(0x8000, 0, 0x8000); /* 64K */ - dma_xfer((uint *)0x10000,0x10000,(uint *)0); + dmacpy(0x10000, 0, 0x10000); /* 128k */ - dma_xfer((uint *)0x20000,0x20000,(uint *)0); + dmacpy(0x20000, 0, 0x20000); /* 256k */ - dma_xfer((uint *)0x40000,0x40000,(uint *)0); + dmacpy(0x40000, 0, 0x40000); /* 512k */ - dma_xfer((uint *)0x80000,0x80000,(uint *)0); + dmacpy(0x80000, 0, 0x80000); /* 1M */ - dma_xfer((uint *)0x100000,0x100000,(uint *)0); + dmacpy(0x100000, 0, 0x100000); /* 2M */ - dma_xfer((uint *)0x200000,0x200000,(uint *)0); + dmacpy(0x200000, 0, 0x200000); /* 4M */ - dma_xfer((uint *)0x400000,0x400000,(uint *)0); + dmacpy(0x400000, 0, 0x400000); - for (i = 1; i < dram_size / 0x800000; i++) { - dma_xfer((uint *)(0x800000*i),0x800000,(uint *)0); - } + for (i = 1; i < dram_size / 0x800000; i++) + dmacpy(0x800000 * i, 0, 0x800000); /* Enable errors for ECC */ ddr->err_disable = 0x00000000; diff --git a/board/sbc8560/sbc8560.c b/board/sbc8560/sbc8560.c index 7f032c8fad8..f8527f9cccc 100644 --- a/board/sbc8560/sbc8560.c +++ b/board/sbc8560/sbc8560.c @@ -349,29 +349,28 @@ phys_size_t initdram (int board_type) } /* 8K */ - dma_xfer((uint *)0x2000,0x2000,(uint *)0); + dmacpy(0x2000, 0, 0x2000); /* 16K */ - dma_xfer((uint *)0x4000,0x4000,(uint *)0); + dmacpy(0x4000, 0, 0x4000); /* 32K */ - dma_xfer((uint *)0x8000,0x8000,(uint *)0); + dmacpy(0x8000, 0, 0x8000); /* 64K */ - dma_xfer((uint *)0x10000,0x10000,(uint *)0); + dmacpy(0x10000, 0, 0x10000); /* 128k */ - dma_xfer((uint *)0x20000,0x20000,(uint *)0); + dmacpy(0x20000, 0, 0x20000); /* 256k */ - dma_xfer((uint *)0x40000,0x40000,(uint *)0); + dmacpy(0x40000, 0, 0x40000); /* 512k */ - dma_xfer((uint *)0x80000,0x80000,(uint *)0); + dmacpy(0x80000, 0, 0x80000); /* 1M */ - dma_xfer((uint *)0x100000,0x100000,(uint *)0); + dmacpy(0x100000, 0, 0x100000); /* 2M */ - dma_xfer((uint *)0x200000,0x200000,(uint *)0); + dmacpy(0x200000, 0, 0x200000); /* 4M */ - dma_xfer((uint *)0x400000,0x400000,(uint *)0); + dmacpy(0x400000, 0, 0x400000); - for (i = 1; i < dram_size / 0x800000; i++) { - dma_xfer((uint *)(0x800000*i),0x800000,(uint *)0); - } + for (i = 1; i < dram_size / 0x800000; i++) + dmacpy(0x800000 * i, 0, 0x800000); /* Enable errors for ECC */ ddr->err_disable = 0x00000000; diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index c4331ae97ee..a5c1f00b10b 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(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; @@ -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 4704d2006f5..97ca7007fcf 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(phys_addr_t dest, phys_addr_t src, phys_size_t n); #endif #ifndef CONFIG_SYS_READ_SPD @@ -898,20 +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 */ - - for (i = 1; i < dram_size / 0x800000; i++) { - dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); - } + 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/cpu/mpc85xx/ddr-gen1.c b/cpu/mpc85xx/ddr-gen1.c index e24c9afaf59..b188906f805 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(phys_addr_t dest, phys_addr_t src, phys_size_t n); /* * Initialize all of memory for ECC, then enable errors. @@ -93,20 +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 */ - - for (i = 1; i < dram_size / 0x800000; i++) { - dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); - } + dmacpy(0x002000, 0, 0x2000); /* 8K */ + dmacpy(0x004000, 0, 0x4000); /* 16K */ + dmacpy(0x008000, 0, 0x8000); /* 32K */ + dmacpy(0x010000, 0, 0x10000); /* 64K */ + dmacpy(0x020000, 0, 0x20000); /* 128K */ + dmacpy(0x040000, 0, 0x40000); /* 256K */ + dmacpy(0x080000, 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); /* * Enable errors for ECC. diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index f05880230b4..49ea8f105da 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -78,7 +78,7 @@ void dma_init(void) { dma_sync(); } -int dma_xfer(void *dest, uint count, void *src) { +int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { volatile fsl_dma_t *dma = &dma_base->dma[0]; uint xfer_size; -- cgit v1.3.1 From 0d595f76bc9c7c8dff5bd31dffed87a840a03c56 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:48 -0500 Subject: fsl_dma: Break out common memory initialization function Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- board/mpc8540eval/mpc8540eval.c | 32 +------------------------------- board/sbc8560/sbc8560.c | 32 +------------------------------- cpu/mpc85xx/ddr-gen1.c | 26 +------------------------- drivers/dma/fsl_dma.c | 32 ++++++++++++++++++++++++++++++++ include/asm-ppc/fsl_dma.h | 3 +++ 5 files changed, 38 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/board/mpc8540eval/mpc8540eval.c b/board/mpc8540eval/mpc8540eval.c index 04a7470c423..7c272334aa5 100644 --- a/board/mpc8540eval/mpc8540eval.c +++ b/board/mpc8540eval/mpc8540eval.c @@ -137,39 +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(0x2000, 0, 0x2000); - /* 16K */ - dmacpy(0x4000, 0, 0x4000); - /* 32K */ - dmacpy(0x8000, 0, 0x8000); - /* 64K */ - dmacpy(0x10000, 0, 0x10000); - /* 128k */ - dmacpy(0x20000, 0, 0x20000); - /* 256k */ - dmacpy(0x40000, 0, 0x40000); - /* 512k */ - dmacpy(0x80000, 0, 0x80000); - /* 1M */ - dmacpy(0x100000, 0, 0x100000); - /* 2M */ - dmacpy(0x200000, 0, 0x200000); - /* 4M */ - dmacpy(0x400000, 0, 0x400000); - - for (i = 1; i < dram_size / 0x800000; i++) - dmacpy(0x800000 * i, 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 17f900bd1af..c40b5e38ddd 100644 --- a/board/sbc8560/sbc8560.c +++ b/board/sbc8560/sbc8560.c @@ -338,39 +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(0x2000, 0, 0x2000); - /* 16K */ - dmacpy(0x4000, 0, 0x4000); - /* 32K */ - dmacpy(0x8000, 0, 0x8000); - /* 64K */ - dmacpy(0x10000, 0, 0x10000); - /* 128k */ - dmacpy(0x20000, 0, 0x20000); - /* 256k */ - dmacpy(0x40000, 0, 0x40000); - /* 512k */ - dmacpy(0x80000, 0, 0x80000); - /* 1M */ - dmacpy(0x100000, 0, 0x100000); - /* 2M */ - dmacpy(0x200000, 0, 0x200000); - /* 4M */ - dmacpy(0x400000, 0, 0x400000); - - for (i = 1; i < dram_size / 0x800000; i++) - dmacpy(0x800000 * i, 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 3bf872b6fbb..54437dd0cbd 100644 --- a/cpu/mpc85xx/ddr-gen1.c +++ b/cpu/mpc85xx/ddr-gen1.c @@ -73,33 +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(0x002000, 0, 0x2000); /* 8K */ - dmacpy(0x004000, 0, 0x4000); /* 16K */ - dmacpy(0x008000, 0, 0x8000); /* 32K */ - dmacpy(0x010000, 0, 0x10000); /* 64K */ - dmacpy(0x020000, 0, 0x20000); /* 128K */ - dmacpy(0x040000, 0, 0x40000); /* 256K */ - dmacpy(0x080000, 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); + 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 49ea8f105da..e103c910fdd 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -110,3 +110,35 @@ 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)) +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(0x002000, 0, 0x002000); /* 8K */ + dmacpy(0x004000, 0, 0x004000); /* 16K */ + dmacpy(0x008000, 0, 0x008000); /* 32K */ + dmacpy(0x010000, 0, 0x010000); /* 64K */ + dmacpy(0x020000, 0, 0x020000); /* 128K */ + dmacpy(0x040000, 0, 0x040000); /* 256K */ + dmacpy(0x080000, 0, 0x080000); /* 512K */ + dmacpy(0x100000, 0, 0x100000); /* 1M */ + dmacpy(0x200000, 0, 0x200000); /* 2M */ + dmacpy(0x400000, 0, 0x400000); /* 4M */ + + for (i = 1; i < size / 0x800000; i++) + dmacpy((0x800000 * i), 0, 0x800000); +} +#endif diff --git a/include/asm-ppc/fsl_dma.h b/include/asm-ppc/fsl_dma.h index 978283a8c41..043669e4336 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(phys_addr_t dest, phys_addr_t src, phys_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_ */ -- cgit v1.3.1 From 6af015b86b86d94de7ca1b23a3890bc93a50c2ab Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:49 -0500 Subject: fsl_dma: Make DMA transactions snoopable Make DMA transactions snoopable so that CPUs can keep caches up-to-date. This allows dma transactions to be used for operations such as memory copies without any additional cache control operations. Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index e103c910fdd..cba5d5b8a84 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -72,8 +72,8 @@ static uint dma_check(void) { void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - out_be32(&dma->satr, FSL_DMA_SATR_SREAD_NO_SNOOP); - out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_NO_SNOOP); + 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 */ dma_sync(); } -- cgit v1.3.1 From e94e460c6e8741f42dab6d8dd4b596ba5d9d79ae Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:51 -0500 Subject: 83xx: Add support for fsl_dma driver Signed-off-by: Peter Tyser Reviewed-by: Ira W. Snyder Tested-by: Ira W. Snyder Acked-by: Kim Phillips Signed-off-by: Kumar Gala --- 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(-) (limited to 'drivers') diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index a5c1f00b10b..e38a3722ca2 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 824396835a3..0f611804a07 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 cba5d5b8a84..df33e7a3eec 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 9c358aa4135..ca143c7fef7 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 043669e4336..11641912a65 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -27,6 +27,41 @@ #include +#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 8f945a15196..7c6a15185e1 100644 --- a/include/asm-ppc/immap_83xx.h +++ b/include/asm-ppc/immap_83xx.h @@ -32,6 +32,7 @@ #include #include #include +#include /* * 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 c5bd6cb16ab..fd742c7809d 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 -- cgit v1.3.1