summaryrefslogtreecommitdiff
path: root/drivers/dma
diff options
context:
space:
mode:
authorJingchang Lu <jingchang.lu@freescale.com>2014-07-09 06:38:27 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:35:40 (GMT)
commit0fa22197b06b301ca0b6bd6ed8c476efa2915f9e (patch)
tree278651cf7b73cb11a9d498d0b8626f803ec74fcc /drivers/dma
parent06a082ea233a5fa790884ff25a8f0d4c93268193 (diff)
downloadlinux-fsl-qoriq-0fa22197b06b301ca0b6bd6ed8c476efa2915f9e.tar.xz
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 <jingchang.lu@freescale.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/fsl-edma.c51
1 files changed, 33 insertions, 18 deletions
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,