X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fsyslib%2Fppc4xx_dma.c;h=1eef4ffed4fb6dc44a8fc487a7e597dd8638bd0f;hb=refs%2Fheads%2Fvserver;hp=b2f3d850503cdee72ed7ed302cd8dfd32c6873ba;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c index b2f3d8505..1eef4ffed 100644 --- a/arch/ppc/syslib/ppc4xx_dma.c +++ b/arch/ppc/syslib/ppc4xx_dma.c @@ -1,6 +1,4 @@ /* - * arch/ppc/kernel/ppc4xx_dma.c - * * IBM PPC4xx DMA engine core library * * Copyright 2000-2004 MontaVista Software Inc. @@ -21,7 +19,6 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include @@ -30,6 +27,7 @@ #include #include +#include #include ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS]; @@ -48,7 +46,7 @@ ppc4xx_set_src_addr(int dmanr, phys_addr_t src_addr) return; } -#ifdef PPC4xx_DMA64BIT +#ifdef PPC4xx_DMA_64BIT mtdcr(DCRN_DMASAH0 + dmanr*2, (u32)(src_addr >> 32)); #else mtdcr(DCRN_DMASA0 + dmanr*2, (u32)src_addr); @@ -63,7 +61,7 @@ ppc4xx_set_dst_addr(int dmanr, phys_addr_t dst_addr) return; } -#ifdef PPC4xx_DMA64BIT +#ifdef PPC4xx_DMA_64BIT mtdcr(DCRN_DMADAH0 + dmanr*2, (u32)(dst_addr >> 32)); #else mtdcr(DCRN_DMADA0 + dmanr*2, (u32)dst_addr); @@ -466,7 +464,7 @@ ppc4xx_init_dma_channel(unsigned int dmanr, ppc_dma_ch_t * p_init) /* clear all polarity signals and then "or" in new signal levels */ polarity &= ~GET_DMA_POLARITY(dmanr); - polarity |= p_dma_ch->polarity; + polarity |= p_init->polarity; #if DCRN_POL > 0 mtdcr(DCRN_POL, polarity); #endif @@ -512,6 +510,8 @@ ppc4xx_get_channel_config(unsigned int dmanr, ppc_dma_ch_t * p_dma_ch) return DMA_STATUS_BAD_CHANNEL; } + memcpy(p_dma_ch, &dma_channels[dmanr], sizeof (ppc_dma_ch_t)); + #if DCRN_POL > 0 polarity = mfdcr(DCRN_POL); #else @@ -604,6 +604,90 @@ ppc4xx_get_peripheral_width(unsigned int dmanr) return (GET_DMA_PW(control)); } +/* + * Clears the channel status bits + */ +int +ppc4xx_clr_dma_status(unsigned int dmanr) +{ + if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) { + printk(KERN_ERR "ppc4xx_clr_dma_status: bad channel: %d\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } + mtdcr(DCRN_DMASR, ((u32)DMA_CH0_ERR | (u32)DMA_CS0 | (u32)DMA_TS0) >> dmanr); + return DMA_STATUS_GOOD; +} + +#ifdef CONFIG_PPC4xx_EDMA +/* + * Enables the burst on the channel (BTEN bit in the control/count register) + * Note: + * For scatter/gather dma, this function MUST be called before the + * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the + * sgl list and used as each sgl element is added. + */ +int +ppc4xx_enable_burst(unsigned int dmanr) +{ + unsigned int ctc; + if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) { + printk(KERN_ERR "ppc4xx_enable_burst: bad channel: %d\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } + ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) | DMA_CTC_BTEN; + mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc); + return DMA_STATUS_GOOD; +} +/* + * Disables the burst on the channel (BTEN bit in the control/count register) + * Note: + * For scatter/gather dma, this function MUST be called before the + * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the + * sgl list and used as each sgl element is added. + */ +int +ppc4xx_disable_burst(unsigned int dmanr) +{ + unsigned int ctc; + if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) { + printk(KERN_ERR "ppc4xx_disable_burst: bad channel: %d\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } + ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) &~ DMA_CTC_BTEN; + mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc); + return DMA_STATUS_GOOD; +} +/* + * Sets the burst size (number of peripheral widths) for the channel + * (BSIZ bits in the control/count register)) + * must be one of: + * DMA_CTC_BSIZ_2 + * DMA_CTC_BSIZ_4 + * DMA_CTC_BSIZ_8 + * DMA_CTC_BSIZ_16 + * Note: + * For scatter/gather dma, this function MUST be called before the + * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the + * sgl list and used as each sgl element is added. + */ +int +ppc4xx_set_burst_size(unsigned int dmanr, unsigned int bsize) +{ + unsigned int ctc; + if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) { + printk(KERN_ERR "ppc4xx_set_burst_size: bad channel: %d\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } + ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) &~ DMA_CTC_BSIZ_MSK; + ctc |= (bsize & DMA_CTC_BSIZ_MSK); + mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc); + return DMA_STATUS_GOOD; +} + +EXPORT_SYMBOL(ppc4xx_enable_burst); +EXPORT_SYMBOL(ppc4xx_disable_burst); +EXPORT_SYMBOL(ppc4xx_set_burst_size); +#endif /* CONFIG_PPC4xx_EDMA */ EXPORT_SYMBOL(ppc4xx_init_dma_channel); EXPORT_SYMBOL(ppc4xx_get_channel_config); @@ -622,3 +706,5 @@ EXPORT_SYMBOL(ppc4xx_get_dma_residue); EXPORT_SYMBOL(ppc4xx_enable_dma_interrupt); EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt); EXPORT_SYMBOL(ppc4xx_get_dma_status); +EXPORT_SYMBOL(ppc4xx_clr_dma_status); +