From 0fa22197b06b301ca0b6bd6ed8c476efa2915f9e Mon Sep 17 00:00:00 2001 From: Jingchang Lu Date: Wed, 9 Jul 2014 14:38:27 +0800 Subject: dmaengine: fsl-edma: swap 8-/16-bit registers offset in big-endian mode As the IP design, all 8-bit and 16-bit registers offset adddress should be swapped in big-endian mode opposite to little-endian mode. Signed-off-by: Jingchang Lu diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 24ab3d3..8040f25 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -177,12 +177,15 @@ struct fsl_edma_engine { /* * R/W functions for big- or little-endian registers * the eDMA controller's endian is independent of the CPU core's endian. + * for the big-endian IP module, the offset for 8-bit or 16-bit register + * should also be swapped oposite to that in little-endian IP. */ static u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr) { + /* swap the reg offset for that in big-endian mode*/ if (edma->big_endian) - return ioread16be(addr); + return ioread16be((void __iomem *)(((u32)addr & ~0x3) | (((u32)addr & 0x3) ^ 0x2))); else return ioread16(addr); } @@ -197,11 +200,24 @@ static u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr) static void edma_writeb(struct fsl_edma_engine *edma, u8 val, void __iomem *addr) { - iowrite8(val, addr); + /* swap the reg offset for that in big-endian mode*/ + if (edma->big_endian) + iowrite8(val, (void __iomem *)(((u32)addr & ~0x3) | (((u32)addr & 0x3) ^ 0x3))); + else + iowrite8(val, addr); } static void edma_writew(struct fsl_edma_engine *edma, u16 val, void __iomem *addr) { + /* swap the reg offset for that in big-endian mode*/ + if (edma->big_endian) + writew(val, (void __iomem *)(((u32)addr & ~0x3) | (((u32)addr & 0x3) ^ 0x2))); + else + writew(val, addr); +} + +static void edma_tcd_writew(struct fsl_edma_engine *edma, u16 val, void __iomem *addr) +{ if (edma->big_endian) iowrite16be(val, addr); else @@ -256,11 +272,10 @@ static void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux]; if (enable) - edma_writeb(fsl_chan->edma, - EDMAMUX_CHCFG_ENBL | EDMAMUX_CHCFG_SOURCE(slot), + writeb(EDMAMUX_CHCFG_ENBL | EDMAMUX_CHCFG_SOURCE(slot), muxaddr + ch_off); else - edma_writeb(fsl_chan->edma, EDMAMUX_CHCFG_DIS, muxaddr + ch_off); + writeb(EDMAMUX_CHCFG_DIS, muxaddr + ch_off); } static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth addr_width) @@ -436,18 +451,18 @@ static void fsl_edma_set_tcd_params(struct fsl_edma_chan *fsl_chan, * TCD parameters have been swapped in fill_tcd_params(), * so just write them to registers in the cpu endian here */ - writew(0, addr + EDMA_TCD_CSR(ch)); + edma_writew(fsl_chan->edma, 0, addr + EDMA_TCD_CSR(ch)); writel(src, addr + EDMA_TCD_SADDR(ch)); writel(dst, addr + EDMA_TCD_DADDR(ch)); - writew(attr, addr + EDMA_TCD_ATTR(ch)); - writew(soff, addr + EDMA_TCD_SOFF(ch)); + edma_writew(fsl_chan->edma, attr, addr + EDMA_TCD_ATTR(ch)); + edma_writew(fsl_chan->edma, soff, addr + EDMA_TCD_SOFF(ch)); writel(nbytes, addr + EDMA_TCD_NBYTES(ch)); writel(slast, addr + EDMA_TCD_SLAST(ch)); - writew(citer, addr + EDMA_TCD_CITER(ch)); - writew(biter, addr + EDMA_TCD_BITER(ch)); - writew(doff, addr + EDMA_TCD_DOFF(ch)); + edma_writew(fsl_chan->edma, citer, addr + EDMA_TCD_CITER(ch)); + edma_writew(fsl_chan->edma, biter, addr + EDMA_TCD_BITER(ch)); + edma_writew(fsl_chan->edma, doff, addr + EDMA_TCD_DOFF(ch)); writel(dlast_sga, addr + EDMA_TCD_DLAST_SGA(ch)); - writew(csr, addr + EDMA_TCD_CSR(ch)); + edma_writew(fsl_chan->edma, csr, addr + EDMA_TCD_CSR(ch)); } static void fill_tcd_params(struct fsl_edma_engine *edma, @@ -465,14 +480,14 @@ static void fill_tcd_params(struct fsl_edma_engine *edma, */ edma_writel(edma, src, &(tcd->saddr)); edma_writel(edma, dst, &(tcd->daddr)); - edma_writew(edma, attr, &(tcd->attr)); - edma_writew(edma, EDMA_TCD_SOFF_SOFF(soff), &(tcd->soff)); + edma_tcd_writew(edma, attr, &(tcd->attr)); + edma_tcd_writew(edma, EDMA_TCD_SOFF_SOFF(soff), &(tcd->soff)); edma_writel(edma, EDMA_TCD_NBYTES_NBYTES(nbytes), &(tcd->nbytes)); edma_writel(edma, EDMA_TCD_SLAST_SLAST(slast), &(tcd->slast)); - edma_writew(edma, EDMA_TCD_CITER_CITER(citer), &(tcd->citer)); - edma_writew(edma, EDMA_TCD_DOFF_DOFF(doff), &(tcd->doff)); + edma_tcd_writew(edma, EDMA_TCD_CITER_CITER(citer), &(tcd->citer)); + edma_tcd_writew(edma, EDMA_TCD_DOFF_DOFF(doff), &(tcd->doff)); edma_writel(edma, EDMA_TCD_DLAST_SGA_DLAST_SGA(dlast_sga), &(tcd->dlast_sga)); - edma_writew(edma, EDMA_TCD_BITER_BITER(biter), &(tcd->biter)); + edma_tcd_writew(edma, EDMA_TCD_BITER_BITER(biter), &(tcd->biter)); if (major_int) csr |= EDMA_TCD_CSR_INT_MAJOR; @@ -482,7 +497,7 @@ static void fill_tcd_params(struct fsl_edma_engine *edma, if (enable_sg) csr |= EDMA_TCD_CSR_E_SG; - edma_writew(edma, csr, &(tcd->csr)); + edma_tcd_writew(edma, csr, &(tcd->csr)); } static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, -- cgit v0.10.2