diff options
author | Linus Walleij <linus.walleij@stericsson.com> | 2010-06-20 17:24:52 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2010-06-22 21:01:53 -0400 |
commit | ef1872ec652b3bc472d6c0995d0b64d5058878ea (patch) | |
tree | 2de7cbca0012ab6931b8321c922311f70bbb4bb0 /drivers | |
parent | 941b77a3b6946dd6223a029007f695aa841b6d34 (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')
-rw-r--r-- | drivers/dma/ste_dma40.c | 64 | ||||
-rw-r--r-- | drivers/dma/ste_dma40_ll.h | 3 |
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 | ||
1213 | static 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 | |||
1237 | static int d40_config_memcpy(struct d40_chan *d40c) | 1213 | static 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 | ||