diff options
| author | Peter Tyser <ptyser@xes-inc.com> | 2009-06-30 17:15:51 -0500 | 
|---|---|---|
| committer | Kumar Gala <galak@kernel.crashing.org> | 2009-07-02 11:15:57 -0500 | 
| commit | e94e460c6e8741f42dab6d8dd4b596ba5d9d79ae (patch) | |
| tree | 35d8c3f5a8070fe16cffb4d4212fe469a2d8a69b | |
| parent | 9adda5459ca62120c0c50b82b766fe1cf6925bbf (diff) | |
| download | olio-uboot-2014.01-e94e460c6e8741f42dab6d8dd4b596ba5d9d79ae.tar.xz olio-uboot-2014.01-e94e460c6e8741f42dab6d8dd4b596ba5d9d79ae.zip | |
83xx: Add support for fsl_dma driver
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Reviewed-by: Ira W. Snyder <iws@ovro.caltech.edu>
Tested-by: Ira W. Snyder <iws@ovro.caltech.edu>
Acked-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
| -rw-r--r-- | cpu/mpc83xx/cpu.c | 85 | ||||
| -rw-r--r-- | cpu/mpc83xx/spd_sdram.c | 40 | ||||
| -rw-r--r-- | drivers/dma/fsl_dma.c | 64 | ||||
| -rw-r--r-- | include/asm-ppc/config.h | 5 | ||||
| -rw-r--r-- | include/asm-ppc/fsl_dma.h | 36 | ||||
| -rw-r--r-- | include/asm-ppc/immap_83xx.h | 49 | ||||
| -rw-r--r-- | include/mpc83xx.h | 16 | 
7 files changed, 96 insertions, 199 deletions
| diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index a5c1f00b1..e38a3722c 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 824396835..0f611804a 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 cba5d5b8a..df33e7a3e 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 9c358aa41..ca143c7fe 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 043669e43..11641912a 100644 --- a/include/asm-ppc/fsl_dma.h +++ b/include/asm-ppc/fsl_dma.h @@ -27,6 +27,41 @@  #include <asm/types.h> +#ifdef CONFIG_MPC83xx +typedef struct fsl_dma { +	uint	mr;		/* DMA mode register */ +#define FSL_DMA_MR_CS		0x00000001	/* Channel start */ +#define FSL_DMA_MR_CC		0x00000002	/* Channel continue */ +#define FSL_DMA_MR_CTM		0x00000004	/* Channel xfer mode */ +#define FSL_DMA_MR_CTM_DIRECT	0x00000004	/* Direct channel xfer mode */ +#define FSL_DMA_MR_EOTIE	0x00000080	/* End-of-transfer interrupt en */ +#define FSL_DMA_MR_PRC_MASK	0x00000c00	/* PCI read command */ +#define FSL_DMA_MR_SAHE		0x00001000	/* Source addr hold enable */ +#define FSL_DMA_MR_DAHE		0x00002000	/* Dest addr hold enable */ +#define FSL_DMA_MR_SAHTS_MASK	0x0000c000	/* Source addr hold xfer size */ +#define FSL_DMA_MR_DAHTS_MASK	0x00030000	/* Dest addr hold xfer size */ +#define FSL_DMA_MR_EMS_EN	0x00040000	/* Ext master start en */ +#define FSL_DMA_MR_IRQS		0x00080000	/* Interrupt steer */ +#define FSL_DMA_MR_DMSEN	0x00100000	/* Direct mode snooping en */ +#define FSL_DMA_MR_BWC_MASK	0x00e00000	/* Bandwidth/pause ctl */ +#define FSL_DMA_MR_DRCNT	0x0f000000	/* DMA request count */ +	uint	sr;		/* DMA status register */ +#define FSL_DMA_SR_EOCDI	0x00000001	/* End-of-chain/direct interrupt */ +#define FSL_DMA_SR_EOSI		0x00000002	/* End-of-segment interrupt */ +#define FSL_DMA_SR_CB		0x00000004	/* Channel busy */ +#define FSL_DMA_SR_TE		0x00000080	/* Transfer error */ +	uint	cdar;		/* DMA current descriptor address register */ +	char	res0[4]; +	uint	sar;		/* DMA source address register */ +	char	res1[4]; +	uint	dar;		/* DMA destination address register */ +	char	res2[4]; +	uint	bcr;		/* DMA byte count register */ +	uint	ndar;		/* DMA next descriptor address register */ +	uint	gsr;		/* DMA general status register (DMA3 ONLY!) */ +	char	res3[84]; +} fsl_dma_t; +#else  typedef struct fsl_dma {  	uint	mr;		/* DMA mode register */  #define FSL_DMA_MR_CS		0x00000001	/* Channel start */ @@ -93,6 +128,7 @@ typedef struct fsl_dma {  	uint	dsr;		/* DMA destination stride register */  	char	res4[56];  } fsl_dma_t; +#endif /* !CONFIG_MPC83xx */  #ifdef CONFIG_FSL_DMA  void dma_init(void); diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h index 8f945a151..7c6a15185 100644 --- a/include/asm-ppc/immap_83xx.h +++ b/include/asm-ppc/immap_83xx.h @@ -32,6 +32,7 @@  #include <asm/fsl_i2c.h>  #include <asm/mpc8xxx_spi.h>  #include <asm/fsl_lbc.h> +#include <asm/fsl_dma.h>  /*   * Local Access Window @@ -367,51 +368,7 @@ typedef struct dma83xx {  	u32 imisr;		/* 0x80 Inbound message interrupt status register */  	u32 imimr;		/* 0x84 Inbound message interrupt mask register */  	u32 res4[0x1E];		/* 0x88-0x99 reserved */ -	u32 dmamr0;		/* 0x100 DMA 0 mode register */ -	u32 dmasr0;		/* 0x104 DMA 0 status register */ -	u32 dmacdar0;		/* 0x108 DMA 0 current descriptor address register */ -	u32 res5;		/* 0x10C reserved */ -	u32 dmasar0;		/* 0x110 DMA 0 source address register */ -	u32 res6;		/* 0x114 reserved */ -	u32 dmadar0;		/* 0x118 DMA 0 destination address register */ -	u32 res7;		/* 0x11C reserved */ -	u32 dmabcr0;		/* 0x120 DMA 0 byte count register */ -	u32 dmandar0;		/* 0x124 DMA 0 next descriptor address register */ -	u32 res8[0x16];		/* 0x128-0x179 reserved */ -	u32 dmamr1;		/* 0x180 DMA 1 mode register */ -	u32 dmasr1;		/* 0x184 DMA 1 status register */ -	u32 dmacdar1;		/* 0x188 DMA 1 current descriptor address register */ -	u32 res9;		/* 0x18C reserved */ -	u32 dmasar1;		/* 0x190 DMA 1 source address register */ -	u32 res10;		/* 0x194 reserved */ -	u32 dmadar1;		/* 0x198 DMA 1 destination address register */ -	u32 res11;		/* 0x19C reserved */ -	u32 dmabcr1;		/* 0x1A0 DMA 1 byte count register */ -	u32 dmandar1;		/* 0x1A4 DMA 1 next descriptor address register */ -	u32 res12[0x16];	/* 0x1A8-0x199 reserved */ -	u32 dmamr2;		/* 0x200 DMA 2 mode register */ -	u32 dmasr2;		/* 0x204 DMA 2 status register */ -	u32 dmacdar2;		/* 0x208 DMA 2 current descriptor address register */ -	u32 res13;		/* 0x20C reserved */ -	u32 dmasar2;		/* 0x210 DMA 2 source address register */ -	u32 res14;		/* 0x214 reserved */ -	u32 dmadar2;		/* 0x218 DMA 2 destination address register */ -	u32 res15;		/* 0x21C reserved */ -	u32 dmabcr2;		/* 0x220 DMA 2 byte count register */ -	u32 dmandar2;		/* 0x224 DMA 2 next descriptor address register */ -	u32 res16[0x16];	/* 0x228-0x279 reserved */ -	u32 dmamr3;		/* 0x280 DMA 3 mode register */ -	u32 dmasr3;		/* 0x284 DMA 3 status register */ -	u32 dmacdar3;		/* 0x288 DMA 3 current descriptor address register */ -	u32 res17;		/* 0x28C reserved */ -	u32 dmasar3;		/* 0x290 DMA 3 source address register */ -	u32 res18;		/* 0x294 reserved */ -	u32 dmadar3;		/* 0x298 DMA 3 destination address register */ -	u32 res19;		/* 0x29C reserved */ -	u32 dmabcr3;		/* 0x2A0 DMA 3 byte count register */ -	u32 dmandar3;		/* 0x2A4 DMA 3 next descriptor address register */ -	u32 dmagsr;		/* 0x2A8 DMA general status register */ -	u32 res20[0x15];	/* 0x2AC-0x2FF reserved */ +	struct fsl_dma dma[4];  } dma83xx_t;  /* @@ -895,6 +852,8 @@ typedef struct immap {  } immap_t;  #endif +#define CONFIG_SYS_MPC83xx_DMA_OFFSET	(0x8000) +#define CONFIG_SYS_MPC83xx_DMA_ADDR	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)  #define CONFIG_SYS_MPC83xx_ESDHC_OFFSET	(0x2e000)  #define CONFIG_SYS_MPC83xx_ESDHC_ADDR	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)  #define CONFIG_SYS_MPC83xx_USB_OFFSET	0x23000 diff --git a/include/mpc83xx.h b/include/mpc83xx.h index c5bd6cb16..fd742c780 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 |