提交 c5ed98b6 编写于 作者: R Russell King

dmaengine: omap-dma: provide register read/write functions

Provide a pair of channel register accessors, and a pair of global
accessors for non-channel specific registers.
Acked-by: NTony Lindgren <tony@atomide.com>
Acked-by: NVinod Koul <vinod.koul@intel.com>
Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
上级 45da7b04
...@@ -170,12 +170,32 @@ static void omap_dma_desc_free(struct virt_dma_desc *vd) ...@@ -170,12 +170,32 @@ static void omap_dma_desc_free(struct virt_dma_desc *vd)
kfree(container_of(vd, struct omap_desc, vd)); kfree(container_of(vd, struct omap_desc, vd));
} }
static void omap_dma_glbl_write(struct omap_dmadev *od, unsigned reg, unsigned val)
{
od->plat->dma_write(val, reg, 0);
}
static unsigned omap_dma_glbl_read(struct omap_dmadev *od, unsigned reg)
{
return od->plat->dma_read(reg, 0);
}
static void omap_dma_chan_write(struct omap_chan *c, unsigned reg, unsigned val)
{
c->plat->dma_write(val, reg, c->dma_ch);
}
static unsigned omap_dma_chan_read(struct omap_chan *c, unsigned reg)
{
return c->plat->dma_read(reg, c->dma_ch);
}
static void omap_dma_clear_csr(struct omap_chan *c) static void omap_dma_clear_csr(struct omap_chan *c)
{ {
if (dma_omap1()) if (dma_omap1())
c->plat->dma_read(CSR, c->dma_ch); omap_dma_chan_read(c, CSR);
else else
c->plat->dma_write(~0, CSR, c->dma_ch); omap_dma_chan_write(c, CSR, ~0);
} }
static void omap_dma_start(struct omap_chan *c, struct omap_desc *d) static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
...@@ -183,17 +203,17 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d) ...@@ -183,17 +203,17 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device); struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
if (__dma_omap15xx(od->plat->dma_attr)) if (__dma_omap15xx(od->plat->dma_attr))
c->plat->dma_write(0, CPC, c->dma_ch); omap_dma_chan_write(c, CPC, 0);
else else
c->plat->dma_write(0, CDAC, c->dma_ch); omap_dma_chan_write(c, CDAC, 0);
omap_dma_clear_csr(c); omap_dma_clear_csr(c);
/* Enable interrupts */ /* Enable interrupts */
c->plat->dma_write(d->cicr, CICR, c->dma_ch); omap_dma_chan_write(c, CICR, d->cicr);
/* Enable channel */ /* Enable channel */
c->plat->dma_write(d->ccr | CCR_ENABLE, CCR, c->dma_ch); omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE);
} }
static void omap_dma_stop(struct omap_chan *c) static void omap_dma_stop(struct omap_chan *c)
...@@ -202,27 +222,27 @@ static void omap_dma_stop(struct omap_chan *c) ...@@ -202,27 +222,27 @@ static void omap_dma_stop(struct omap_chan *c)
uint32_t val; uint32_t val;
/* disable irq */ /* disable irq */
c->plat->dma_write(0, CICR, c->dma_ch); omap_dma_chan_write(c, CICR, 0);
omap_dma_clear_csr(c); omap_dma_clear_csr(c);
val = c->plat->dma_read(CCR, c->dma_ch); val = omap_dma_chan_read(c, CCR);
if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) { if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) {
uint32_t sysconfig; uint32_t sysconfig;
unsigned i; unsigned i;
sysconfig = c->plat->dma_read(OCP_SYSCONFIG, c->dma_ch); sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
val = sysconfig & ~DMA_SYSCONFIG_MIDLEMODE_MASK; val = sysconfig & ~DMA_SYSCONFIG_MIDLEMODE_MASK;
val |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE); val |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
c->plat->dma_write(val, OCP_SYSCONFIG, c->dma_ch); omap_dma_glbl_write(od, OCP_SYSCONFIG, val);
val = c->plat->dma_read(CCR, c->dma_ch); val = omap_dma_chan_read(c, CCR);
val &= ~CCR_ENABLE; val &= ~CCR_ENABLE;
c->plat->dma_write(val, CCR, c->dma_ch); omap_dma_chan_write(c, CCR, val);
/* Wait for sDMA FIFO to drain */ /* Wait for sDMA FIFO to drain */
for (i = 0; ; i++) { for (i = 0; ; i++) {
val = c->plat->dma_read(CCR, c->dma_ch); val = omap_dma_chan_read(c, CCR);
if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE))) if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
break; break;
...@@ -237,23 +257,23 @@ static void omap_dma_stop(struct omap_chan *c) ...@@ -237,23 +257,23 @@ static void omap_dma_stop(struct omap_chan *c)
"DMA drain did not complete on lch %d\n", "DMA drain did not complete on lch %d\n",
c->dma_ch); c->dma_ch);
c->plat->dma_write(sysconfig, OCP_SYSCONFIG, c->dma_ch); omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else { } else {
val &= ~CCR_ENABLE; val &= ~CCR_ENABLE;
c->plat->dma_write(val, CCR, c->dma_ch); omap_dma_chan_write(c, CCR, val);
} }
mb(); mb();
if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) { if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) {
val = c->plat->dma_read(CLNK_CTRL, c->dma_ch); val = omap_dma_chan_read(c, CLNK_CTRL);
if (dma_omap1()) if (dma_omap1())
val |= 1 << 14; /* set the STOP_LNK bit */ val |= 1 << 14; /* set the STOP_LNK bit */
else else
val &= ~CLNK_CTRL_ENABLE_LNK; val &= ~CLNK_CTRL_ENABLE_LNK;
c->plat->dma_write(val, CLNK_CTRL, c->dma_ch); omap_dma_chan_write(c, CLNK_CTRL, val);
} }
} }
...@@ -273,11 +293,11 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d, ...@@ -273,11 +293,11 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
cxfi = CSFI; cxfi = CSFI;
} }
c->plat->dma_write(sg->addr, cxsa, c->dma_ch); omap_dma_chan_write(c, cxsa, sg->addr);
c->plat->dma_write(0, cxei, c->dma_ch); omap_dma_chan_write(c, cxei, 0);
c->plat->dma_write(0, cxfi, c->dma_ch); omap_dma_chan_write(c, cxfi, 0);
c->plat->dma_write(sg->en, CEN, c->dma_ch); omap_dma_chan_write(c, CEN, sg->en);
c->plat->dma_write(sg->fn, CFN, c->dma_ch); omap_dma_chan_write(c, CFN, sg->fn);
omap_dma_start(c, d); omap_dma_start(c, d);
} }
...@@ -305,9 +325,9 @@ static void omap_dma_start_desc(struct omap_chan *c) ...@@ -305,9 +325,9 @@ static void omap_dma_start_desc(struct omap_chan *c)
*/ */
mb(); mb();
c->plat->dma_write(d->ccr, CCR, c->dma_ch); omap_dma_chan_write(c, CCR, d->ccr);
if (dma_omap1()) if (dma_omap1())
c->plat->dma_write(d->ccr >> 16, CCR2, c->dma_ch); omap_dma_chan_write(c, CCR2, d->ccr >> 16);
if (d->dir == DMA_DEV_TO_MEM) { if (d->dir == DMA_DEV_TO_MEM) {
cxsa = CSSA; cxsa = CSSA;
...@@ -319,11 +339,11 @@ static void omap_dma_start_desc(struct omap_chan *c) ...@@ -319,11 +339,11 @@ static void omap_dma_start_desc(struct omap_chan *c)
cxfi = CDFI; cxfi = CDFI;
} }
c->plat->dma_write(d->dev_addr, cxsa, c->dma_ch); omap_dma_chan_write(c, cxsa, d->dev_addr);
c->plat->dma_write(0, cxei, c->dma_ch); omap_dma_chan_write(c, cxei, 0);
c->plat->dma_write(d->fi, cxfi, c->dma_ch); omap_dma_chan_write(c, cxfi, d->fi);
c->plat->dma_write(d->csdp, CSDP, c->dma_ch); omap_dma_chan_write(c, CSDP, d->csdp);
c->plat->dma_write(d->clnk_ctrl, CLNK_CTRL, c->dma_ch); omap_dma_chan_write(c, CLNK_CTRL, d->clnk_ctrl);
omap_dma_start_sg(c, d, 0); omap_dma_start_sg(c, d, 0);
} }
...@@ -437,12 +457,12 @@ static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c) ...@@ -437,12 +457,12 @@ static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
dma_addr_t addr; dma_addr_t addr;
if (__dma_omap15xx(od->plat->dma_attr)) if (__dma_omap15xx(od->plat->dma_attr))
addr = c->plat->dma_read(CPC, c->dma_ch); addr = omap_dma_chan_read(c, CPC);
else else
addr = c->plat->dma_read(CSAC, c->dma_ch); addr = omap_dma_chan_read(c, CSAC);
if (od->plat->errata & DMA_ERRATA_3_3 && addr == 0) if (od->plat->errata & DMA_ERRATA_3_3 && addr == 0)
addr = c->plat->dma_read(CSAC, c->dma_ch); addr = omap_dma_chan_read(c, CSAC);
if (!__dma_omap15xx(od->plat->dma_attr)) { if (!__dma_omap15xx(od->plat->dma_attr)) {
/* /*
...@@ -450,14 +470,14 @@ static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c) ...@@ -450,14 +470,14 @@ static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
* not been started (no data has been transferred so far). * not been started (no data has been transferred so far).
* Return the programmed source start address in this case. * Return the programmed source start address in this case.
*/ */
if (c->plat->dma_read(CDAC, c->dma_ch)) if (omap_dma_chan_read(c, CDAC))
addr = c->plat->dma_read(CSAC, c->dma_ch); addr = omap_dma_chan_read(c, CSAC);
else else
addr = c->plat->dma_read(CSSA, c->dma_ch); addr = omap_dma_chan_read(c, CSSA);
} }
if (dma_omap1()) if (dma_omap1())
addr |= c->plat->dma_read(CSSA, c->dma_ch) & 0xffff0000; addr |= omap_dma_chan_read(c, CSSA) & 0xffff0000;
return addr; return addr;
} }
...@@ -468,27 +488,27 @@ static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c) ...@@ -468,27 +488,27 @@ static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c)
dma_addr_t addr; dma_addr_t addr;
if (__dma_omap15xx(od->plat->dma_attr)) if (__dma_omap15xx(od->plat->dma_attr))
addr = c->plat->dma_read(CPC, c->dma_ch); addr = omap_dma_chan_read(c, CPC);
else else
addr = c->plat->dma_read(CDAC, c->dma_ch); addr = omap_dma_chan_read(c, CDAC);
/* /*
* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel. * read before the DMA controller finished disabling the channel.
*/ */
if (!__dma_omap15xx(od->plat->dma_attr) && addr == 0) { if (!__dma_omap15xx(od->plat->dma_attr) && addr == 0) {
addr = c->plat->dma_read(CDAC, c->dma_ch); addr = omap_dma_chan_read(c, CDAC);
/* /*
* CDAC == 0 indicates that the DMA transfer on the channel has * CDAC == 0 indicates that the DMA transfer on the channel has
* not been started (no data has been transferred so far). * not been started (no data has been transferred so far).
* Return the programmed destination start address in this case. * Return the programmed destination start address in this case.
*/ */
if (addr == 0) if (addr == 0)
addr = c->plat->dma_read(CDSA, c->dma_ch); addr = omap_dma_chan_read(c, CDSA);
} }
if (dma_omap1()) if (dma_omap1())
addr |= c->plat->dma_read(CDSA, c->dma_ch) & 0xffff0000; addr |= omap_dma_chan_read(c, CDSA) & 0xffff0000;
return addr; return addr;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册