From e94e460c6e8741f42dab6d8dd4b596ba5d9d79ae Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:51 -0500 Subject: [PATCH] 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(-) diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index a5c1f00b10..e38a3722ca 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 824396835a..0f611804a0 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 cba5d5b8a8..df33e7a3ee 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 9c358aa413..ca143c7fef 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 043669e433..11641912a6 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 8f945a1519..7c6a15185e 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 c5bd6cb16a..fd742c7809 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 -- 2.30.2