* [PATCH 01/26] dmaengine: omap-dma: use devm_kzalloc() to allocate omap_dmadev.
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
@ 2014-02-10 15:55 ` Russell King
2014-02-10 15:56 ` [PATCH 02/26] dmaengine: omap-dma: provide a hook to get the underlying DMA platform ops Russell King
` (27 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:55 UTC (permalink / raw)
To: linux-arm-kernel
Use devm_kzalloc() to allocate omap_dmadev() so that we don't need
complex error cleanup paths.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 362e7c49f2e1..98034e8c558f 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -594,7 +594,6 @@ static void omap_dma_free(struct omap_dmadev *od)
tasklet_kill(&c->vc.task);
kfree(c);
}
- kfree(od);
}
static int omap_dma_probe(struct platform_device *pdev)
@@ -602,7 +601,7 @@ static int omap_dma_probe(struct platform_device *pdev)
struct omap_dmadev *od;
int rc, i;
- od = kzalloc(sizeof(*od), GFP_KERNEL);
+ od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
if (!od)
return -ENOMEM;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 02/26] dmaengine: omap-dma: provide a hook to get the underlying DMA platform ops
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
2014-02-10 15:55 ` [PATCH 01/26] dmaengine: omap-dma: use devm_kzalloc() to allocate omap_dmadev Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 03/26] dmaengine: omap-dma: program hardware directly Russell King
` (26 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Provide and use a hook to obtain the underlying DMA platform operations
so that omap-dma.c can access the hardware more directly without
involving the legacy DMA driver.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/plat-omap/dma.c | 6 ++++++
drivers/dma/omap-dma.c | 7 +++++++
include/linux/omap-dma.h | 2 ++
3 files changed, 15 insertions(+)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 01619c2910e3..d4d9a5e62152 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2000,6 +2000,12 @@ void omap_dma_global_context_restore(void)
omap_clear_dma(ch);
}
+struct omap_system_dma_plat_info *omap_get_plat_info(void)
+{
+ return p;
+}
+EXPORT_SYMBOL_GPL(omap_get_plat_info);
+
static int omap_system_dma_probe(struct platform_device *pdev)
{
int ch, ret = 0;
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 98034e8c558f..4ac26bf0ad30 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -26,11 +26,13 @@ struct omap_dmadev {
spinlock_t lock;
struct tasklet_struct task;
struct list_head pending;
+ struct omap_system_dma_plat_info *plat;
};
struct omap_chan {
struct virt_dma_chan vc;
struct list_head node;
+ struct omap_system_dma_plat_info *plat;
struct dma_slave_config cfg;
unsigned dma_sig;
@@ -573,6 +575,7 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
if (!c)
return -ENOMEM;
+ c->plat = od->plat;
c->dma_sig = dma_sig;
c->vc.desc_free = omap_dma_desc_free;
vchan_init(&c->vc, &od->ddev);
@@ -605,6 +608,10 @@ static int omap_dma_probe(struct platform_device *pdev)
if (!od)
return -ENOMEM;
+ od->plat = omap_get_plat_info();
+ if (!od->plat)
+ return -EPROBE_DEFER;
+
dma_cap_set(DMA_SLAVE, od->ddev.cap_mask);
dma_cap_set(DMA_CYCLIC, od->ddev.cap_mask);
od->ddev.device_alloc_chan_resources = omap_dma_alloc_chan_resources;
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 7af25a9c9c51..14742fc2aefe 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -292,6 +292,8 @@ struct omap_system_dma_plat_info {
#define dma_omap15xx() ((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE)))
#define dma_omap16xx() ((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE)))
+extern struct omap_system_dma_plat_info *omap_get_plat_info(void);
+
extern void omap_set_dma_priority(int lch, int dst_port, int priority);
extern int omap_request_dma(int dev_id, const char *dev_name,
void (*callback)(int lch, u16 ch_status, void *data),
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 03/26] dmaengine: omap-dma: program hardware directly
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
2014-02-10 15:55 ` [PATCH 01/26] dmaengine: omap-dma: use devm_kzalloc() to allocate omap_dmadev Russell King
2014-02-10 15:56 ` [PATCH 02/26] dmaengine: omap-dma: provide a hook to get the underlying DMA platform ops Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 04/26] dmaengine: omap-dma: consolidate writes to DMA registers Russell King
` (25 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Program the transfer parameters directly into the hardware, rather
than using the functions in arch/arm/plat-omap/dma.c.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 142 +++++++++++++++++++++++++++++++++++++++++------
include/linux/omap-dma.h | 6 +-
2 files changed, 130 insertions(+), 18 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 4ac26bf0ad30..47a3fa5bc38e 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -99,16 +99,94 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
unsigned idx)
{
struct omap_sg *sg = d->sg + idx;
+ uint32_t val;
+
+ if (d->dir == DMA_DEV_TO_MEM) {
+ if (dma_omap1()) {
+ val = c->plat->dma_read(CSDP, c->dma_ch);
+ val &= ~(0x1f << 9);
+ val |= OMAP_DMA_PORT_EMIFF << 9;
+ c->plat->dma_write(val, CSDP, c->dma_ch);
+ }
- if (d->dir == DMA_DEV_TO_MEM)
- omap_set_dma_dest_params(c->dma_ch, OMAP_DMA_PORT_EMIFF,
- OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0);
- else
- omap_set_dma_src_params(c->dma_ch, OMAP_DMA_PORT_EMIFF,
- OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0);
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~(0x03 << 14);
+ val |= OMAP_DMA_AMODE_POST_INC << 14;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+
+ c->plat->dma_write(sg->addr, CDSA, c->dma_ch);
+ c->plat->dma_write(0, CDEI, c->dma_ch);
+ c->plat->dma_write(0, CDFI, c->dma_ch);
+ } else {
+ if (dma_omap1()) {
+ val = c->plat->dma_read(CSDP, c->dma_ch);
+ val &= ~(0x1f << 2);
+ val |= OMAP_DMA_PORT_EMIFF << 2;
+ c->plat->dma_write(val, CSDP, c->dma_ch);
+ }
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~(0x03 << 12);
+ val |= OMAP_DMA_AMODE_POST_INC << 12;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+
+ c->plat->dma_write(sg->addr, CSSA, c->dma_ch);
+ c->plat->dma_write(0, CSEI, c->dma_ch);
+ c->plat->dma_write(0, CSFI, c->dma_ch);
+ }
+
+ val = c->plat->dma_read(CSDP, c->dma_ch);
+ val &= ~0x03;
+ val |= d->es;
+ c->plat->dma_write(val, CSDP, c->dma_ch);
+
+ if (dma_omap1()) {
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~(1 << 5);
+ if (d->sync_mode == OMAP_DMA_SYNC_FRAME)
+ val |= 1 << 5;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+
+ val = c->plat->dma_read(CCR2, c->dma_ch);
+ val &= ~(1 << 2);
+ if (d->sync_mode == OMAP_DMA_SYNC_BLOCK)
+ val |= 1 << 2;
+ c->plat->dma_write(val, CCR2, c->dma_ch);
+ } else if (c->dma_sig) {
+ val = c->plat->dma_read(CCR, c->dma_ch);
+
+ /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
+ val &= ~((1 << 23) | (3 << 19) | 0x1f);
+ val |= (c->dma_sig & ~0x1f) << 14;
+ val |= c->dma_sig & 0x1f;
+
+ if (d->sync_mode & OMAP_DMA_SYNC_FRAME)
+ val |= 1 << 5;
+ else
+ val &= ~(1 << 5);
+
+ if (d->sync_mode & OMAP_DMA_SYNC_BLOCK)
+ val |= 1 << 18;
+ else
+ val &= ~(1 << 18);
+
+ switch (d->sync_type) {
+ case OMAP_DMA_DST_SYNC_PREFETCH:
+ val &= ~(1 << 24); /* dest synch */
+ val |= 1 << 23; /* Prefetch */
+ break;
+ case 0:
+ val &= ~(1 << 24); /* dest synch */
+ break;
+ default:
+ val |= 1 << 24; /* source synch */
+ break;
+ }
+ c->plat->dma_write(val, CCR, c->dma_ch);
+ }
- omap_set_dma_transfer_params(c->dma_ch, d->es, sg->en, sg->fn,
- d->sync_mode, c->dma_sig, d->sync_type);
+ c->plat->dma_write(sg->en, CEN, c->dma_ch);
+ c->plat->dma_write(sg->fn, CFN, c->dma_ch);
omap_start_dma(c->dma_ch);
}
@@ -117,6 +195,7 @@ static void omap_dma_start_desc(struct omap_chan *c)
{
struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
struct omap_desc *d;
+ uint32_t val;
if (!vd) {
c->desc = NULL;
@@ -128,12 +207,39 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->desc = d = to_omap_dma_desc(&vd->tx);
c->sgidx = 0;
- if (d->dir == DMA_DEV_TO_MEM)
- omap_set_dma_src_params(c->dma_ch, d->periph_port,
- OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi);
- else
- omap_set_dma_dest_params(c->dma_ch, d->periph_port,
- OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi);
+ if (d->dir == DMA_DEV_TO_MEM) {
+ if (dma_omap1()) {
+ val = c->plat->dma_read(CSDP, c->dma_ch);
+ val &= ~(0x1f << 2);
+ val |= d->periph_port << 2;
+ c->plat->dma_write(val, CSDP, c->dma_ch);
+ }
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~(0x03 << 12);
+ val |= OMAP_DMA_AMODE_CONSTANT << 12;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+
+ c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
+ c->plat->dma_write(0, CSEI, c->dma_ch);
+ c->plat->dma_write(d->fi, CSFI, c->dma_ch);
+ } else {
+ if (dma_omap1()) {
+ val = c->plat->dma_read(CSDP, c->dma_ch);
+ val &= ~(0x1f << 9);
+ val |= d->periph_port << 9;
+ c->plat->dma_write(val, CSDP, c->dma_ch);
+ }
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~(0x03 << 14);
+ val |= OMAP_DMA_AMODE_CONSTANT << 14;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+
+ c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
+ c->plat->dma_write(0, CDEI, c->dma_ch);
+ c->plat->dma_write(d->fi, CDFI, c->dma_ch);
+ }
omap_dma_start_sg(c, d, 0);
}
@@ -452,8 +558,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
}
if (dma_omap2plus()) {
- omap_set_dma_src_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16);
- omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16);
+ uint32_t val;
+
+ val = c->plat->dma_read(CSDP, c->dma_ch);
+ val |= 0x03 << 7; /* src burst mode 16 */
+ val |= 0x03 << 14; /* dst burst mode 16 */
+ c->plat->dma_write(val, CSDP, c->dma_ch);
}
return vchan_tx_prep(&c->vc, &d->vd, flags);
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 14742fc2aefe..d631658e2237 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -289,8 +289,10 @@ struct omap_system_dma_plat_info {
#define dma_omap2plus() 0
#endif
#define dma_omap1() (!dma_omap2plus())
-#define dma_omap15xx() ((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE)))
-#define dma_omap16xx() ((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE)))
+#define __dma_omap15xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_1510_MODE)
+#define __dma_omap16xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_16XX_MODE)
+#define dma_omap15xx() __dma_omap15xx(d)
+#define dma_omap16xx() __dma_omap16xx(d)
extern struct omap_system_dma_plat_info *omap_get_plat_info(void);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 04/26] dmaengine: omap-dma: consolidate writes to DMA registers
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (2 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 03/26] dmaengine: omap-dma: program hardware directly Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 05/26] dmaengine: omap-dma: control start/stop directly Russell King
` (24 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
There's no need to keep writing registers which don't change value in
omap_dma_start_sg(). Move this into omap_dma_start_desc() and merge
the register updates together.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 123 +++++++++++++++++++------------------------------
1 file changed, 48 insertions(+), 75 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 47a3fa5bc38e..8c5c862f01ed 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -99,40 +99,75 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
unsigned idx)
{
struct omap_sg *sg = d->sg + idx;
+
+ if (d->dir == DMA_DEV_TO_MEM) {
+ c->plat->dma_write(sg->addr, CDSA, c->dma_ch);
+ c->plat->dma_write(0, CDEI, c->dma_ch);
+ c->plat->dma_write(0, CDFI, c->dma_ch);
+ } else {
+ c->plat->dma_write(sg->addr, CSSA, c->dma_ch);
+ c->plat->dma_write(0, CSEI, c->dma_ch);
+ c->plat->dma_write(0, CSFI, c->dma_ch);
+ }
+
+ c->plat->dma_write(sg->en, CEN, c->dma_ch);
+ c->plat->dma_write(sg->fn, CFN, c->dma_ch);
+
+ omap_start_dma(c->dma_ch);
+}
+
+static void omap_dma_start_desc(struct omap_chan *c)
+{
+ struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
+ struct omap_desc *d;
uint32_t val;
+ if (!vd) {
+ c->desc = NULL;
+ return;
+ }
+
+ list_del(&vd->node);
+
+ c->desc = d = to_omap_dma_desc(&vd->tx);
+ c->sgidx = 0;
+
if (d->dir == DMA_DEV_TO_MEM) {
if (dma_omap1()) {
val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~(0x1f << 9);
+ val &= ~(0x1f << 9 | 0x1f << 2);
val |= OMAP_DMA_PORT_EMIFF << 9;
+ val |= d->periph_port << 2;
c->plat->dma_write(val, CSDP, c->dma_ch);
}
val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(0x03 << 14);
+ val &= ~(0x03 << 14 | 0x03 << 12);
val |= OMAP_DMA_AMODE_POST_INC << 14;
+ val |= OMAP_DMA_AMODE_CONSTANT << 12;
c->plat->dma_write(val, CCR, c->dma_ch);
- c->plat->dma_write(sg->addr, CDSA, c->dma_ch);
- c->plat->dma_write(0, CDEI, c->dma_ch);
- c->plat->dma_write(0, CDFI, c->dma_ch);
+ c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
+ c->plat->dma_write(0, CSEI, c->dma_ch);
+ c->plat->dma_write(d->fi, CSFI, c->dma_ch);
} else {
if (dma_omap1()) {
val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~(0x1f << 2);
+ val &= ~(0x1f << 9 | 0x1f << 2);
+ val |= d->periph_port << 9;
val |= OMAP_DMA_PORT_EMIFF << 2;
c->plat->dma_write(val, CSDP, c->dma_ch);
}
val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(0x03 << 12);
+ val &= ~(0x03 << 12 | 0x03 << 14);
+ val |= OMAP_DMA_AMODE_CONSTANT << 14;
val |= OMAP_DMA_AMODE_POST_INC << 12;
c->plat->dma_write(val, CCR, c->dma_ch);
- c->plat->dma_write(sg->addr, CSSA, c->dma_ch);
- c->plat->dma_write(0, CSEI, c->dma_ch);
- c->plat->dma_write(0, CSFI, c->dma_ch);
+ c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
+ c->plat->dma_write(0, CDEI, c->dma_ch);
+ c->plat->dma_write(d->fi, CDFI, c->dma_ch);
}
val = c->plat->dma_read(CSDP, c->dma_ch);
@@ -156,91 +191,29 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
val = c->plat->dma_read(CCR, c->dma_ch);
/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
- val &= ~((1 << 23) | (3 << 19) | 0x1f);
+ val &= ~(1 << 24 | 1 << 23 | 3 << 19 | 1 << 18 | 1 << 5 | 0x1f);
val |= (c->dma_sig & ~0x1f) << 14;
val |= c->dma_sig & 0x1f;
if (d->sync_mode & OMAP_DMA_SYNC_FRAME)
val |= 1 << 5;
- else
- val &= ~(1 << 5);
if (d->sync_mode & OMAP_DMA_SYNC_BLOCK)
val |= 1 << 18;
- else
- val &= ~(1 << 18);
switch (d->sync_type) {
- case OMAP_DMA_DST_SYNC_PREFETCH:
- val &= ~(1 << 24); /* dest synch */
+ case OMAP_DMA_DST_SYNC_PREFETCH:/* dest synch */
val |= 1 << 23; /* Prefetch */
break;
case 0:
- val &= ~(1 << 24); /* dest synch */
break;
default:
- val |= 1 << 24; /* source synch */
+ val |= 1 << 24; /* source synch */
break;
}
c->plat->dma_write(val, CCR, c->dma_ch);
}
- c->plat->dma_write(sg->en, CEN, c->dma_ch);
- c->plat->dma_write(sg->fn, CFN, c->dma_ch);
-
- omap_start_dma(c->dma_ch);
-}
-
-static void omap_dma_start_desc(struct omap_chan *c)
-{
- struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
- struct omap_desc *d;
- uint32_t val;
-
- if (!vd) {
- c->desc = NULL;
- return;
- }
-
- list_del(&vd->node);
-
- c->desc = d = to_omap_dma_desc(&vd->tx);
- c->sgidx = 0;
-
- if (d->dir == DMA_DEV_TO_MEM) {
- if (dma_omap1()) {
- val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~(0x1f << 2);
- val |= d->periph_port << 2;
- c->plat->dma_write(val, CSDP, c->dma_ch);
- }
-
- val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(0x03 << 12);
- val |= OMAP_DMA_AMODE_CONSTANT << 12;
- c->plat->dma_write(val, CCR, c->dma_ch);
-
- c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
- c->plat->dma_write(0, CSEI, c->dma_ch);
- c->plat->dma_write(d->fi, CSFI, c->dma_ch);
- } else {
- if (dma_omap1()) {
- val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~(0x1f << 9);
- val |= d->periph_port << 9;
- c->plat->dma_write(val, CSDP, c->dma_ch);
- }
-
- val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(0x03 << 14);
- val |= OMAP_DMA_AMODE_CONSTANT << 14;
- c->plat->dma_write(val, CCR, c->dma_ch);
-
- c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
- c->plat->dma_write(0, CDEI, c->dma_ch);
- c->plat->dma_write(d->fi, CDFI, c->dma_ch);
- }
-
omap_dma_start_sg(c, d, 0);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 05/26] dmaengine: omap-dma: control start/stop directly
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (3 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 04/26] dmaengine: omap-dma: consolidate writes to DMA registers Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 06/26] dmaengine: omap-dma: move reading of dma position to omap-dma.c Russell King
` (23 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Program the non-cyclic mode DMA start/stop directly, rather than via
arch/arm/plat-omap/dma.c.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 151 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 141 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 8c5c862f01ed..7aa5ff7ab935 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -5,6 +5,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
@@ -60,6 +61,7 @@ struct omap_desc {
uint8_t sync_mode; /* OMAP_DMA_SYNC_xxx */
uint8_t sync_type; /* OMAP_DMA_xxx_SYNC* */
uint8_t periph_port; /* Peripheral port */
+ uint16_t cicr; /* CICR value */
unsigned sglen;
struct omap_sg sg[0];
@@ -95,6 +97,111 @@ static void omap_dma_desc_free(struct virt_dma_desc *vd)
kfree(container_of(vd, struct omap_desc, vd));
}
+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);
+ uint32_t val;
+
+ if (__dma_omap15xx(od->plat->dma_attr))
+ c->plat->dma_write(0, CPC, c->dma_ch);
+ else
+ c->plat->dma_write(0, CDAC, c->dma_ch);
+
+ if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) {
+ val = c->plat->dma_read(CLNK_CTRL, c->dma_ch);
+
+ if (dma_omap1())
+ val &= ~(1 << 14);
+
+ val |= c->dma_ch | 1 << 15;
+
+ c->plat->dma_write(val, CLNK_CTRL, c->dma_ch);
+ } else if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
+ c->plat->dma_write(c->dma_ch, CLNK_CTRL, c->dma_ch);
+
+ /* Clear CSR */
+ if (dma_omap1())
+ c->plat->dma_read(CSR, c->dma_ch);
+ else
+ c->plat->dma_write(~0, CSR, c->dma_ch);
+
+ /* Enable interrupts */
+ c->plat->dma_write(d->cicr, CICR, c->dma_ch);
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
+ val |= OMAP_DMA_CCR_BUFFERING_DISABLE;
+ val |= OMAP_DMA_CCR_EN;
+ mb();
+ c->plat->dma_write(val, CCR, c->dma_ch);
+}
+
+static void omap_dma_stop(struct omap_chan *c)
+{
+ struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+ uint32_t val;
+
+ /* disable irq */
+ c->plat->dma_write(0, CICR, c->dma_ch);
+
+ /* Clear CSR */
+ if (dma_omap1())
+ c->plat->dma_read(CSR, c->dma_ch);
+ else
+ c->plat->dma_write(~0, CSR, c->dma_ch);
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ if (od->plat->errata & DMA_ERRATA_i541 &&
+ val & OMAP_DMA_CCR_SEL_SRC_DST_SYNC) {
+ uint32_t sysconfig;
+ unsigned i;
+
+ sysconfig = c->plat->dma_read(OCP_SYSCONFIG, c->dma_ch);
+ val = sysconfig & ~DMA_SYSCONFIG_MIDLEMODE_MASK;
+ val |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
+ c->plat->dma_write(val, OCP_SYSCONFIG, c->dma_ch);
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~OMAP_DMA_CCR_EN;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+
+ /* Wait for sDMA FIFO to drain */
+ for (i = 0; ; i++) {
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ if (!(val & (OMAP_DMA_CCR_RD_ACTIVE | OMAP_DMA_CCR_WR_ACTIVE)))
+ break;
+
+ if (i > 100)
+ break;
+
+ udelay(5);
+ }
+
+ if (val & (OMAP_DMA_CCR_RD_ACTIVE | OMAP_DMA_CCR_WR_ACTIVE))
+ dev_err(c->vc.chan.device->dev,
+ "DMA drain did not complete on lch %d\n",
+ c->dma_ch);
+
+ c->plat->dma_write(sysconfig, OCP_SYSCONFIG, c->dma_ch);
+ } else {
+ val &= ~OMAP_DMA_CCR_EN;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+ }
+
+ mb();
+
+ if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) {
+ val = c->plat->dma_read(CLNK_CTRL, c->dma_ch);
+
+ if (dma_omap1())
+ val |= 1 << 14; /* set the STOP_LNK bit */
+ else
+ val &= ~(1 << 15); /* Clear the ENABLE_LNK bit */
+
+ c->plat->dma_write(val, CLNK_CTRL, c->dma_ch);
+ }
+}
+
static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
unsigned idx)
{
@@ -113,7 +220,7 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
c->plat->dma_write(sg->en, CEN, c->dma_ch);
c->plat->dma_write(sg->fn, CFN, c->dma_ch);
- omap_start_dma(c->dma_ch);
+ omap_dma_start(c, d);
}
static void omap_dma_start_desc(struct omap_chan *c)
@@ -434,6 +541,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->sync_mode = OMAP_DMA_SYNC_FRAME;
d->sync_type = sync_type;
d->periph_port = OMAP_DMA_PORT_TIPB;
+ d->cicr = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
+
+ if (dma_omap1())
+ d->cicr |= OMAP1_DMA_TOUT_IRQ;
+ else
+ d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
/*
* Build our scatterlist entries: each contains the address,
@@ -463,6 +576,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
size_t period_len, enum dma_transfer_direction dir, unsigned long flags,
void *context)
{
+ struct omap_dmadev *od = to_omap_dma_dev(chan->device);
struct omap_chan *c = to_omap_dma_chan(chan);
enum dma_slave_buswidth dev_width;
struct omap_desc *d;
@@ -519,15 +633,25 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->sg[0].en = period_len / es_bytes[es];
d->sg[0].fn = buf_len / period_len;
d->sglen = 1;
+ d->cicr = OMAP_DMA_DROP_IRQ;
+ if (flags & DMA_PREP_INTERRUPT)
+ d->cicr |= OMAP_DMA_FRAME_IRQ;
+
+ if (dma_omap1())
+ d->cicr |= OMAP1_DMA_TOUT_IRQ;
+ else
+ d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
if (!c->cyclic) {
c->cyclic = true;
- omap_dma_link_lch(c->dma_ch, c->dma_ch);
- if (flags & DMA_PREP_INTERRUPT)
- omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ);
+ if (__dma_omap15xx(od->plat->dma_attr)) {
+ uint32_t val;
- omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ);
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val |= 3 << 8;
+ c->plat->dma_write(val, CCR, c->dma_ch);
+ }
}
if (dma_omap2plus()) {
@@ -568,20 +692,27 @@ static int omap_dma_terminate_all(struct omap_chan *c)
/*
* Stop DMA activity: we assume the callback will not be called
- * after omap_stop_dma() returns (even if it does, it will see
+ * after omap_dma_stop() returns (even if it does, it will see
* c->desc is NULL and exit.)
*/
if (c->desc) {
c->desc = NULL;
/* Avoid stopping the dma twice */
if (!c->paused)
- omap_stop_dma(c->dma_ch);
+ omap_dma_stop(c);
}
if (c->cyclic) {
c->cyclic = false;
c->paused = false;
- omap_dma_unlink_lch(c->dma_ch, c->dma_ch);
+
+ if (__dma_omap15xx(od->plat->dma_attr)) {
+ uint32_t val;
+
+ val = c->plat->dma_read(CCR, c->dma_ch);
+ val &= ~(3 << 8);
+ c->plat->dma_write(val, CCR, c->dma_ch);
+ }
}
vchan_get_all_descriptors(&c->vc, &head);
@@ -598,7 +729,7 @@ static int omap_dma_pause(struct omap_chan *c)
return -EINVAL;
if (!c->paused) {
- omap_stop_dma(c->dma_ch);
+ omap_dma_stop(c);
c->paused = true;
}
@@ -612,7 +743,7 @@ static int omap_dma_resume(struct omap_chan *c)
return -EINVAL;
if (c->paused) {
- omap_start_dma(c->dma_ch);
+ omap_dma_start(c, c->desc);
c->paused = false;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 06/26] dmaengine: omap-dma: move reading of dma position to omap-dma.c
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (4 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 05/26] dmaengine: omap-dma: control start/stop directly Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 07/26] dmaengine: omap-dma: consolidate setup of CSDP Russell King
` (22 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Read the current DMA position from the hardware directly rather than via
arch/arm/plat-omap/dma.c.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 7aa5ff7ab935..323eae2c9d08 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -427,6 +427,68 @@ static size_t omap_dma_desc_size_pos(struct omap_desc *d, dma_addr_t addr)
return size;
}
+static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
+{
+ struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+ dma_addr_t addr;
+
+ if (__dma_omap15xx(od->plat->dma_attr))
+ addr = c->plat->dma_read(CPC, c->dma_ch);
+ else
+ addr = c->plat->dma_read(CSAC, c->dma_ch);
+
+ if (od->plat->errata & DMA_ERRATA_3_3 && addr == 0)
+ addr = c->plat->dma_read(CSAC, c->dma_ch);
+
+ if (!__dma_omap15xx(od->plat->dma_attr)) {
+ /*
+ * CDAC == 0 indicates that the DMA transfer on the channel has
+ * not been started (no data has been transferred so far).
+ * Return the programmed source start address in this case.
+ */
+ if (c->plat->dma_read(CDAC, c->dma_ch))
+ addr = c->plat->dma_read(CSAC, c->dma_ch);
+ else
+ addr = c->plat->dma_read(CSSA, c->dma_ch);
+ }
+
+ if (dma_omap1())
+ addr |= c->plat->dma_read(CSSA, c->dma_ch) & 0xffff0000;
+
+ return addr;
+}
+
+static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c)
+{
+ struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+ dma_addr_t addr;
+
+ if (__dma_omap15xx(od->plat->dma_attr))
+ addr = c->plat->dma_read(CPC, c->dma_ch);
+ else
+ addr = c->plat->dma_read(CDAC, c->dma_ch);
+
+ /*
+ * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!__dma_omap15xx(od->plat->dma_attr) && addr == 0) {
+ addr = c->plat->dma_read(CDAC, c->dma_ch);
+ /*
+ * CDAC == 0 indicates that the DMA transfer on the channel has
+ * not been started (no data has been transferred so far).
+ * Return the programmed destination start address in this case.
+ */
+ if (addr == 0)
+ addr = c->plat->dma_read(CDSA, c->dma_ch);
+ }
+
+ if (dma_omap1())
+ addr |= c->plat->dma_read(CDSA, c->dma_ch) & 0xffff0000;
+
+ return addr;
+}
+
static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
dma_cookie_t cookie, struct dma_tx_state *txstate)
{
@@ -448,9 +510,9 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
dma_addr_t pos;
if (d->dir == DMA_MEM_TO_DEV)
- pos = omap_get_dma_src_pos(c->dma_ch);
+ pos = omap_dma_get_src_pos(c);
else if (d->dir == DMA_DEV_TO_MEM)
- pos = omap_get_dma_dst_pos(c->dma_ch);
+ pos = omap_dma_get_dst_pos(c);
else
pos = 0;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 07/26] dmaengine: omap-dma: consolidate setup of CSDP
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (5 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 06/26] dmaengine: omap-dma: move reading of dma position to omap-dma.c Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 08/26] dmaengine: omap-dma: consolidate setup of CCR Russell King
` (21 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Consolidate the setup of the channel source destination parameters
register. This way, we calculate the required CSDP value when we setup
a transfer descriptor, and only write it to the device registers once
when we start the descriptor.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 64 ++++++++++++++++++++++----------------------------
1 file changed, 28 insertions(+), 36 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 323eae2c9d08..ec7cc10d4594 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -60,8 +60,8 @@ struct omap_desc {
uint8_t es; /* OMAP_DMA_DATA_TYPE_xxx */
uint8_t sync_mode; /* OMAP_DMA_SYNC_xxx */
uint8_t sync_type; /* OMAP_DMA_xxx_SYNC* */
- uint8_t periph_port; /* Peripheral port */
uint16_t cicr; /* CICR value */
+ uint32_t csdp; /* CSDP value */
unsigned sglen;
struct omap_sg sg[0];
@@ -240,14 +240,6 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->sgidx = 0;
if (d->dir == DMA_DEV_TO_MEM) {
- if (dma_omap1()) {
- val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~(0x1f << 9 | 0x1f << 2);
- val |= OMAP_DMA_PORT_EMIFF << 9;
- val |= d->periph_port << 2;
- c->plat->dma_write(val, CSDP, c->dma_ch);
- }
-
val = c->plat->dma_read(CCR, c->dma_ch);
val &= ~(0x03 << 14 | 0x03 << 12);
val |= OMAP_DMA_AMODE_POST_INC << 14;
@@ -258,14 +250,6 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->plat->dma_write(0, CSEI, c->dma_ch);
c->plat->dma_write(d->fi, CSFI, c->dma_ch);
} else {
- if (dma_omap1()) {
- val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~(0x1f << 9 | 0x1f << 2);
- val |= d->periph_port << 9;
- val |= OMAP_DMA_PORT_EMIFF << 2;
- c->plat->dma_write(val, CSDP, c->dma_ch);
- }
-
val = c->plat->dma_read(CCR, c->dma_ch);
val &= ~(0x03 << 12 | 0x03 << 14);
val |= OMAP_DMA_AMODE_CONSTANT << 14;
@@ -277,10 +261,7 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->plat->dma_write(d->fi, CDFI, c->dma_ch);
}
- val = c->plat->dma_read(CSDP, c->dma_ch);
- val &= ~0x03;
- val |= d->es;
- c->plat->dma_write(val, CSDP, c->dma_ch);
+ c->plat->dma_write(d->csdp, CSDP, c->dma_ch);
if (dma_omap1()) {
val = c->plat->dma_read(CCR, c->dma_ch);
@@ -602,13 +583,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->es = es;
d->sync_mode = OMAP_DMA_SYNC_FRAME;
d->sync_type = sync_type;
- d->periph_port = OMAP_DMA_PORT_TIPB;
d->cicr = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
+ d->csdp = es;
- if (dma_omap1())
+ if (dma_omap1()) {
d->cicr |= OMAP1_DMA_TOUT_IRQ;
- else
+
+ if (dir == DMA_DEV_TO_MEM)
+ d->csdp |= OMAP_DMA_PORT_EMIFF << 9 |
+ OMAP_DMA_PORT_TIPB << 2;
+ else
+ d->csdp |= OMAP_DMA_PORT_TIPB << 9 |
+ OMAP_DMA_PORT_EMIFF << 2;
+ } else {
d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
+ }
/*
* Build our scatterlist entries: each contains the address,
@@ -690,7 +679,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
else
d->sync_mode = OMAP_DMA_SYNC_ELEMENT;
d->sync_type = sync_type;
- d->periph_port = OMAP_DMA_PORT_MPUI;
d->sg[0].addr = buf_addr;
d->sg[0].en = period_len / es_bytes[es];
d->sg[0].fn = buf_len / period_len;
@@ -699,11 +687,24 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
if (flags & DMA_PREP_INTERRUPT)
d->cicr |= OMAP_DMA_FRAME_IRQ;
- if (dma_omap1())
+ d->csdp = es;
+
+ if (dma_omap1()) {
d->cicr |= OMAP1_DMA_TOUT_IRQ;
- else
+
+ if (dir == DMA_DEV_TO_MEM)
+ d->csdp |= OMAP_DMA_PORT_EMIFF << 9 |
+ OMAP_DMA_PORT_MPUI << 2;
+ else
+ d->csdp |= OMAP_DMA_PORT_MPUI << 9 |
+ OMAP_DMA_PORT_EMIFF << 2;
+ } else {
d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
+ /* src and dst burst mode 16 */
+ d->csdp |= 3 << 14 | 3 << 7;
+ }
+
if (!c->cyclic) {
c->cyclic = true;
@@ -716,15 +717,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
}
}
- if (dma_omap2plus()) {
- uint32_t val;
-
- val = c->plat->dma_read(CSDP, c->dma_ch);
- val |= 0x03 << 7; /* src burst mode 16 */
- val |= 0x03 << 14; /* dst burst mode 16 */
- c->plat->dma_write(val, CSDP, c->dma_ch);
- }
-
return vchan_tx_prep(&c->vc, &d->vd, flags);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 08/26] dmaengine: omap-dma: consolidate setup of CCR
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (6 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 07/26] dmaengine: omap-dma: consolidate setup of CSDP Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 09/26] dmaengine: omap-dma: provide register definitions Russell King
` (20 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Consolidate the setup of the channel control register. Prepare the
basic value in the preparation of the DMA descriptor, and write it into
the register upon descriptor execution.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 147 ++++++++++++++++++++-----------------------------
1 file changed, 61 insertions(+), 86 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index ec7cc10d4594..9a9e81907475 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -58,8 +58,7 @@ struct omap_desc {
int16_t fi; /* for OMAP_DMA_SYNC_PACKET */
uint8_t es; /* OMAP_DMA_DATA_TYPE_xxx */
- uint8_t sync_mode; /* OMAP_DMA_SYNC_xxx */
- uint8_t sync_type; /* OMAP_DMA_xxx_SYNC* */
+ uint32_t ccr; /* CCR value */
uint16_t cicr; /* CICR value */
uint32_t csdp; /* CSDP value */
@@ -227,7 +226,6 @@ static void omap_dma_start_desc(struct omap_chan *c)
{
struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
struct omap_desc *d;
- uint32_t val;
if (!vd) {
c->desc = NULL;
@@ -239,23 +237,15 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->desc = d = to_omap_dma_desc(&vd->tx);
c->sgidx = 0;
- if (d->dir == DMA_DEV_TO_MEM) {
- val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(0x03 << 14 | 0x03 << 12);
- val |= OMAP_DMA_AMODE_POST_INC << 14;
- val |= OMAP_DMA_AMODE_CONSTANT << 12;
- c->plat->dma_write(val, CCR, c->dma_ch);
+ c->plat->dma_write(d->ccr, CCR, c->dma_ch);
+ if (dma_omap1())
+ c->plat->dma_write(d->ccr >> 16, CCR2, c->dma_ch);
+ if (d->dir == DMA_DEV_TO_MEM) {
c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
c->plat->dma_write(0, CSEI, c->dma_ch);
c->plat->dma_write(d->fi, CSFI, c->dma_ch);
} else {
- val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(0x03 << 12 | 0x03 << 14);
- val |= OMAP_DMA_AMODE_CONSTANT << 14;
- val |= OMAP_DMA_AMODE_POST_INC << 12;
- c->plat->dma_write(val, CCR, c->dma_ch);
-
c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
c->plat->dma_write(0, CDEI, c->dma_ch);
c->plat->dma_write(d->fi, CDFI, c->dma_ch);
@@ -263,45 +253,6 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->plat->dma_write(d->csdp, CSDP, c->dma_ch);
- if (dma_omap1()) {
- val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(1 << 5);
- if (d->sync_mode == OMAP_DMA_SYNC_FRAME)
- val |= 1 << 5;
- c->plat->dma_write(val, CCR, c->dma_ch);
-
- val = c->plat->dma_read(CCR2, c->dma_ch);
- val &= ~(1 << 2);
- if (d->sync_mode == OMAP_DMA_SYNC_BLOCK)
- val |= 1 << 2;
- c->plat->dma_write(val, CCR2, c->dma_ch);
- } else if (c->dma_sig) {
- val = c->plat->dma_read(CCR, c->dma_ch);
-
- /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
- val &= ~(1 << 24 | 1 << 23 | 3 << 19 | 1 << 18 | 1 << 5 | 0x1f);
- val |= (c->dma_sig & ~0x1f) << 14;
- val |= c->dma_sig & 0x1f;
-
- if (d->sync_mode & OMAP_DMA_SYNC_FRAME)
- val |= 1 << 5;
-
- if (d->sync_mode & OMAP_DMA_SYNC_BLOCK)
- val |= 1 << 18;
-
- switch (d->sync_type) {
- case OMAP_DMA_DST_SYNC_PREFETCH:/* dest synch */
- val |= 1 << 23; /* Prefetch */
- break;
- case 0:
- break;
- default:
- val |= 1 << 24; /* source synch */
- break;
- }
- c->plat->dma_write(val, CCR, c->dma_ch);
- }
-
omap_dma_start_sg(c, d, 0);
}
@@ -540,19 +491,17 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
struct scatterlist *sgent;
struct omap_desc *d;
dma_addr_t dev_addr;
- unsigned i, j = 0, es, en, frame_bytes, sync_type;
+ unsigned i, j = 0, es, en, frame_bytes;
u32 burst;
if (dir == DMA_DEV_TO_MEM) {
dev_addr = c->cfg.src_addr;
dev_width = c->cfg.src_addr_width;
burst = c->cfg.src_maxburst;
- sync_type = OMAP_DMA_SRC_SYNC;
} else if (dir == DMA_MEM_TO_DEV) {
dev_addr = c->cfg.dst_addr;
dev_width = c->cfg.dst_addr_width;
burst = c->cfg.dst_maxburst;
- sync_type = OMAP_DMA_DST_SYNC;
} else {
dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
return NULL;
@@ -581,12 +530,28 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->dir = dir;
d->dev_addr = dev_addr;
d->es = es;
- d->sync_mode = OMAP_DMA_SYNC_FRAME;
- d->sync_type = sync_type;
+
+ d->ccr = 0;
+ if (dir == DMA_DEV_TO_MEM)
+ d->ccr |= OMAP_DMA_AMODE_POST_INC << 14 |
+ OMAP_DMA_AMODE_CONSTANT << 12;
+ else
+ d->ccr |= OMAP_DMA_AMODE_CONSTANT << 14 |
+ OMAP_DMA_AMODE_POST_INC << 12;
+
d->cicr = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
d->csdp = es;
if (dma_omap1()) {
+ d->ccr |= 1 << 5; /* frame sync */
+ if (__dma_omap16xx(od->plat->dma_attr)) {
+ d->ccr |= 1 << 10; /* disable 3.0/3.1 compatibility mode */
+ /* Duplicate what plat-omap/dma.c does */
+ d->ccr |= c->dma_ch + 1;
+ } else {
+ d->ccr |= c->dma_sig & 0x1f;
+ }
+
d->cicr |= OMAP1_DMA_TOUT_IRQ;
if (dir == DMA_DEV_TO_MEM)
@@ -596,6 +561,13 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->csdp |= OMAP_DMA_PORT_TIPB << 9 |
OMAP_DMA_PORT_EMIFF << 2;
} else {
+ d->ccr |= (c->dma_sig & ~0x1f) << 14;
+ d->ccr |= c->dma_sig & 0x1f;
+ d->ccr |= 1 << 5; /* frame sync */
+
+ if (dir == DMA_DEV_TO_MEM)
+ d->ccr |= 1 << 24; /* source synch */
+
d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
}
@@ -632,19 +604,17 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
enum dma_slave_buswidth dev_width;
struct omap_desc *d;
dma_addr_t dev_addr;
- unsigned es, sync_type;
+ unsigned es;
u32 burst;
if (dir == DMA_DEV_TO_MEM) {
dev_addr = c->cfg.src_addr;
dev_width = c->cfg.src_addr_width;
burst = c->cfg.src_maxburst;
- sync_type = OMAP_DMA_SRC_SYNC;
} else if (dir == DMA_MEM_TO_DEV) {
dev_addr = c->cfg.dst_addr;
dev_width = c->cfg.dst_addr_width;
burst = c->cfg.dst_maxburst;
- sync_type = OMAP_DMA_DST_SYNC;
} else {
dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
return NULL;
@@ -674,15 +644,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->dev_addr = dev_addr;
d->fi = burst;
d->es = es;
- if (burst)
- d->sync_mode = OMAP_DMA_SYNC_PACKET;
- else
- d->sync_mode = OMAP_DMA_SYNC_ELEMENT;
- d->sync_type = sync_type;
d->sg[0].addr = buf_addr;
d->sg[0].en = period_len / es_bytes[es];
d->sg[0].fn = buf_len / period_len;
d->sglen = 1;
+
+ d->ccr = 0;
+ if (__dma_omap15xx(od->plat->dma_attr))
+ d->ccr = 3 << 8;
+ if (dir == DMA_DEV_TO_MEM)
+ d->ccr |= OMAP_DMA_AMODE_POST_INC << 14 |
+ OMAP_DMA_AMODE_CONSTANT << 12;
+ else
+ d->ccr |= OMAP_DMA_AMODE_CONSTANT << 14 |
+ OMAP_DMA_AMODE_POST_INC << 12;
+
d->cicr = OMAP_DMA_DROP_IRQ;
if (flags & DMA_PREP_INTERRUPT)
d->cicr |= OMAP_DMA_FRAME_IRQ;
@@ -690,6 +666,14 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->csdp = es;
if (dma_omap1()) {
+ if (__dma_omap16xx(od->plat->dma_attr)) {
+ d->ccr |= 1 << 10; /* disable 3.0/3.1 compatibility mode */
+ /* Duplicate what plat-omap/dma.c does */
+ d->ccr |= c->dma_ch + 1;
+ } else {
+ d->ccr |= c->dma_sig & 0x1f;
+ }
+
d->cicr |= OMAP1_DMA_TOUT_IRQ;
if (dir == DMA_DEV_TO_MEM)
@@ -699,23 +683,22 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->csdp |= OMAP_DMA_PORT_MPUI << 9 |
OMAP_DMA_PORT_EMIFF << 2;
} else {
+ d->ccr |= (c->dma_sig & ~0x1f) << 14;
+ d->ccr |= c->dma_sig & 0x1f;
+
+ if (burst)
+ d->ccr |= 1 << 18 | 1 << 5; /* packet */
+
+ if (dir == DMA_DEV_TO_MEM)
+ d->ccr |= 1 << 24; /* source synch */
+
d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
/* src and dst burst mode 16 */
d->csdp |= 3 << 14 | 3 << 7;
}
- if (!c->cyclic) {
- c->cyclic = true;
-
- if (__dma_omap15xx(od->plat->dma_attr)) {
- uint32_t val;
-
- val = c->plat->dma_read(CCR, c->dma_ch);
- val |= 3 << 8;
- c->plat->dma_write(val, CCR, c->dma_ch);
- }
- }
+ c->cyclic = true;
return vchan_tx_prep(&c->vc, &d->vd, flags);
}
@@ -759,14 +742,6 @@ static int omap_dma_terminate_all(struct omap_chan *c)
if (c->cyclic) {
c->cyclic = false;
c->paused = false;
-
- if (__dma_omap15xx(od->plat->dma_attr)) {
- uint32_t val;
-
- val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~(3 << 8);
- c->plat->dma_write(val, CCR, c->dma_ch);
- }
}
vchan_get_all_descriptors(&c->vc, &head);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 09/26] dmaengine: omap-dma: provide register definitions
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (7 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 08/26] dmaengine: omap-dma: consolidate setup of CCR Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 10/26] dmaengine: omap-dma: move CCR buffering disable errata out of the fast path Russell King
` (19 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Provide our own set of more complete register definitions; this allows
us to get rid of the meaningless 1 << n constants scattered throughout
this code.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 171 +++++++++++++++++++++++++++++++++----------------
1 file changed, 117 insertions(+), 54 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 9a9e81907475..6cf66e608338 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -57,7 +57,7 @@ struct omap_desc {
dma_addr_t dev_addr;
int16_t fi; /* for OMAP_DMA_SYNC_PACKET */
- uint8_t es; /* OMAP_DMA_DATA_TYPE_xxx */
+ uint8_t es; /* CSDP_DATA_TYPE_xxx */
uint32_t ccr; /* CCR value */
uint16_t cicr; /* CICR value */
uint32_t csdp; /* CSDP value */
@@ -66,10 +66,83 @@ struct omap_desc {
struct omap_sg sg[0];
};
+enum {
+ CCR_FS = BIT(5),
+ CCR_READ_PRIORITY = BIT(6),
+ CCR_ENABLE = BIT(7),
+ CCR_AUTO_INIT = BIT(8), /* OMAP1 only */
+ CCR_REPEAT = BIT(9), /* OMAP1 only */
+ CCR_OMAP31_DISABLE = BIT(10), /* OMAP1 only */
+ CCR_SUSPEND_SENSITIVE = BIT(8), /* OMAP2+ only */
+ CCR_RD_ACTIVE = BIT(9), /* OMAP2+ only */
+ CCR_WR_ACTIVE = BIT(10), /* OMAP2+ only */
+ CCR_SRC_AMODE_CONSTANT = 0 << 12,
+ CCR_SRC_AMODE_POSTINC = 1 << 12,
+ CCR_SRC_AMODE_SGLIDX = 2 << 12,
+ CCR_SRC_AMODE_DBLIDX = 3 << 12,
+ CCR_DST_AMODE_CONSTANT = 0 << 14,
+ CCR_DST_AMODE_POSTINC = 1 << 14,
+ CCR_DST_AMODE_SGLIDX = 2 << 14,
+ CCR_DST_AMODE_DBLIDX = 3 << 14,
+ CCR_CONSTANT_FILL = BIT(16),
+ CCR_TRANSPARENT_COPY = BIT(17),
+ CCR_BS = BIT(18),
+ CCR_SUPERVISOR = BIT(22),
+ CCR_PREFETCH = BIT(23),
+ CCR_TRIGGER_SRC = BIT(24),
+ CCR_BUFFERING_DISABLE = BIT(25),
+ CCR_WRITE_PRIORITY = BIT(26),
+ CCR_SYNC_ELEMENT = 0,
+ CCR_SYNC_FRAME = CCR_FS,
+ CCR_SYNC_BLOCK = CCR_BS,
+ CCR_SYNC_PACKET = CCR_BS | CCR_FS,
+
+ CSDP_DATA_TYPE_8 = 0,
+ CSDP_DATA_TYPE_16 = 1,
+ CSDP_DATA_TYPE_32 = 2,
+ CSDP_SRC_PORT_EMIFF = 0 << 2, /* OMAP1 only */
+ CSDP_SRC_PORT_EMIFS = 1 << 2, /* OMAP1 only */
+ CSDP_SRC_PORT_OCP_T1 = 2 << 2, /* OMAP1 only */
+ CSDP_SRC_PORT_TIPB = 3 << 2, /* OMAP1 only */
+ CSDP_SRC_PORT_OCP_T2 = 4 << 2, /* OMAP1 only */
+ CSDP_SRC_PORT_MPUI = 5 << 2, /* OMAP1 only */
+ CSDP_SRC_PACKED = BIT(6),
+ CSDP_SRC_BURST_1 = 0 << 7,
+ CSDP_SRC_BURST_16 = 1 << 7,
+ CSDP_SRC_BURST_32 = 2 << 7,
+ CSDP_SRC_BURST_64 = 3 << 7,
+ CSDP_DST_PORT_EMIFF = 0 << 9, /* OMAP1 only */
+ CSDP_DST_PORT_EMIFS = 1 << 9, /* OMAP1 only */
+ CSDP_DST_PORT_OCP_T1 = 2 << 9, /* OMAP1 only */
+ CSDP_DST_PORT_TIPB = 3 << 9, /* OMAP1 only */
+ CSDP_DST_PORT_OCP_T2 = 4 << 9, /* OMAP1 only */
+ CSDP_DST_PORT_MPUI = 5 << 9, /* OMAP1 only */
+ CSDP_DST_PACKED = BIT(13),
+ CSDP_DST_BURST_1 = 0 << 14,
+ CSDP_DST_BURST_16 = 1 << 14,
+ CSDP_DST_BURST_32 = 2 << 14,
+ CSDP_DST_BURST_64 = 3 << 14,
+
+ CICR_TOUT_IE = BIT(0), /* OMAP1 only */
+ CICR_DROP_IE = BIT(1),
+ CICR_HALF_IE = BIT(2),
+ CICR_FRAME_IE = BIT(3),
+ CICR_LAST_IE = BIT(4),
+ CICR_BLOCK_IE = BIT(5),
+ CICR_PKT_IE = BIT(7), /* OMAP2+ only */
+ CICR_TRANS_ERR_IE = BIT(8), /* OMAP2+ only */
+ CICR_SUPERVISOR_ERR_IE = BIT(10), /* OMAP2+ only */
+ CICR_MISALIGNED_ERR_IE = BIT(11), /* OMAP2+ only */
+ CICR_DRAIN_IE = BIT(12), /* OMAP2+ only */
+ CICR_SUPER_BLOCK_IE = BIT(14), /* OMAP2+ only */
+
+ CLNK_CTRL_ENABLE_LNK = BIT(15),
+};
+
static const unsigned es_bytes[] = {
- [OMAP_DMA_DATA_TYPE_S8] = 1,
- [OMAP_DMA_DATA_TYPE_S16] = 2,
- [OMAP_DMA_DATA_TYPE_S32] = 4,
+ [CSDP_DATA_TYPE_8] = 1,
+ [CSDP_DATA_TYPE_16] = 2,
+ [CSDP_DATA_TYPE_32] = 4,
};
static struct of_dma_filter_info omap_dma_info = {
@@ -112,7 +185,7 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
if (dma_omap1())
val &= ~(1 << 14);
- val |= c->dma_ch | 1 << 15;
+ val |= c->dma_ch | CLNK_CTRL_ENABLE_LNK;
c->plat->dma_write(val, CLNK_CTRL, c->dma_ch);
} else if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
@@ -129,8 +202,8 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
val = c->plat->dma_read(CCR, c->dma_ch);
if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
- val |= OMAP_DMA_CCR_BUFFERING_DISABLE;
- val |= OMAP_DMA_CCR_EN;
+ val |= CCR_BUFFERING_DISABLE;
+ val |= CCR_ENABLE;
mb();
c->plat->dma_write(val, CCR, c->dma_ch);
}
@@ -150,8 +223,7 @@ static void omap_dma_stop(struct omap_chan *c)
c->plat->dma_write(~0, CSR, c->dma_ch);
val = c->plat->dma_read(CCR, c->dma_ch);
- if (od->plat->errata & DMA_ERRATA_i541 &&
- val & OMAP_DMA_CCR_SEL_SRC_DST_SYNC) {
+ if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) {
uint32_t sysconfig;
unsigned i;
@@ -161,13 +233,13 @@ static void omap_dma_stop(struct omap_chan *c)
c->plat->dma_write(val, OCP_SYSCONFIG, c->dma_ch);
val = c->plat->dma_read(CCR, c->dma_ch);
- val &= ~OMAP_DMA_CCR_EN;
+ val &= ~CCR_ENABLE;
c->plat->dma_write(val, CCR, c->dma_ch);
/* Wait for sDMA FIFO to drain */
for (i = 0; ; i++) {
val = c->plat->dma_read(CCR, c->dma_ch);
- if (!(val & (OMAP_DMA_CCR_RD_ACTIVE | OMAP_DMA_CCR_WR_ACTIVE)))
+ if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
break;
if (i > 100)
@@ -176,14 +248,14 @@ static void omap_dma_stop(struct omap_chan *c)
udelay(5);
}
- if (val & (OMAP_DMA_CCR_RD_ACTIVE | OMAP_DMA_CCR_WR_ACTIVE))
+ if (val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
dev_err(c->vc.chan.device->dev,
"DMA drain did not complete on lch %d\n",
c->dma_ch);
c->plat->dma_write(sysconfig, OCP_SYSCONFIG, c->dma_ch);
} else {
- val &= ~OMAP_DMA_CCR_EN;
+ val &= ~CCR_ENABLE;
c->plat->dma_write(val, CCR, c->dma_ch);
}
@@ -195,7 +267,7 @@ static void omap_dma_stop(struct omap_chan *c)
if (dma_omap1())
val |= 1 << 14; /* set the STOP_LNK bit */
else
- val &= ~(1 << 15); /* Clear the ENABLE_LNK bit */
+ val &= ~CLNK_CTRL_ENABLE_LNK;
c->plat->dma_write(val, CLNK_CTRL, c->dma_ch);
}
@@ -510,13 +582,13 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
/* Bus width translates to the element size (ES) */
switch (dev_width) {
case DMA_SLAVE_BUSWIDTH_1_BYTE:
- es = OMAP_DMA_DATA_TYPE_S8;
+ es = CSDP_DATA_TYPE_8;
break;
case DMA_SLAVE_BUSWIDTH_2_BYTES:
- es = OMAP_DMA_DATA_TYPE_S16;
+ es = CSDP_DATA_TYPE_16;
break;
case DMA_SLAVE_BUSWIDTH_4_BYTES:
- es = OMAP_DMA_DATA_TYPE_S32;
+ es = CSDP_DATA_TYPE_32;
break;
default: /* not reached */
return NULL;
@@ -531,44 +603,38 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->dev_addr = dev_addr;
d->es = es;
- d->ccr = 0;
+ d->ccr = CCR_SYNC_FRAME;
if (dir == DMA_DEV_TO_MEM)
- d->ccr |= OMAP_DMA_AMODE_POST_INC << 14 |
- OMAP_DMA_AMODE_CONSTANT << 12;
+ d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
else
- d->ccr |= OMAP_DMA_AMODE_CONSTANT << 14 |
- OMAP_DMA_AMODE_POST_INC << 12;
+ d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC;
- d->cicr = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
+ d->cicr = CICR_DROP_IE | CICR_BLOCK_IE;
d->csdp = es;
if (dma_omap1()) {
- d->ccr |= 1 << 5; /* frame sync */
if (__dma_omap16xx(od->plat->dma_attr)) {
- d->ccr |= 1 << 10; /* disable 3.0/3.1 compatibility mode */
+ d->ccr |= CCR_OMAP31_DISABLE;
/* Duplicate what plat-omap/dma.c does */
d->ccr |= c->dma_ch + 1;
} else {
d->ccr |= c->dma_sig & 0x1f;
}
- d->cicr |= OMAP1_DMA_TOUT_IRQ;
+ d->cicr |= CICR_TOUT_IE;
if (dir == DMA_DEV_TO_MEM)
- d->csdp |= OMAP_DMA_PORT_EMIFF << 9 |
- OMAP_DMA_PORT_TIPB << 2;
+ d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_TIPB;
else
- d->csdp |= OMAP_DMA_PORT_TIPB << 9 |
- OMAP_DMA_PORT_EMIFF << 2;
+ d->csdp |= CSDP_DST_PORT_TIPB | CSDP_SRC_PORT_EMIFF;
} else {
d->ccr |= (c->dma_sig & ~0x1f) << 14;
d->ccr |= c->dma_sig & 0x1f;
- d->ccr |= 1 << 5; /* frame sync */
if (dir == DMA_DEV_TO_MEM)
- d->ccr |= 1 << 24; /* source synch */
+ d->ccr |= CCR_TRIGGER_SRC;
- d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
+ d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
}
/*
@@ -623,13 +689,13 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
/* Bus width translates to the element size (ES) */
switch (dev_width) {
case DMA_SLAVE_BUSWIDTH_1_BYTE:
- es = OMAP_DMA_DATA_TYPE_S8;
+ es = CSDP_DATA_TYPE_8;
break;
case DMA_SLAVE_BUSWIDTH_2_BYTES:
- es = OMAP_DMA_DATA_TYPE_S16;
+ es = CSDP_DATA_TYPE_16;
break;
case DMA_SLAVE_BUSWIDTH_4_BYTES:
- es = OMAP_DMA_DATA_TYPE_S32;
+ es = CSDP_DATA_TYPE_32;
break;
default: /* not reached */
return NULL;
@@ -651,51 +717,48 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->ccr = 0;
if (__dma_omap15xx(od->plat->dma_attr))
- d->ccr = 3 << 8;
+ d->ccr = CCR_AUTO_INIT | CCR_REPEAT;
if (dir == DMA_DEV_TO_MEM)
- d->ccr |= OMAP_DMA_AMODE_POST_INC << 14 |
- OMAP_DMA_AMODE_CONSTANT << 12;
+ d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
else
- d->ccr |= OMAP_DMA_AMODE_CONSTANT << 14 |
- OMAP_DMA_AMODE_POST_INC << 12;
+ d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC;
- d->cicr = OMAP_DMA_DROP_IRQ;
+ d->cicr = CICR_DROP_IE;
if (flags & DMA_PREP_INTERRUPT)
- d->cicr |= OMAP_DMA_FRAME_IRQ;
+ d->cicr |= CICR_FRAME_IE;
d->csdp = es;
if (dma_omap1()) {
if (__dma_omap16xx(od->plat->dma_attr)) {
- d->ccr |= 1 << 10; /* disable 3.0/3.1 compatibility mode */
+ d->ccr |= CCR_OMAP31_DISABLE;
/* Duplicate what plat-omap/dma.c does */
d->ccr |= c->dma_ch + 1;
} else {
d->ccr |= c->dma_sig & 0x1f;
}
- d->cicr |= OMAP1_DMA_TOUT_IRQ;
+ d->cicr |= CICR_TOUT_IE;
if (dir == DMA_DEV_TO_MEM)
- d->csdp |= OMAP_DMA_PORT_EMIFF << 9 |
- OMAP_DMA_PORT_MPUI << 2;
+ d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_MPUI;
else
- d->csdp |= OMAP_DMA_PORT_MPUI << 9 |
- OMAP_DMA_PORT_EMIFF << 2;
+ d->csdp |= CSDP_DST_PORT_MPUI | CSDP_SRC_PORT_EMIFF;
} else {
d->ccr |= (c->dma_sig & ~0x1f) << 14;
d->ccr |= c->dma_sig & 0x1f;
if (burst)
- d->ccr |= 1 << 18 | 1 << 5; /* packet */
+ d->ccr |= CCR_SYNC_PACKET;
+ else
+ d->ccr |= CCR_SYNC_ELEMENT;
if (dir == DMA_DEV_TO_MEM)
- d->ccr |= 1 << 24; /* source synch */
+ d->ccr |= CCR_TRIGGER_SRC;
- d->cicr |= OMAP2_DMA_MISALIGNED_ERR_IRQ | OMAP2_DMA_TRANS_ERR_IRQ;
+ d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
- /* src and dst burst mode 16 */
- d->csdp |= 3 << 14 | 3 << 7;
+ d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
}
c->cyclic = true;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 10/26] dmaengine: omap-dma: move CCR buffering disable errata out of the fast path
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (8 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 09/26] dmaengine: omap-dma: provide register definitions Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 11/26] dmaengine: omap-dma: consolidate clearing channel status register Russell King
` (18 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Since we record the CCR register in the dma transaction, we can move the
processing of the iframe buffering errata out of the omap_dma_start().
Move it to the preparation functions.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 6cf66e608338..324f4c7c5dd0 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -201,8 +201,6 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
c->plat->dma_write(d->cicr, CICR, c->dma_ch);
val = c->plat->dma_read(CCR, c->dma_ch);
- if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
- val |= CCR_BUFFERING_DISABLE;
val |= CCR_ENABLE;
mb();
c->plat->dma_write(val, CCR, c->dma_ch);
@@ -558,6 +556,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl, unsigned sglen,
enum dma_transfer_direction dir, unsigned long tx_flags, void *context)
{
+ struct omap_dmadev *od = to_omap_dma_dev(chan->device);
struct omap_chan *c = to_omap_dma_chan(chan);
enum dma_slave_buswidth dev_width;
struct scatterlist *sgent;
@@ -636,6 +635,8 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
}
+ if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
+ d->ccr |= CCR_BUFFERING_DISABLE;
/*
* Build our scatterlist entries: each contains the address,
@@ -760,6 +761,8 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
}
+ if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
+ d->ccr |= CCR_BUFFERING_DISABLE;
c->cyclic = true;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 11/26] dmaengine: omap-dma: consolidate clearing channel status register
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (9 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 10/26] dmaengine: omap-dma: move CCR buffering disable errata out of the fast path Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 12/26] dmaengine: omap-dma: improve efficiency loading C.SA/C.EI/C.FI registers Russell King
` (17 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 324f4c7c5dd0..d1641aa9d113 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -169,6 +169,14 @@ static void omap_dma_desc_free(struct virt_dma_desc *vd)
kfree(container_of(vd, struct omap_desc, vd));
}
+static void omap_dma_clear_csr(struct omap_chan *c)
+{
+ if (dma_omap1())
+ c->plat->dma_read(CSR, c->dma_ch);
+ else
+ c->plat->dma_write(~0, CSR, c->dma_ch);
+}
+
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);
@@ -191,11 +199,7 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
} else if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
c->plat->dma_write(c->dma_ch, CLNK_CTRL, c->dma_ch);
- /* Clear CSR */
- if (dma_omap1())
- c->plat->dma_read(CSR, c->dma_ch);
- else
- c->plat->dma_write(~0, CSR, c->dma_ch);
+ omap_dma_clear_csr(c);
/* Enable interrupts */
c->plat->dma_write(d->cicr, CICR, c->dma_ch);
@@ -214,11 +218,7 @@ static void omap_dma_stop(struct omap_chan *c)
/* disable irq */
c->plat->dma_write(0, CICR, c->dma_ch);
- /* Clear CSR */
- if (dma_omap1())
- c->plat->dma_read(CSR, c->dma_ch);
- else
- c->plat->dma_write(~0, CSR, c->dma_ch);
+ omap_dma_clear_csr(c);
val = c->plat->dma_read(CCR, c->dma_ch);
if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) {
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 12/26] dmaengine: omap-dma: improve efficiency loading C.SA/C.EI/C.FI registers
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (10 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 11/26] dmaengine: omap-dma: consolidate clearing channel status register Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:56 ` [PATCH 13/26] dmaengine: omap-dma: move clnk_ctrl setting to preparation functions Russell King
` (16 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index d1641aa9d113..06727a78e883 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -275,17 +275,21 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
unsigned idx)
{
struct omap_sg *sg = d->sg + idx;
+ unsigned cxsa, cxei, cxfi;
if (d->dir == DMA_DEV_TO_MEM) {
- c->plat->dma_write(sg->addr, CDSA, c->dma_ch);
- c->plat->dma_write(0, CDEI, c->dma_ch);
- c->plat->dma_write(0, CDFI, c->dma_ch);
+ cxsa = CDSA;
+ cxei = CDEI;
+ cxfi = CDFI;
} else {
- c->plat->dma_write(sg->addr, CSSA, c->dma_ch);
- c->plat->dma_write(0, CSEI, c->dma_ch);
- c->plat->dma_write(0, CSFI, c->dma_ch);
+ cxsa = CSSA;
+ cxei = CSEI;
+ cxfi = CSFI;
}
+ c->plat->dma_write(sg->addr, cxsa, c->dma_ch);
+ c->plat->dma_write(0, cxei, c->dma_ch);
+ c->plat->dma_write(0, cxfi, c->dma_ch);
c->plat->dma_write(sg->en, CEN, c->dma_ch);
c->plat->dma_write(sg->fn, CFN, c->dma_ch);
@@ -296,6 +300,7 @@ static void omap_dma_start_desc(struct omap_chan *c)
{
struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
struct omap_desc *d;
+ unsigned cxsa, cxei, cxfi;
if (!vd) {
c->desc = NULL;
@@ -312,15 +317,18 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->plat->dma_write(d->ccr >> 16, CCR2, c->dma_ch);
if (d->dir == DMA_DEV_TO_MEM) {
- c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
- c->plat->dma_write(0, CSEI, c->dma_ch);
- c->plat->dma_write(d->fi, CSFI, c->dma_ch);
+ cxsa = CSSA;
+ cxei = CSEI;
+ cxfi = CSFI;
} else {
- c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
- c->plat->dma_write(0, CDEI, c->dma_ch);
- c->plat->dma_write(d->fi, CDFI, c->dma_ch);
+ cxsa = CDSA;
+ cxei = CDEI;
+ cxfi = CDFI;
}
+ c->plat->dma_write(d->dev_addr, cxsa, c->dma_ch);
+ c->plat->dma_write(0, cxei, c->dma_ch);
+ c->plat->dma_write(d->fi, cxfi, c->dma_ch);
c->plat->dma_write(d->csdp, CSDP, c->dma_ch);
omap_dma_start_sg(c, d, 0);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 13/26] dmaengine: omap-dma: move clnk_ctrl setting to preparation functions
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (11 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 12/26] dmaengine: omap-dma: improve efficiency loading C.SA/C.EI/C.FI registers Russell King
@ 2014-02-10 15:56 ` Russell King
2014-02-10 15:57 ` [PATCH 14/26] dmaengine: omap-dma: move barrier to omap_dma_start_desc() Russell King
` (15 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:56 UTC (permalink / raw)
To: linux-arm-kernel
Move the clnk_ctrl setup to the preparation functions, saving its
value in the omap_desc. This only needs to be set once per descriptor,
not for each segment, so set it in omap_dma_start_desc() rather than
omap_dma_start().
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 06727a78e883..49609275b2e7 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -59,6 +59,7 @@ struct omap_desc {
int16_t fi; /* for OMAP_DMA_SYNC_PACKET */
uint8_t es; /* CSDP_DATA_TYPE_xxx */
uint32_t ccr; /* CCR value */
+ uint16_t clnk_ctrl; /* CLNK_CTRL value */
uint16_t cicr; /* CICR value */
uint32_t csdp; /* CSDP value */
@@ -187,18 +188,6 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
else
c->plat->dma_write(0, CDAC, c->dma_ch);
- if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) {
- val = c->plat->dma_read(CLNK_CTRL, c->dma_ch);
-
- if (dma_omap1())
- val &= ~(1 << 14);
-
- val |= c->dma_ch | CLNK_CTRL_ENABLE_LNK;
-
- c->plat->dma_write(val, CLNK_CTRL, c->dma_ch);
- } else if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
- c->plat->dma_write(c->dma_ch, CLNK_CTRL, c->dma_ch);
-
omap_dma_clear_csr(c);
/* Enable interrupts */
@@ -330,6 +319,7 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->plat->dma_write(0, cxei, c->dma_ch);
c->plat->dma_write(d->fi, cxfi, c->dma_ch);
c->plat->dma_write(d->csdp, CSDP, c->dma_ch);
+ c->plat->dma_write(d->clnk_ctrl, CLNK_CTRL, c->dma_ch);
omap_dma_start_sg(c, d, 0);
}
@@ -645,6 +635,8 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
}
if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
d->ccr |= CCR_BUFFERING_DISABLE;
+ if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
+ d->clnk_ctrl = c->dma_ch;
/*
* Build our scatterlist entries: each contains the address,
@@ -725,8 +717,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->sglen = 1;
d->ccr = 0;
- if (__dma_omap15xx(od->plat->dma_attr))
- d->ccr = CCR_AUTO_INIT | CCR_REPEAT;
if (dir == DMA_DEV_TO_MEM)
d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
else
@@ -772,6 +762,11 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
d->ccr |= CCR_BUFFERING_DISABLE;
+ if (__dma_omap15xx(od->plat->dma_attr))
+ d->ccr |= CCR_AUTO_INIT | CCR_REPEAT;
+ else
+ d->clnk_ctrl = c->dma_ch | CLNK_CTRL_ENABLE_LNK;
+
c->cyclic = true;
return vchan_tx_prep(&c->vc, &d->vd, flags);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 14/26] dmaengine: omap-dma: move barrier to omap_dma_start_desc()
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (12 preceding siblings ...)
2014-02-10 15:56 ` [PATCH 13/26] dmaengine: omap-dma: move clnk_ctrl setting to preparation functions Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 15/26] dmaengine: omap-dma: use cached CCR value when enabling DMA Russell King
` (14 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
We don't need to issue a barrier for every segment of a DMA transfer;
doing this just once per descriptor will do.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 49609275b2e7..49b303296d75 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -195,7 +195,6 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
val = c->plat->dma_read(CCR, c->dma_ch);
val |= CCR_ENABLE;
- mb();
c->plat->dma_write(val, CCR, c->dma_ch);
}
@@ -301,6 +300,13 @@ static void omap_dma_start_desc(struct omap_chan *c)
c->desc = d = to_omap_dma_desc(&vd->tx);
c->sgidx = 0;
+ /*
+ * This provides the necessary barrier to ensure data held in
+ * DMA coherent memory is visible to the DMA engine prior to
+ * the transfer starting.
+ */
+ mb();
+
c->plat->dma_write(d->ccr, CCR, c->dma_ch);
if (dma_omap1())
c->plat->dma_write(d->ccr >> 16, CCR2, c->dma_ch);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 15/26] dmaengine: omap-dma: use cached CCR value when enabling DMA
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (13 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 14/26] dmaengine: omap-dma: move barrier to omap_dma_start_desc() Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 16/26] dmaengine: omap-dma: provide register read/write functions Russell King
` (13 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
We don't need to read-modify-write the CCR register; we already know
what value it should contain at this point. Use the cached CCR value
when setting the enable bit.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 49b303296d75..b270aedf1d15 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -181,7 +181,6 @@ static void omap_dma_clear_csr(struct omap_chan *c)
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);
- uint32_t val;
if (__dma_omap15xx(od->plat->dma_attr))
c->plat->dma_write(0, CPC, c->dma_ch);
@@ -193,9 +192,8 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
/* Enable interrupts */
c->plat->dma_write(d->cicr, CICR, c->dma_ch);
- val = c->plat->dma_read(CCR, c->dma_ch);
- val |= CCR_ENABLE;
- c->plat->dma_write(val, CCR, c->dma_ch);
+ /* Enable channel */
+ c->plat->dma_write(d->ccr | CCR_ENABLE, CCR, c->dma_ch);
}
static void omap_dma_stop(struct omap_chan *c)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 16/26] dmaengine: omap-dma: provide register read/write functions
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (14 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 15/26] dmaengine: omap-dma: use cached CCR value when enabling DMA Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 17/26] dmaengine: omap-dma: cleanup errata 3.3 handling Russell King
` (12 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
Provide a pair of channel register accessors, and a pair of global
accessors for non-channel specific registers.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 102 +++++++++++++++++++++++++++++--------------------
1 file changed, 61 insertions(+), 41 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index b270aedf1d15..a1baada7dcd4 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -170,12 +170,32 @@ static void omap_dma_desc_free(struct virt_dma_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)
{
if (dma_omap1())
- c->plat->dma_read(CSR, c->dma_ch);
+ omap_dma_chan_read(c, CSR);
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)
@@ -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);
if (__dma_omap15xx(od->plat->dma_attr))
- c->plat->dma_write(0, CPC, c->dma_ch);
+ omap_dma_chan_write(c, CPC, 0);
else
- c->plat->dma_write(0, CDAC, c->dma_ch);
+ omap_dma_chan_write(c, CDAC, 0);
omap_dma_clear_csr(c);
/* Enable interrupts */
- c->plat->dma_write(d->cicr, CICR, c->dma_ch);
+ omap_dma_chan_write(c, CICR, d->cicr);
/* 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)
@@ -202,27 +222,27 @@ static void omap_dma_stop(struct omap_chan *c)
uint32_t val;
/* disable irq */
- c->plat->dma_write(0, CICR, c->dma_ch);
+ omap_dma_chan_write(c, CICR, 0);
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) {
uint32_t sysconfig;
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 |= 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;
- c->plat->dma_write(val, CCR, c->dma_ch);
+ omap_dma_chan_write(c, CCR, val);
/* Wait for sDMA FIFO to drain */
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)))
break;
@@ -237,23 +257,23 @@ static void omap_dma_stop(struct omap_chan *c)
"DMA drain did not complete on lch %d\n",
c->dma_ch);
- c->plat->dma_write(sysconfig, OCP_SYSCONFIG, c->dma_ch);
+ omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else {
val &= ~CCR_ENABLE;
- c->plat->dma_write(val, CCR, c->dma_ch);
+ omap_dma_chan_write(c, CCR, val);
}
mb();
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())
val |= 1 << 14; /* set the STOP_LNK bit */
else
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,
cxfi = CSFI;
}
- c->plat->dma_write(sg->addr, cxsa, c->dma_ch);
- c->plat->dma_write(0, cxei, c->dma_ch);
- c->plat->dma_write(0, cxfi, c->dma_ch);
- c->plat->dma_write(sg->en, CEN, c->dma_ch);
- c->plat->dma_write(sg->fn, CFN, c->dma_ch);
+ omap_dma_chan_write(c, cxsa, sg->addr);
+ omap_dma_chan_write(c, cxei, 0);
+ omap_dma_chan_write(c, cxfi, 0);
+ omap_dma_chan_write(c, CEN, sg->en);
+ omap_dma_chan_write(c, CFN, sg->fn);
omap_dma_start(c, d);
}
@@ -305,9 +325,9 @@ static void omap_dma_start_desc(struct omap_chan *c)
*/
mb();
- c->plat->dma_write(d->ccr, CCR, c->dma_ch);
+ omap_dma_chan_write(c, CCR, d->ccr);
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) {
cxsa = CSSA;
@@ -319,11 +339,11 @@ static void omap_dma_start_desc(struct omap_chan *c)
cxfi = CDFI;
}
- c->plat->dma_write(d->dev_addr, cxsa, c->dma_ch);
- c->plat->dma_write(0, cxei, c->dma_ch);
- c->plat->dma_write(d->fi, cxfi, c->dma_ch);
- c->plat->dma_write(d->csdp, CSDP, c->dma_ch);
- c->plat->dma_write(d->clnk_ctrl, CLNK_CTRL, c->dma_ch);
+ omap_dma_chan_write(c, cxsa, d->dev_addr);
+ omap_dma_chan_write(c, cxei, 0);
+ omap_dma_chan_write(c, cxfi, d->fi);
+ omap_dma_chan_write(c, CSDP, d->csdp);
+ omap_dma_chan_write(c, CLNK_CTRL, d->clnk_ctrl);
omap_dma_start_sg(c, d, 0);
}
@@ -437,12 +457,12 @@ static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
dma_addr_t addr;
if (__dma_omap15xx(od->plat->dma_attr))
- addr = c->plat->dma_read(CPC, c->dma_ch);
+ addr = omap_dma_chan_read(c, CPC);
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)
- addr = c->plat->dma_read(CSAC, c->dma_ch);
+ addr = omap_dma_chan_read(c, CSAC);
if (!__dma_omap15xx(od->plat->dma_attr)) {
/*
@@ -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).
* Return the programmed source start address in this case.
*/
- if (c->plat->dma_read(CDAC, c->dma_ch))
- addr = c->plat->dma_read(CSAC, c->dma_ch);
+ if (omap_dma_chan_read(c, CDAC))
+ addr = omap_dma_chan_read(c, CSAC);
else
- addr = c->plat->dma_read(CSSA, c->dma_ch);
+ addr = omap_dma_chan_read(c, CSSA);
}
if (dma_omap1())
- addr |= c->plat->dma_read(CSSA, c->dma_ch) & 0xffff0000;
+ addr |= omap_dma_chan_read(c, CSSA) & 0xffff0000;
return addr;
}
@@ -468,27 +488,27 @@ static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c)
dma_addr_t addr;
if (__dma_omap15xx(od->plat->dma_attr))
- addr = c->plat->dma_read(CPC, c->dma_ch);
+ addr = omap_dma_chan_read(c, CPC);
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
* read before the DMA controller finished disabling the channel.
*/
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
* not been started (no data has been transferred so far).
* Return the programmed destination start address in this case.
*/
if (addr == 0)
- addr = c->plat->dma_read(CDSA, c->dma_ch);
+ addr = omap_dma_chan_read(c, CDSA);
}
if (dma_omap1())
- addr |= c->plat->dma_read(CDSA, c->dma_ch) & 0xffff0000;
+ addr |= omap_dma_chan_read(c, CDSA) & 0xffff0000;
return addr;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 17/26] dmaengine: omap-dma: cleanup errata 3.3 handling
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (15 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 16/26] dmaengine: omap-dma: provide register read/write functions Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 18/26] ARM: omap: remove references to disable_irq_lch Russell King
` (11 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 52 ++++++++++++++++++++++++++++----------------------
1 file changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index a1baada7dcd4..1e0018f36384 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -451,28 +451,39 @@ static size_t omap_dma_desc_size_pos(struct omap_desc *d, dma_addr_t addr)
return size;
}
+/*
+ * OMAP 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+static uint32_t omap_dma_chan_read_3_3(struct omap_chan *c, unsigned reg)
+{
+ struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+ uint32_t val;
+
+ val = omap_dma_chan_read(c, reg);
+ if (val == 0 && od->plat->errata & DMA_ERRATA_3_3)
+ val = omap_dma_chan_read(c, reg);
+
+ return val;
+}
+
static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
{
struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
- dma_addr_t addr;
+ dma_addr_t addr, cdac;
- if (__dma_omap15xx(od->plat->dma_attr))
+ if (__dma_omap15xx(od->plat->dma_attr)) {
addr = omap_dma_chan_read(c, CPC);
- else
- addr = omap_dma_chan_read(c, CSAC);
-
- if (od->plat->errata & DMA_ERRATA_3_3 && addr == 0)
- addr = omap_dma_chan_read(c, CSAC);
+ } else {
+ addr = omap_dma_chan_read_3_3(c, CSAC);
+ cdac = omap_dma_chan_read_3_3(c, CDAC);
- if (!__dma_omap15xx(od->plat->dma_attr)) {
/*
* CDAC == 0 indicates that the DMA transfer on the channel has
* not been started (no data has been transferred so far).
* Return the programmed source start address in this case.
*/
- if (omap_dma_chan_read(c, CDAC))
- addr = omap_dma_chan_read(c, CSAC);
- else
+ if (cdac == 0)
addr = omap_dma_chan_read(c, CSSA);
}
@@ -487,21 +498,16 @@ static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c)
struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
dma_addr_t addr;
- if (__dma_omap15xx(od->plat->dma_attr))
+ if (__dma_omap15xx(od->plat->dma_attr)) {
addr = omap_dma_chan_read(c, CPC);
- else
- addr = omap_dma_chan_read(c, CDAC);
+ } else {
+ addr = omap_dma_chan_read_3_3(c, CDAC);
- /*
- * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
- * read before the DMA controller finished disabling the channel.
- */
- if (!__dma_omap15xx(od->plat->dma_attr) && addr == 0) {
- addr = omap_dma_chan_read(c, CDAC);
/*
- * CDAC == 0 indicates that the DMA transfer on the channel has
- * not been started (no data has been transferred so far).
- * Return the programmed destination start address in this case.
+ * CDAC == 0 indicates that the DMA transfer on the channel
+ * has not been started (no data has been transferred so
+ * far). Return the programmed destination start address in
+ * this case.
*/
if (addr == 0)
addr = omap_dma_chan_read(c, CDSA);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 18/26] ARM: omap: remove references to disable_irq_lch
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (16 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 17/26] dmaengine: omap-dma: cleanup errata 3.3 handling Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 19/26] ARM: omap: remove almost-const variables Russell King
` (10 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
The disable_irq_lch method is never actually used, so there's not much
point it existing; remove it.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 1 -
arch/arm/mach-omap2/dma.c | 10 ----------
include/linux/omap-dma.h | 1 -
3 files changed, 12 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index 5bb8ce86d54b..d292055d3117 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -363,7 +363,6 @@ static int __init omap1_system_dma_init(void)
p->clear_dma = omap1_clear_dma;
p->dma_write = dma_write;
p->dma_read = dma_read;
- p->disable_irq_lch = NULL;
p->errata = configure_dma_errata();
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 49fd0d501c9b..81c2d3383bc5 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -112,15 +112,6 @@ static inline u32 dma_read(int reg, int lch)
return val;
}
-static inline void omap2_disable_irq_lch(int lch)
-{
- u32 val;
-
- val = dma_read(IRQENABLE_L0, lch);
- val &= ~(1 << lch);
- dma_write(val, IRQENABLE_L0, lch);
-}
-
static void omap2_clear_dma(int lch)
{
int i = dma_common_ch_start;
@@ -239,7 +230,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
}
p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
- p->disable_irq_lch = omap2_disable_irq_lch;
p->show_dma_caps = omap2_show_dma_caps;
p->clear_dma = omap2_clear_dma;
p->dma_write = dma_write;
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index d631658e2237..0bb7de77d478 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -275,7 +275,6 @@ struct omap_dma_dev_attr {
struct omap_system_dma_plat_info {
struct omap_dma_dev_attr *dma_attr;
u32 errata;
- void (*disable_irq_lch)(int lch);
void (*show_dma_caps)(void);
void (*clear_lch_regs)(int lch);
void (*clear_dma)(int lch);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 19/26] ARM: omap: remove almost-const variables
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (17 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 18/26] ARM: omap: remove references to disable_irq_lch Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 20/26] ARM: omap: clean up DMA register accesses Russell King
` (9 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
dma_stride and dma_common_ch_start are only ever initialised to one
known value at initialisation, and are private to each of these files.
There's no point these being variables at all.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 14 ++++----------
arch/arm/mach-omap2/dma.c | 14 +++++---------
2 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index d292055d3117..11f0b0ee67a3 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -36,8 +36,6 @@
static u32 errata;
static u32 enable_1510_mode;
-static u8 dma_stride;
-static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
static u16 reg_map[] = {
[GCR] = 0x400,
@@ -184,7 +182,7 @@ static inline void dma_write(u32 val, int reg, int lch)
u8 stride;
u32 offset;
- stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ stride = (reg >= CPC) ? OMAP1_DMA_STRIDE : 0;
offset = reg_map[reg] + (stride * lch);
__raw_writew(val, dma_base + offset);
@@ -200,7 +198,7 @@ static inline u32 dma_read(int reg, int lch)
u8 stride;
u32 offset, val;
- stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ stride = (reg >= CPC) ? OMAP1_DMA_STRIDE : 0;
offset = reg_map[reg] + (stride * lch);
val = __raw_readw(dma_base + offset);
@@ -216,9 +214,9 @@ static inline u32 dma_read(int reg, int lch)
static void omap1_clear_lch_regs(int lch)
{
- int i = dma_common_ch_start;
+ int i;
- for (; i <= dma_common_ch_end; i += 1)
+ for (i = CPC; i <= COLOR; i += 1)
dma_write(0, i, lch);
}
@@ -380,10 +378,6 @@ static int __init omap1_system_dma_init(void)
goto exit_release_chan;
}
- dma_stride = OMAP1_DMA_STRIDE;
- dma_common_ch_start = CPC;
- dma_common_ch_end = COLOR;
-
dma_pdev = platform_device_register_full(&omap_dma_dev_info);
if (IS_ERR(dma_pdev)) {
ret = PTR_ERR(dma_pdev);
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 81c2d3383bc5..e4ac7ac9a228 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -38,11 +38,10 @@
#define OMAP2_DMA_STRIDE 0x60
static u32 errata;
-static u8 dma_stride;
static struct omap_dma_dev_attr *d;
-static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
+static enum omap_reg_offsets dma_common_ch_end;
static u16 reg_map[] = {
[REVISION] = 0x00,
@@ -96,7 +95,7 @@ static inline void dma_write(u32 val, int reg, int lch)
u8 stride;
u32 offset;
- stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ stride = (reg >= CSDP) ? OMAP2_DMA_STRIDE : 0;
offset = reg_map[reg] + (stride * lch);
__raw_writel(val, dma_base + offset);
}
@@ -106,7 +105,7 @@ static inline u32 dma_read(int reg, int lch)
u8 stride;
u32 offset, val;
- stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ stride = (reg >= CSDP) ? OMAP2_DMA_STRIDE : 0;
offset = reg_map[reg] + (stride * lch);
val = __raw_readl(dma_base + offset);
return val;
@@ -114,9 +113,9 @@ static inline u32 dma_read(int reg, int lch)
static void omap2_clear_dma(int lch)
{
- int i = dma_common_ch_start;
+ int i;
- for (; i <= dma_common_ch_end; i += 1)
+ for (i = CSDP; i <= dma_common_ch_end; i += 1)
dma_write(0, i, lch);
}
@@ -219,9 +218,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
struct resource *mem;
char *name = "omap_dma_system";
- dma_stride = OMAP2_DMA_STRIDE;
- dma_common_ch_start = CSDP;
-
p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
if (!p) {
pr_err("%s: Unable to allocate pdata for %s:%s\n",
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 20/26] ARM: omap: clean up DMA register accesses
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (18 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 19/26] ARM: omap: remove almost-const variables Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 21/26] ARM: omap: dma: get rid of errata global Russell King
` (8 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
We can do much better with this by using a structure to describe each
register, rather than code.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 117 +++++++++++++++++++++-------------------------
arch/arm/mach-omap2/dma.c | 99 +++++++++++++++++++--------------------
include/linux/omap-dma.h | 13 ++++++
3 files changed, 115 insertions(+), 114 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index 11f0b0ee67a3..b680db7a35d4 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -32,53 +32,52 @@
#define OMAP1_DMA_BASE (0xfffed800)
#define OMAP1_LOGICAL_DMA_CH_COUNT 17
-#define OMAP1_DMA_STRIDE 0x40
static u32 errata;
static u32 enable_1510_mode;
-static u16 reg_map[] = {
- [GCR] = 0x400,
- [GSCR] = 0x404,
- [GRST1] = 0x408,
- [HW_ID] = 0x442,
- [PCH2_ID] = 0x444,
- [PCH0_ID] = 0x446,
- [PCH1_ID] = 0x448,
- [PCHG_ID] = 0x44a,
- [PCHD_ID] = 0x44c,
- [CAPS_0] = 0x44e,
- [CAPS_1] = 0x452,
- [CAPS_2] = 0x456,
- [CAPS_3] = 0x458,
- [CAPS_4] = 0x45a,
- [PCH2_SR] = 0x460,
- [PCH0_SR] = 0x480,
- [PCH1_SR] = 0x482,
- [PCHD_SR] = 0x4c0,
+static const struct omap_dma_reg reg_map[] = {
+ [GCR] = { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
+ [GSCR] = { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
+ [GRST1] = { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
+ [HW_ID] = { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH2_ID] = { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH0_ID] = { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH1_ID] = { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
+ [PCHG_ID] = { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
+ [PCHD_ID] = { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
+ [CAPS_0] = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
+ [CAPS_1] = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
+ [CAPS_2] = { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
+ [CAPS_3] = { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
+ [CAPS_4] = { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH2_SR] = { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH0_SR] = { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
+ [PCH1_SR] = { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
+ [PCHD_SR] = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },
/* Common Registers */
- [CSDP] = 0x00,
- [CCR] = 0x02,
- [CICR] = 0x04,
- [CSR] = 0x06,
- [CEN] = 0x10,
- [CFN] = 0x12,
- [CSFI] = 0x14,
- [CSEI] = 0x16,
- [CPC] = 0x18, /* 15xx only */
- [CSAC] = 0x18,
- [CDAC] = 0x1a,
- [CDEI] = 0x1c,
- [CDFI] = 0x1e,
- [CLNK_CTRL] = 0x28,
+ [CSDP] = { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
+ [CCR] = { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
+ [CICR] = { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
+ [CSR] = { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
+ [CEN] = { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
+ [CFN] = { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
+ [CSFI] = { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
+ [CSEI] = { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
+ [CPC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */
+ [CSAC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
+ [CDAC] = { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
+ [CDEI] = { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
+ [CDFI] = { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
+ [CLNK_CTRL] = { 0x0028, 0x40, OMAP_DMA_REG_16BIT },
/* Channel specific register offsets */
- [CSSA] = 0x08,
- [CDSA] = 0x0c,
- [COLOR] = 0x20,
- [CCR2] = 0x24,
- [LCH_CTRL] = 0x2a,
+ [CSSA] = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
+ [CDSA] = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
+ [COLOR] = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
+ [CCR2] = { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
+ [LCH_CTRL] = { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
};
static struct resource res[] __initdata = {
@@ -179,36 +178,28 @@ static struct resource res[] __initdata = {
static void __iomem *dma_base;
static inline void dma_write(u32 val, int reg, int lch)
{
- u8 stride;
- u32 offset;
+ void __iomem *addr = dma_base;
- stride = (reg >= CPC) ? OMAP1_DMA_STRIDE : 0;
- offset = reg_map[reg] + (stride * lch);
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
- __raw_writew(val, dma_base + offset);
- if ((reg > CLNK_CTRL && reg < CCEN) ||
- (reg > PCHD_ID && reg < CAPS_2)) {
- u32 offset2 = reg_map[reg] + 2 + (stride * lch);
- __raw_writew(val >> 16, dma_base + offset2);
- }
+ __raw_writew(val, addr);
+ if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
+ __raw_writew(val >> 16, addr + 2);
}
static inline u32 dma_read(int reg, int lch)
{
- u8 stride;
- u32 offset, val;
-
- stride = (reg >= CPC) ? OMAP1_DMA_STRIDE : 0;
- offset = reg_map[reg] + (stride * lch);
-
- val = __raw_readw(dma_base + offset);
- if ((reg > CLNK_CTRL && reg < CCEN) ||
- (reg > PCHD_ID && reg < CAPS_2)) {
- u16 upper;
- u32 offset2 = reg_map[reg] + 2 + (stride * lch);
- upper = __raw_readw(dma_base + offset2);
- val |= (upper << 16);
- }
+ void __iomem *addr = dma_base;
+ uint32_t val;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
+
+ val = __raw_readw(addr);
+ if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
+ val |= __raw_readw(addr + 2) << 16;
+
return val;
}
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index e4ac7ac9a228..e633b48a3fcb 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -35,80 +35,77 @@
#include "omap_hwmod.h"
#include "omap_device.h"
-#define OMAP2_DMA_STRIDE 0x60
-
static u32 errata;
static struct omap_dma_dev_attr *d;
static enum omap_reg_offsets dma_common_ch_end;
-static u16 reg_map[] = {
- [REVISION] = 0x00,
- [GCR] = 0x78,
- [IRQSTATUS_L0] = 0x08,
- [IRQSTATUS_L1] = 0x0c,
- [IRQSTATUS_L2] = 0x10,
- [IRQSTATUS_L3] = 0x14,
- [IRQENABLE_L0] = 0x18,
- [IRQENABLE_L1] = 0x1c,
- [IRQENABLE_L2] = 0x20,
- [IRQENABLE_L3] = 0x24,
- [SYSSTATUS] = 0x28,
- [OCP_SYSCONFIG] = 0x2c,
- [CAPS_0] = 0x64,
- [CAPS_2] = 0x6c,
- [CAPS_3] = 0x70,
- [CAPS_4] = 0x74,
+static const struct omap_dma_reg reg_map[] = {
+ [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
+ [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
+ [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
+ [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
+ [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
+ [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
/* Common register offsets */
- [CCR] = 0x80,
- [CLNK_CTRL] = 0x84,
- [CICR] = 0x88,
- [CSR] = 0x8c,
- [CSDP] = 0x90,
- [CEN] = 0x94,
- [CFN] = 0x98,
- [CSEI] = 0xa4,
- [CSFI] = 0xa8,
- [CDEI] = 0xac,
- [CDFI] = 0xb0,
- [CSAC] = 0xb4,
- [CDAC] = 0xb8,
+ [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
+ [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
+ [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
+ [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
+ [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
+ [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
+ [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
+ [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
+ [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
+ [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
+ [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
+ [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
+ [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
/* Channel specific register offsets */
- [CSSA] = 0x9c,
- [CDSA] = 0xa0,
- [CCEN] = 0xbc,
- [CCFN] = 0xc0,
- [COLOR] = 0xc4,
+ [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
+ [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
+ [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
+ [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
+ [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
/* OMAP4 specific registers */
- [CDP] = 0xd0,
- [CNDP] = 0xd4,
- [CCDN] = 0xd8,
+ [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
+ [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
+ [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
};
static void __iomem *dma_base;
static inline void dma_write(u32 val, int reg, int lch)
{
- u8 stride;
- u32 offset;
+ void __iomem *addr = dma_base;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
- stride = (reg >= CSDP) ? OMAP2_DMA_STRIDE : 0;
- offset = reg_map[reg] + (stride * lch);
- __raw_writel(val, dma_base + offset);
+ __raw_writel(val, addr);
}
static inline u32 dma_read(int reg, int lch)
{
- u8 stride;
- u32 offset, val;
+ void __iomem *addr = dma_base;
+
+ addr += reg_map[reg].offset;
+ addr += reg_map[reg].stride * lch;
- stride = (reg >= CSDP) ? OMAP2_DMA_STRIDE : 0;
- offset = reg_map[reg] + (stride * lch);
- val = __raw_readl(dma_base + offset);
- return val;
+ return __raw_readl(addr);
}
static void omap2_clear_dma(int lch)
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 0bb7de77d478..41328725721a 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -271,6 +271,19 @@ struct omap_dma_dev_attr {
struct omap_dma_lch *chan;
};
+enum {
+ OMAP_DMA_REG_NONE,
+ OMAP_DMA_REG_16BIT,
+ OMAP_DMA_REG_2X16BIT,
+ OMAP_DMA_REG_32BIT,
+};
+
+struct omap_dma_reg {
+ u16 offset;
+ u8 stride;
+ u8 type;
+};
+
/* System DMA platform data structure */
struct omap_system_dma_plat_info {
struct omap_dma_dev_attr *dma_attr;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 21/26] ARM: omap: dma: get rid of errata global
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (19 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 20/26] ARM: omap: clean up DMA register accesses Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 22/26] ARM: omap: move dma channel allocation into plat-omap code Russell King
` (7 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
There's no need for this to be a global variable; move it into the
errata configuration function instead.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 4 ++--
arch/arm/mach-omap2/dma.c | 5 ++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index b680db7a35d4..c979e3f88bbb 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -33,7 +33,6 @@
#define OMAP1_DMA_BASE (0xfffed800)
#define OMAP1_LOGICAL_DMA_CH_COUNT 17
-static u32 errata;
static u32 enable_1510_mode;
static const struct omap_dma_reg reg_map[] = {
@@ -244,8 +243,9 @@ static void omap1_show_dma_caps(void)
return;
}
-static u32 configure_dma_errata(void)
+static unsigned configure_dma_errata(void)
{
+ unsigned errata = 0;
/*
* Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index e633b48a3fcb..244ff5012aed 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -35,8 +35,6 @@
#include "omap_hwmod.h"
#include "omap_device.h"
-static u32 errata;
-
static struct omap_dma_dev_attr *d;
static enum omap_reg_offsets dma_common_ch_end;
@@ -124,8 +122,9 @@ static void omap2_show_dma_caps(void)
return;
}
-static u32 configure_dma_errata(void)
+static unsigned configure_dma_errata(void)
{
+ unsigned errata = 0;
/*
* Errata applicable for OMAP2430ES1.0 and all omap2420
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 22/26] ARM: omap: move dma channel allocation into plat-omap code
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (20 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 21/26] ARM: omap: dma: get rid of errata global Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 23/26] ARM: omap: dma: get rid of 'p' allocation and clean up Russell King
` (6 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
This really needs to be there, because otherwise the plat-omap code can
kfree() this data structure, and then re-use the pointer later.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 17 ++---------------
arch/arm/mach-omap2/dma.c | 7 -------
arch/arm/plat-omap/dma.c | 11 ++++++++---
include/linux/omap-dma.h | 1 -
4 files changed, 10 insertions(+), 26 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index c979e3f88bbb..d170f7d0a6ac 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -325,17 +325,6 @@ static int __init omap1_system_dma_init(void)
d->dev_caps |= CLEAR_CSR_ON_READ;
d->dev_caps |= IS_WORD_16;
-
- d->chan = kzalloc(sizeof(struct omap_dma_lch) *
- (d->lch_count), GFP_KERNEL);
- if (!d->chan) {
- dev_err(&pdev->dev,
- "%s: Memory allocation failed for d->chan!\n",
- __func__);
- ret = -ENOMEM;
- goto exit_release_d;
- }
-
if (cpu_is_omap15xx())
d->chan_count = 9;
else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
@@ -359,14 +348,14 @@ static int __init omap1_system_dma_init(void)
if (ret) {
dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
__func__, pdev->name, pdev->id);
- goto exit_release_chan;
+ goto exit_release_d;
}
ret = platform_device_add(pdev);
if (ret) {
dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
__func__, pdev->name, pdev->id);
- goto exit_release_chan;
+ goto exit_release_d;
}
dma_pdev = platform_device_register_full(&omap_dma_dev_info);
@@ -379,8 +368,6 @@ static int __init omap1_system_dma_init(void)
exit_release_pdev:
platform_device_del(pdev);
-exit_release_chan:
- kfree(d->chan);
exit_release_d:
kfree(d);
exit_release_p:
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 244ff5012aed..9f210d637354 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -251,13 +251,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
}
d = oh->dev_attr;
- d->chan = kzalloc(sizeof(struct omap_dma_lch) *
- (d->lch_count), GFP_KERNEL);
-
- if (!d->chan) {
- dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
- return -ENOMEM;
- }
if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
d->dev_caps |= HS_CHANNELS_RESERVED;
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index d4d9a5e62152..5f5b975887fc 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2030,9 +2030,16 @@ static int omap_system_dma_probe(struct platform_device *pdev)
dma_lch_count = d->lch_count;
dma_chan_count = dma_lch_count;
- dma_chan = d->chan;
enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+ dma_chan = devm_kcalloc(&pdev->dev, dma_lch_count,
+ sizeof(struct omap_dma_lch), GFP_KERNEL);
+ if (!dma_chan) {
+ dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
+ return -ENOMEM;
+ }
+
+
if (dma_omap2plus()) {
dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
dma_lch_count, GFP_KERNEL);
@@ -2117,7 +2124,6 @@ static int omap_system_dma_probe(struct platform_device *pdev)
}
exit_dma_lch_fail:
- kfree(dma_chan);
return ret;
}
@@ -2137,7 +2143,6 @@ static int omap_system_dma_remove(struct platform_device *pdev)
free_irq(dma_irq, (void *)(irq_rel + 1));
}
}
- kfree(dma_chan);
return 0;
}
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 41328725721a..7813636a193d 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -268,7 +268,6 @@ struct omap_dma_dev_attr {
u32 dev_caps;
u16 lch_count;
u16 chan_count;
- struct omap_dma_lch *chan;
};
enum {
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 23/26] ARM: omap: dma: get rid of 'p' allocation and clean up
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (21 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 22/26] ARM: omap: move dma channel allocation into plat-omap code Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:57 ` [PATCH 24/26] dmaengine: omap-dma: move register read/writes into omap-dma.c Russell King
` (5 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
The omap_system_dma_plat_info structure is only seven words, it's not
worth the expense of kmalloc()'ing backing store for this only to
release it later. Note that platform_device_add_data() copies the
data anyway. Clean up the initialisation of this structure - we don't
even need code to initialise most of this structure.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 36 ++++++++++++++----------------------
arch/arm/mach-omap2/dma.c | 34 +++++++++++++---------------------
2 files changed, 27 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index d170f7d0a6ac..a8c83ccc36fb 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -263,9 +263,17 @@ static const struct platform_device_info omap_dma_dev_info = {
.dma_mask = DMA_BIT_MASK(32),
};
+static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+ .show_dma_caps = omap1_show_dma_caps,
+ .clear_lch_regs = omap1_clear_lch_regs,
+ .clear_dma = omap1_clear_dma,
+ .dma_write = dma_write,
+ .dma_read = dma_read,
+};
+
static int __init omap1_system_dma_init(void)
{
- struct omap_system_dma_plat_info *p;
+ struct omap_system_dma_plat_info p;
struct omap_dma_dev_attr *d;
struct platform_device *pdev, *dma_pdev;
int ret;
@@ -291,20 +299,12 @@ static int __init omap1_system_dma_init(void)
goto exit_iounmap;
}
- p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
- if (!p) {
- dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
- __func__, pdev->name);
- ret = -ENOMEM;
- goto exit_iounmap;
- }
-
d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
if (!d) {
dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
__func__, pdev->name);
ret = -ENOMEM;
- goto exit_release_p;
+ goto exit_iounmap;
}
d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
@@ -334,17 +334,11 @@ static int __init omap1_system_dma_init(void)
d->chan_count = 9;
}
- p->dma_attr = d;
-
- p->show_dma_caps = omap1_show_dma_caps;
- p->clear_lch_regs = omap1_clear_lch_regs;
- p->clear_dma = omap1_clear_dma;
- p->dma_write = dma_write;
- p->dma_read = dma_read;
-
- p->errata = configure_dma_errata();
+ p = dma_plat_info;
+ p.dma_attr = d;
+ p.errata = configure_dma_errata();
- ret = platform_device_add_data(pdev, p, sizeof(*p));
+ ret = platform_device_add_data(pdev, &p, sizeof(p));
if (ret) {
dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
__func__, pdev->name, pdev->id);
@@ -370,8 +364,6 @@ static int __init omap1_system_dma_init(void)
platform_device_del(pdev);
exit_release_d:
kfree(d);
-exit_release_p:
- kfree(p);
exit_iounmap:
iounmap(dma_base);
exit_device_put:
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 9f210d637354..6331fc4b4054 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -35,8 +35,6 @@
#include "omap_hwmod.h"
#include "omap_device.h"
-static struct omap_dma_dev_attr *d;
-
static enum omap_reg_offsets dma_common_ch_end;
static const struct omap_dma_reg reg_map[] = {
@@ -206,33 +204,27 @@ static unsigned configure_dma_errata(void)
return errata;
}
+static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+ .show_dma_caps = omap2_show_dma_caps,
+ .clear_dma = omap2_clear_dma,
+ .dma_write = dma_write,
+ .dma_read = dma_read,
+};
+
/* One time initializations */
static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
{
struct platform_device *pdev;
- struct omap_system_dma_plat_info *p;
+ struct omap_system_dma_plat_info p;
+ struct omap_dma_dev_attr *d;
struct resource *mem;
char *name = "omap_dma_system";
- p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
- if (!p) {
- pr_err("%s: Unable to allocate pdata for %s:%s\n",
- __func__, name, oh->name);
- return -ENOMEM;
- }
-
- p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
- p->show_dma_caps = omap2_show_dma_caps;
- p->clear_dma = omap2_clear_dma;
- p->dma_write = dma_write;
- p->dma_read = dma_read;
-
- p->clear_lch_regs = NULL;
-
- p->errata = configure_dma_errata();
+ p = dma_plat_info;
+ p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+ p.errata = configure_dma_errata();
- pdev = omap_device_build(name, 0, oh, p, sizeof(*p));
- kfree(p);
+ pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
if (IS_ERR(pdev)) {
pr_err("%s: Can't build omap_device for %s:%s.\n",
__func__, name, oh->name);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 24/26] dmaengine: omap-dma: move register read/writes into omap-dma.c
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (22 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 23/26] ARM: omap: dma: get rid of 'p' allocation and clean up Russell King
@ 2014-02-10 15:57 ` Russell King
2014-02-10 15:58 ` [PATCH 25/26] dmaengine: omap-dma: move IRQ handling to omap-dma Russell King
` (4 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:57 UTC (permalink / raw)
To: linux-arm-kernel
Export the DMA register information from the SoC specific data, such
that we can access the registers directly in omap-dma.c, mapping the
register region ourselves as well.
Rather than calculating the DMA channel register in its entirety for
each access, we pre-calculate an offset base address for the allocated
DMA channel and then just use the appropriate register offset.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-omap1/dma.c | 4 ++
arch/arm/mach-omap2/dma.c | 18 ++++++---
drivers/dma/omap-dma.c | 96 ++++++++++++++++++++++++++++++++++++++++++-----
include/linux/omap-dma.h | 2 +
4 files changed, 105 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index a8c83ccc36fb..4be601b638d7 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -261,9 +261,13 @@ static const struct platform_device_info omap_dma_dev_info = {
.name = "omap-dma-engine",
.id = -1,
.dma_mask = DMA_BIT_MASK(32),
+ .res = res,
+ .num_res = 1,
};
static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+ .reg_map = reg_map,
+ .channel_stride = 0x40,
.show_dma_caps = omap1_show_dma_caps,
.clear_lch_regs = omap1_clear_lch_regs,
.clear_dma = omap1_clear_dma,
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 6331fc4b4054..5689c88d986d 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -205,12 +205,20 @@ static unsigned configure_dma_errata(void)
}
static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+ .reg_map = reg_map,
+ .channel_stride = 0x60,
.show_dma_caps = omap2_show_dma_caps,
.clear_dma = omap2_clear_dma,
.dma_write = dma_write,
.dma_read = dma_read,
};
+static struct platform_device_info omap_dma_dev_info = {
+ .name = "omap-dma-engine",
+ .id = -1,
+ .dma_mask = DMA_BIT_MASK(32),
+};
+
/* One time initializations */
static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
{
@@ -231,11 +239,15 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
return PTR_ERR(pdev);
}
+ omap_dma_dev_info.res = pdev->resource;
+ omap_dma_dev_info.num_res = pdev->num_resources;
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
return -EINVAL;
}
+
dma_base = ioremap(mem->start, resource_size(mem));
if (!dma_base) {
dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
@@ -256,12 +268,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
return 0;
}
-static const struct platform_device_info omap_dma_dev_info = {
- .name = "omap-dma-engine",
- .id = -1,
- .dma_mask = DMA_BIT_MASK(32),
-};
-
static int __init omap2_system_dma_init(void)
{
struct platform_device *pdev;
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 1e0018f36384..00f8e566cf12 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -27,13 +27,16 @@ struct omap_dmadev {
spinlock_t lock;
struct tasklet_struct task;
struct list_head pending;
+ void __iomem *base;
+ const struct omap_dma_reg *reg_map;
struct omap_system_dma_plat_info *plat;
};
struct omap_chan {
struct virt_dma_chan vc;
struct list_head node;
- struct omap_system_dma_plat_info *plat;
+ void __iomem *channel_base;
+ const struct omap_dma_reg *reg_map;
struct dma_slave_config cfg;
unsigned dma_sig;
@@ -170,24 +173,77 @@ static void omap_dma_desc_free(struct virt_dma_desc *vd)
kfree(container_of(vd, struct omap_desc, vd));
}
+static void omap_dma_write(uint32_t val, unsigned type, void __iomem *addr)
+{
+ switch (type) {
+ case OMAP_DMA_REG_16BIT:
+ writew_relaxed(val, addr);
+ break;
+ case OMAP_DMA_REG_2X16BIT:
+ writew_relaxed(val, addr);
+ writew_relaxed(val >> 16, addr + 2);
+ break;
+ case OMAP_DMA_REG_32BIT:
+ writel_relaxed(val, addr);
+ break;
+ default:
+ WARN_ON(1);
+ }
+}
+
+static unsigned omap_dma_read(unsigned type, void __iomem *addr)
+{
+ unsigned val;
+
+ switch (type) {
+ case OMAP_DMA_REG_16BIT:
+ val = readw_relaxed(addr);
+ break;
+ case OMAP_DMA_REG_2X16BIT:
+ val = readw_relaxed(addr);
+ val |= readw_relaxed(addr + 2) << 16;
+ break;
+ case OMAP_DMA_REG_32BIT:
+ val = readl_relaxed(addr);
+ break;
+ default:
+ WARN_ON(1);
+ val = 0;
+ }
+
+ return val;
+}
+
static void omap_dma_glbl_write(struct omap_dmadev *od, unsigned reg, unsigned val)
{
- od->plat->dma_write(val, reg, 0);
+ const struct omap_dma_reg *r = od->reg_map + reg;
+
+ WARN_ON(r->stride);
+
+ omap_dma_write(val, r->type, od->base + r->offset);
}
static unsigned omap_dma_glbl_read(struct omap_dmadev *od, unsigned reg)
{
- return od->plat->dma_read(reg, 0);
+ const struct omap_dma_reg *r = od->reg_map + reg;
+
+ WARN_ON(r->stride);
+
+ return omap_dma_read(r->type, od->base + r->offset);
}
static void omap_dma_chan_write(struct omap_chan *c, unsigned reg, unsigned val)
{
- c->plat->dma_write(val, reg, c->dma_ch);
+ const struct omap_dma_reg *r = c->reg_map + reg;
+
+ omap_dma_write(val, r->type, c->channel_base + r->offset);
}
static unsigned omap_dma_chan_read(struct omap_chan *c, unsigned reg)
{
- return c->plat->dma_read(reg, c->dma_ch);
+ const struct omap_dma_reg *r = c->reg_map + reg;
+
+ return omap_dma_read(r->type, c->channel_base + r->offset);
}
static void omap_dma_clear_csr(struct omap_chan *c)
@@ -198,6 +254,12 @@ static void omap_dma_clear_csr(struct omap_chan *c)
omap_dma_chan_write(c, CSR, ~0);
}
+static void omap_dma_assign(struct omap_dmadev *od, struct omap_chan *c,
+ unsigned lch)
+{
+ c->channel_base = od->base + od->plat->channel_stride * lch;
+}
+
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);
@@ -400,18 +462,26 @@ static void omap_dma_sched(unsigned long data)
static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
{
+ struct omap_dmadev *od = to_omap_dma_dev(chan->device);
struct omap_chan *c = to_omap_dma_chan(chan);
+ int ret;
+
+ dev_dbg(od->ddev.dev, "allocating channel for %u\n", c->dma_sig);
- dev_dbg(c->vc.chan.device->dev, "allocating channel for %u\n", c->dma_sig);
+ ret = omap_request_dma(c->dma_sig, "DMA engine", omap_dma_callback,
+ c, &c->dma_ch);
- return omap_request_dma(c->dma_sig, "DMA engine",
- omap_dma_callback, c, &c->dma_ch);
+ if (ret >= 0)
+ omap_dma_assign(od, c, c->dma_ch);
+
+ return ret;
}
static void omap_dma_free_chan_resources(struct dma_chan *chan)
{
struct omap_chan *c = to_omap_dma_chan(chan);
+ c->channel_base = NULL;
vchan_free_chan_resources(&c->vc);
omap_free_dma(c->dma_ch);
@@ -917,7 +987,7 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
if (!c)
return -ENOMEM;
- c->plat = od->plat;
+ c->reg_map = od->reg_map;
c->dma_sig = dma_sig;
c->vc.desc_free = omap_dma_desc_free;
vchan_init(&c->vc, &od->ddev);
@@ -944,16 +1014,24 @@ static void omap_dma_free(struct omap_dmadev *od)
static int omap_dma_probe(struct platform_device *pdev)
{
struct omap_dmadev *od;
+ struct resource *res;
int rc, i;
od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
if (!od)
return -ENOMEM;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ od->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(od->base))
+ return PTR_ERR(od->base);
+
od->plat = omap_get_plat_info();
if (!od->plat)
return -EPROBE_DEFER;
+ od->reg_map = od->plat->reg_map;
+
dma_cap_set(DMA_SLAVE, od->ddev.cap_mask);
dma_cap_set(DMA_CYCLIC, od->ddev.cap_mask);
od->ddev.device_alloc_chan_resources = omap_dma_alloc_chan_resources;
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 7813636a193d..41a13e70f41f 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -285,6 +285,8 @@ struct omap_dma_reg {
/* System DMA platform data structure */
struct omap_system_dma_plat_info {
+ const struct omap_dma_reg *reg_map;
+ unsigned channel_stride;
struct omap_dma_dev_attr *dma_attr;
u32 errata;
void (*show_dma_caps)(void);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 25/26] dmaengine: omap-dma: move IRQ handling to omap-dma
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (23 preceding siblings ...)
2014-02-10 15:57 ` [PATCH 24/26] dmaengine: omap-dma: move register read/writes into omap-dma.c Russell King
@ 2014-02-10 15:58 ` Russell King
2014-02-10 15:58 ` [PATCH 26/26] dmaengine: omap-dma: more consolidation of CCR register setup Russell King
` (3 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:58 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 115 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 00f8e566cf12..ec98e718de70 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -30,6 +30,10 @@ struct omap_dmadev {
void __iomem *base;
const struct omap_dma_reg *reg_map;
struct omap_system_dma_plat_info *plat;
+ bool legacy;
+ spinlock_t irq_lock;
+ uint32_t irq_enable_mask;
+ struct omap_chan *lch_map[32];
};
struct omap_chan {
@@ -254,10 +258,22 @@ static void omap_dma_clear_csr(struct omap_chan *c)
omap_dma_chan_write(c, CSR, ~0);
}
+static unsigned omap_dma_get_csr(struct omap_chan *c)
+{
+ unsigned val = omap_dma_chan_read(c, CSR);
+
+ if (!dma_omap1())
+ omap_dma_chan_write(c, CSR, val);
+
+ return val;
+}
+
static void omap_dma_assign(struct omap_dmadev *od, struct omap_chan *c,
unsigned lch)
{
c->channel_base = od->base + od->plat->channel_stride * lch;
+
+ od->lch_map[lch] = c;
}
static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
@@ -460,32 +476,103 @@ static void omap_dma_sched(unsigned long data)
}
}
+static irqreturn_t omap_dma_irq(int irq, void *devid)
+{
+ struct omap_dmadev *od = devid;
+ unsigned status, channel;
+
+ spin_lock(&od->irq_lock);
+
+ status = omap_dma_glbl_read(od, IRQSTATUS_L1);
+ status &= od->irq_enable_mask;
+ if (status == 0) {
+ spin_unlock(&od->irq_lock);
+ return IRQ_NONE;
+ }
+
+ while ((channel = ffs(status)) != 0) {
+ unsigned mask, csr;
+ struct omap_chan *c;
+
+ channel -= 1;
+ mask = BIT(channel);
+ status &= ~mask;
+
+ c = od->lch_map[channel];
+ if (c == NULL) {
+ /* This should never happen */
+ dev_err(od->ddev.dev, "invalid channel %u\n", channel);
+ continue;
+ }
+
+ csr = omap_dma_get_csr(c);
+ omap_dma_glbl_write(od, IRQSTATUS_L1, mask);
+
+ omap_dma_callback(channel, csr, c);
+ }
+
+ spin_unlock(&od->irq_lock);
+
+ return IRQ_HANDLED;
+}
+
static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
{
struct omap_dmadev *od = to_omap_dma_dev(chan->device);
struct omap_chan *c = to_omap_dma_chan(chan);
int ret;
- dev_dbg(od->ddev.dev, "allocating channel for %u\n", c->dma_sig);
+ if (od->legacy) {
+ ret = omap_request_dma(c->dma_sig, "DMA engine",
+ omap_dma_callback, c, &c->dma_ch);
+ } else {
+ ret = omap_request_dma(c->dma_sig, "DMA engine", NULL, NULL,
+ &c->dma_ch);
+ }
- ret = omap_request_dma(c->dma_sig, "DMA engine", omap_dma_callback,
- c, &c->dma_ch);
+ dev_dbg(od->ddev.dev, "allocating channel %u for %u\n",
+ c->dma_ch, c->dma_sig);
- if (ret >= 0)
+ if (ret >= 0) {
omap_dma_assign(od, c, c->dma_ch);
+ if (!od->legacy) {
+ unsigned val;
+
+ spin_lock_irq(&od->irq_lock);
+ val = BIT(c->dma_ch);
+ omap_dma_glbl_write(od, IRQSTATUS_L1, val);
+ od->irq_enable_mask |= val;
+ omap_dma_glbl_write(od, IRQENABLE_L1, od->irq_enable_mask);
+
+ val = omap_dma_glbl_read(od, IRQENABLE_L0);
+ val &= ~BIT(c->dma_ch);
+ omap_dma_glbl_write(od, IRQENABLE_L0, val);
+ spin_unlock_irq(&od->irq_lock);
+ }
+ }
+
return ret;
}
static void omap_dma_free_chan_resources(struct dma_chan *chan)
{
+ struct omap_dmadev *od = to_omap_dma_dev(chan->device);
struct omap_chan *c = to_omap_dma_chan(chan);
+ if (!od->legacy) {
+ spin_lock_irq(&od->irq_lock);
+ od->irq_enable_mask &= ~BIT(c->dma_ch);
+ omap_dma_glbl_write(od, IRQENABLE_L1, od->irq_enable_mask);
+ spin_unlock_irq(&od->irq_lock);
+ }
+
c->channel_base = NULL;
+ od->lch_map[c->dma_ch] = NULL;
vchan_free_chan_resources(&c->vc);
omap_free_dma(c->dma_ch);
- dev_dbg(c->vc.chan.device->dev, "freeing channel for %u\n", c->dma_sig);
+ dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
}
static size_t omap_dma_sg_size(struct omap_sg *sg)
@@ -1015,7 +1102,7 @@ static int omap_dma_probe(struct platform_device *pdev)
{
struct omap_dmadev *od;
struct resource *res;
- int rc, i;
+ int rc, i, irq;
od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
if (!od)
@@ -1045,6 +1132,7 @@ static int omap_dma_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&od->ddev.channels);
INIT_LIST_HEAD(&od->pending);
spin_lock_init(&od->lock);
+ spin_lock_init(&od->irq_lock);
tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
@@ -1056,6 +1144,21 @@ static int omap_dma_probe(struct platform_device *pdev)
}
}
+ irq = platform_get_irq(pdev, 1);
+ if (irq <= 0) {
+ dev_info(&pdev->dev, "failed to get L1 IRQ: %d\n", irq);
+ od->legacy = true;
+ } else {
+ /* Disable all interrupts */
+ od->irq_enable_mask = 0;
+ omap_dma_glbl_write(od, IRQENABLE_L1, 0);
+
+ rc = devm_request_irq(&pdev->dev, irq, omap_dma_irq,
+ IRQF_SHARED, "omap-dma-engine", od);
+ if (rc)
+ return rc;
+ }
+
rc = dma_async_device_register(&od->ddev);
if (rc) {
pr_warn("OMAP-DMA: failed to register slave DMA engine device: %d\n",
@@ -1092,6 +1195,12 @@ static int omap_dma_remove(struct platform_device *pdev)
of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(&od->ddev);
+
+ if (!od->legacy) {
+ /* Disable all interrupts */
+ omap_dma_glbl_write(od, IRQENABLE_L0, 0);
+ }
+
omap_dma_free(od);
return 0;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 26/26] dmaengine: omap-dma: more consolidation of CCR register setup
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (24 preceding siblings ...)
2014-02-10 15:58 ` [PATCH 25/26] dmaengine: omap-dma: move IRQ handling to omap-dma Russell King
@ 2014-02-10 15:58 ` Russell King
2014-02-13 17:22 ` [PATCH 00/26] OMAP dma engine rework Tony Lindgren
` (2 subsequent siblings)
28 siblings, 0 replies; 32+ messages in thread
From: Russell King @ 2014-02-10 15:58 UTC (permalink / raw)
To: linux-arm-kernel
We can move the handling of the DMA synchronisation control out of the
prepare functions; this can be pre-calculated when the DMA channel has
been allocated, so we don't need to duplicate this in both prepare
functions.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/dma/omap-dma.c | 46 ++++++++++++++++++----------------------------
1 file changed, 18 insertions(+), 28 deletions(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index ec98e718de70..64ceca2920b8 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -41,6 +41,7 @@ struct omap_chan {
struct list_head node;
void __iomem *channel_base;
const struct omap_dma_reg *reg_map;
+ uint32_t ccr;
struct dma_slave_config cfg;
unsigned dma_sig;
@@ -552,6 +553,21 @@ static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
}
}
+ if (dma_omap1()) {
+ if (__dma_omap16xx(od->plat->dma_attr)) {
+ c->ccr = CCR_OMAP31_DISABLE;
+ /* Duplicate what plat-omap/dma.c does */
+ c->ccr |= c->dma_ch + 1;
+ } else {
+ c->ccr = c->dma_sig & 0x1f;
+ }
+ } else {
+ c->ccr = c->dma_sig & 0x1f;
+ c->ccr |= (c->dma_sig & ~0x1f) << 14;
+ }
+ if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
+ c->ccr |= CCR_BUFFERING_DISABLE;
+
return ret;
}
@@ -787,7 +803,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->dev_addr = dev_addr;
d->es = es;
- d->ccr = CCR_SYNC_FRAME;
+ d->ccr = c->ccr | CCR_SYNC_FRAME;
if (dir == DMA_DEV_TO_MEM)
d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
else
@@ -797,14 +813,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->csdp = es;
if (dma_omap1()) {
- if (__dma_omap16xx(od->plat->dma_attr)) {
- d->ccr |= CCR_OMAP31_DISABLE;
- /* Duplicate what plat-omap/dma.c does */
- d->ccr |= c->dma_ch + 1;
- } else {
- d->ccr |= c->dma_sig & 0x1f;
- }
-
d->cicr |= CICR_TOUT_IE;
if (dir == DMA_DEV_TO_MEM)
@@ -812,16 +820,11 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
else
d->csdp |= CSDP_DST_PORT_TIPB | CSDP_SRC_PORT_EMIFF;
} else {
- d->ccr |= (c->dma_sig & ~0x1f) << 14;
- d->ccr |= c->dma_sig & 0x1f;
-
if (dir == DMA_DEV_TO_MEM)
d->ccr |= CCR_TRIGGER_SRC;
d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
}
- if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
- d->ccr |= CCR_BUFFERING_DISABLE;
if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
d->clnk_ctrl = c->dma_ch;
@@ -903,7 +906,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->sg[0].fn = buf_len / period_len;
d->sglen = 1;
- d->ccr = 0;
+ d->ccr = c->ccr;
if (dir == DMA_DEV_TO_MEM)
d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
else
@@ -916,14 +919,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->csdp = es;
if (dma_omap1()) {
- if (__dma_omap16xx(od->plat->dma_attr)) {
- d->ccr |= CCR_OMAP31_DISABLE;
- /* Duplicate what plat-omap/dma.c does */
- d->ccr |= c->dma_ch + 1;
- } else {
- d->ccr |= c->dma_sig & 0x1f;
- }
-
d->cicr |= CICR_TOUT_IE;
if (dir == DMA_DEV_TO_MEM)
@@ -931,9 +926,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
else
d->csdp |= CSDP_DST_PORT_MPUI | CSDP_SRC_PORT_EMIFF;
} else {
- d->ccr |= (c->dma_sig & ~0x1f) << 14;
- d->ccr |= c->dma_sig & 0x1f;
-
if (burst)
d->ccr |= CCR_SYNC_PACKET;
else
@@ -946,8 +938,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
}
- if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
- d->ccr |= CCR_BUFFERING_DISABLE;
if (__dma_omap15xx(od->plat->dma_attr))
d->ccr |= CCR_AUTO_INIT | CCR_REPEAT;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 00/26] OMAP dma engine rework
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (25 preceding siblings ...)
2014-02-10 15:58 ` [PATCH 26/26] dmaengine: omap-dma: more consolidation of CCR register setup Russell King
@ 2014-02-13 17:22 ` Tony Lindgren
2014-02-14 12:54 ` Sricharan R
2014-03-18 15:48 ` Vinod Koul
28 siblings, 0 replies; 32+ messages in thread
From: Tony Lindgren @ 2014-02-13 17:22 UTC (permalink / raw)
To: linux-arm-kernel
* Russell King - ARM Linux <linux@arm.linux.org.uk> [140210 07:58]:
> This is the current set of patches for the OMAP DMA engine rework,
> which should now work correctly on OMAP1 platforms thanks to Tony's
> testing.
>
> It would be good to get this validated by others across a range of
> OMAP platforms, and queued up for the next merge window, so it can
> be built upon.
>
> Acks appreciated, and once sufficient have been added, I'll send a
> pull request for this to Vinod.
Looks good to me and should not conflict with other patches
that I'm aware of. Please feel free to add:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 00/26] OMAP dma engine rework
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (26 preceding siblings ...)
2014-02-13 17:22 ` [PATCH 00/26] OMAP dma engine rework Tony Lindgren
@ 2014-02-14 12:54 ` Sricharan R
2014-03-18 15:48 ` Vinod Koul
28 siblings, 0 replies; 32+ messages in thread
From: Sricharan R @ 2014-02-14 12:54 UTC (permalink / raw)
To: linux-arm-kernel
On Monday 10 February 2014 09:25 PM, Russell King - ARM Linux wrote:
> This is the current set of patches for the OMAP DMA engine rework,
> which should now work correctly on OMAP1 platforms thanks to Tony's
> testing.
>
> It would be good to get this validated by others across a range of
> OMAP platforms, and queued up for the next merge window, so it can
> be built upon.
>
> Acks appreciated, and once sufficient have been added, I'll send a
> pull request for this to Vinod.
>
> arch/arm/mach-omap1/dma.c | 191 ++++++--------
> arch/arm/mach-omap2/dma.c | 183 ++++++-------
> arch/arm/plat-omap/dma.c | 17 +-
> drivers/dma/omap-dma.c | 659 +++++++++++++++++++++++++++++++++++++++++-----
> include/linux/omap-dma.h | 25 +-
> 5 files changed, 784 insertions(+), 291 deletions(-)
>
Tested this on DRA7XX with MMC peripheral DMA
Regards,
Sricharan
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 00/26] OMAP dma engine rework
2014-02-10 15:55 [PATCH 00/26] OMAP dma engine rework Russell King - ARM Linux
` (27 preceding siblings ...)
2014-02-14 12:54 ` Sricharan R
@ 2014-03-18 15:48 ` Vinod Koul
2014-03-29 18:13 ` Russell King - ARM Linux
28 siblings, 1 reply; 32+ messages in thread
From: Vinod Koul @ 2014-03-18 15:48 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 10, 2014 at 09:25:31PM +0530, Russell King - ARM Linux wrote:
> This is the current set of patches for the OMAP DMA engine rework,
> which should now work correctly on OMAP1 platforms thanks to Tony's
> testing.
>
> It would be good to get this validated by others across a range of
> OMAP platforms, and queued up for the next merge window, so it can
> be built upon.
>
> Acks appreciated, and once sufficient have been added, I'll send a
> pull request for this to Vinod.
So is this series finalized. I havent seen the pull request for this or did i
miss it!
--
~Vinod
>
> arch/arm/mach-omap1/dma.c | 191 ++++++--------
> arch/arm/mach-omap2/dma.c | 183 ++++++-------
> arch/arm/plat-omap/dma.c | 17 +-
> drivers/dma/omap-dma.c | 659 +++++++++++++++++++++++++++++++++++++++++-----
> include/linux/omap-dma.h | 25 +-
> 5 files changed, 784 insertions(+), 291 deletions(-)
>
> --
> FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
> in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
> Estimate before purchase was "up to 13.2Mbit".
--
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 00/26] OMAP dma engine rework
2014-03-18 15:48 ` Vinod Koul
@ 2014-03-29 18:13 ` Russell King - ARM Linux
2014-04-02 16:32 ` Vinod Koul
0 siblings, 1 reply; 32+ messages in thread
From: Russell King - ARM Linux @ 2014-03-29 18:13 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Mar 18, 2014 at 09:18:45PM +0530, Vinod Koul wrote:
> On Mon, Feb 10, 2014 at 09:25:31PM +0530, Russell King - ARM Linux wrote:
> > This is the current set of patches for the OMAP DMA engine rework,
> > which should now work correctly on OMAP1 platforms thanks to Tony's
> > testing.
> >
> > It would be good to get this validated by others across a range of
> > OMAP platforms, and queued up for the next merge window, so it can
> > be built upon.
> >
> > Acks appreciated, and once sufficient have been added, I'll send a
> > pull request for this to Vinod.
> So is this series finalized. I havent seen the pull request for this or did i
> miss it!
Gah, missed this.
As nothing has changed with it since 18th February, which was to add
Tony's ack to the set. I think it's as good as it's going to get for
the time being. It's also been in linux-next all this time, and no
one has reported any problems. I'll need to sort out a proper pull
request for it ASAP... or something. An alternate solution would be
your blessing for this set.
--
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 00/26] OMAP dma engine rework
2014-03-29 18:13 ` Russell King - ARM Linux
@ 2014-04-02 16:32 ` Vinod Koul
0 siblings, 0 replies; 32+ messages in thread
From: Vinod Koul @ 2014-04-02 16:32 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Mar 29, 2014 at 06:13:06PM +0000, Russell King - ARM Linux wrote:
> On Tue, Mar 18, 2014 at 09:18:45PM +0530, Vinod Koul wrote:
> > On Mon, Feb 10, 2014 at 09:25:31PM +0530, Russell King - ARM Linux wrote:
> > > This is the current set of patches for the OMAP DMA engine rework,
> > > which should now work correctly on OMAP1 platforms thanks to Tony's
> > > testing.
> > >
> > > It would be good to get this validated by others across a range of
> > > OMAP platforms, and queued up for the next merge window, so it can
> > > be built upon.
> > >
> > > Acks appreciated, and once sufficient have been added, I'll send a
> > > pull request for this to Vinod.
> > So is this series finalized. I havent seen the pull request for this or did i
> > miss it!
>
> Gah, missed this.
>
> As nothing has changed with it since 18th February, which was to add
> Tony's ack to the set. I think it's as good as it's going to get for
> the time being. It's also been in linux-next all this time, and no
> one has reported any problems. I'll need to sort out a proper pull
> request for it ASAP... or something. An alternate solution would be
> your blessing for this set.
Okay in that case pls send with my ACK.
Thanks
--
~Vinod
^ permalink raw reply [flat|nested] 32+ messages in thread