aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-06-20 17:24:52 -0400
committerDan Williams <dan.j.williams@intel.com>2010-06-22 21:01:53 -0400
commitef1872ec652b3bc472d6c0995d0b64d5058878ea (patch)
tree2de7cbca0012ab6931b8321c922311f70bbb4bb0 /drivers/dma
parent941b77a3b6946dd6223a029007f695aa841b6d34 (diff)
DMAENGINE: ste_dma40: only write phy channel config first time
We only need to write the configuration to a physical channel if it is free, else it is already written. Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/ste_dma40.c64
-rw-r--r--drivers/dma/ste_dma40_ll.h3
2 files changed, 35 insertions, 32 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 4618d6c727c8..9655452f0b69 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1210,30 +1210,6 @@ out:
1210 1210
1211} 1211}
1212 1212
1213static int d40_config_chan(struct d40_chan *d40c,
1214 struct stedma40_chan_cfg *info)
1215{
1216
1217 /* Fill in basic CFG register values */
1218 d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg,
1219 &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN);
1220
1221 if (d40c->log_num != D40_PHY_CHAN) {
1222 d40_log_cfg(&d40c->dma_cfg,
1223 &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
1224
1225 if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
1226 d40c->lcpa = d40c->base->lcpa_base +
1227 d40c->dma_cfg.src_dev_type * 32;
1228 else
1229 d40c->lcpa = d40c->base->lcpa_base +
1230 d40c->dma_cfg.dst_dev_type * 32 + 16;
1231 }
1232
1233 /* Write channel configuration to the DMA */
1234 return d40_config_write(d40c);
1235}
1236
1237static int d40_config_memcpy(struct d40_chan *d40c) 1213static int d40_config_memcpy(struct d40_chan *d40c)
1238{ 1214{
1239 dma_cap_mask_t cap = d40c->chan.device->cap_mask; 1215 dma_cap_mask_t cap = d40c->chan.device->cap_mask;
@@ -1691,20 +1667,21 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
1691 unsigned long flags; 1667 unsigned long flags;
1692 struct d40_chan *d40c = 1668 struct d40_chan *d40c =
1693 container_of(chan, struct d40_chan, chan); 1669 container_of(chan, struct d40_chan, chan);
1694 1670 bool is_free_phy;
1695 spin_lock_irqsave(&d40c->lock, flags); 1671 spin_lock_irqsave(&d40c->lock, flags);
1696 1672
1697 d40c->completed = chan->cookie = 1; 1673 d40c->completed = chan->cookie = 1;
1698 1674
1699 /* 1675 /*
1700 * If no dma configuration is set (channel_type == 0) 1676 * If no dma configuration is set (channel_type == 0)
1701 * use default configuration 1677 * use default configuration (memcpy)
1702 */ 1678 */
1703 if (d40c->dma_cfg.channel_type == 0) { 1679 if (d40c->dma_cfg.channel_type == 0) {
1704 err = d40_config_memcpy(d40c); 1680 err = d40_config_memcpy(d40c);
1705 if (err) 1681 if (err)
1706 goto err_alloc; 1682 goto err_alloc;
1707 } 1683 }
1684 is_free_phy = (d40c->phy_chan == NULL);
1708 1685
1709 err = d40_allocate_channel(d40c); 1686 err = d40_allocate_channel(d40c);
1710 if (err) { 1687 if (err) {
@@ -1713,12 +1690,35 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
1713 goto err_alloc; 1690 goto err_alloc;
1714 } 1691 }
1715 1692
1716 err = d40_config_chan(d40c, &d40c->dma_cfg); 1693 /* Fill in basic CFG register values */
1717 if (err) { 1694 d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg,
1718 dev_err(&d40c->chan.dev->device, 1695 &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN);
1719 "[%s] Failed to configure channel\n", 1696
1720 __func__); 1697 if (d40c->log_num != D40_PHY_CHAN) {
1721 goto err_config; 1698 d40_log_cfg(&d40c->dma_cfg,
1699 &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
1700
1701 if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
1702 d40c->lcpa = d40c->base->lcpa_base +
1703 d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
1704 else
1705 d40c->lcpa = d40c->base->lcpa_base +
1706 d40c->dma_cfg.dst_dev_type *
1707 D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
1708 }
1709
1710 /*
1711 * Only write channel configuration to the DMA if the physical
1712 * resource is free. In case of multiple logical channels
1713 * on the same physical resource, only the first write is necessary.
1714 */
1715 if (is_free_phy) {
1716 err = d40_config_write(d40c);
1717 if (err) {
1718 dev_err(&d40c->chan.dev->device,
1719 "[%s] Failed to configure channel\n",
1720 __func__);
1721 }
1722 } 1722 }
1723 1723
1724 spin_unlock_irqrestore(&d40c->lock, flags); 1724 spin_unlock_irqrestore(&d40c->lock, flags);
diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h
index 2029280cb332..c081f28ec1e3 100644
--- a/drivers/dma/ste_dma40_ll.h
+++ b/drivers/dma/ste_dma40_ll.h
@@ -13,6 +13,9 @@
13#define D40_DREG_PCDELTA (8 * 4) 13#define D40_DREG_PCDELTA (8 * 4)
14#define D40_LLI_ALIGN 16 /* LLI alignment must be 16 bytes. */ 14#define D40_LLI_ALIGN 16 /* LLI alignment must be 16 bytes. */
15 15
16#define D40_LCPA_CHAN_SIZE 32
17#define D40_LCPA_CHAN_DST_DELTA 16
18
16#define D40_TYPE_TO_GROUP(type) (type / 16) 19#define D40_TYPE_TO_GROUP(type) (type / 16)
17#define D40_TYPE_TO_EVENT(type) (type % 16) 20#define D40_TYPE_TO_EVENT(type) (type % 16)
18 21