aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/amba-pl08x.c
diff options
context:
space:
mode:
authorRussell King - ARM Linux <linux@arm.linux.org.uk>2011-07-21 12:12:47 -0400
committerVinod Koul <vinod.koul@intel.com>2011-07-26 06:03:28 -0400
commitf14c426c723634d223344ad820997d92a3e355b6 (patch)
tree99ce25418d727c42e9db8169ae326ee685c71702 /drivers/dma/amba-pl08x.c
parentb207b4d02beb06059478339bbe4672ba715605d6 (diff)
DMA: PL08x: separately store source/destination cctl
Store the source/destination cctl values into the channel structure. This moves us towards being able to avoid a configuration call each time we use the channel. Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r--drivers/dma/amba-pl08x.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 077ddeefb864..ba617e3f23f8 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1095,12 +1095,21 @@ static const struct burst_table burst_sizes[] = {
1095 }, 1095 },
1096}; 1096};
1097 1097
1098static u32 pl08x_cctl(u32 cctl)
1099{
1100 cctl &= ~(PL080_CONTROL_SRC_AHB2 | PL080_CONTROL_DST_AHB2 |
1101 PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR |
1102 PL080_CONTROL_PROT_MASK);
1103
1104 /* Access the cell in privileged mode, non-bufferable, non-cacheable */
1105 return cctl | PL080_CONTROL_PROT_SYS;
1106}
1107
1098static int dma_set_runtime_config(struct dma_chan *chan, 1108static int dma_set_runtime_config(struct dma_chan *chan,
1099 struct dma_slave_config *config) 1109 struct dma_slave_config *config)
1100{ 1110{
1101 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1111 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1102 struct pl08x_driver_data *pl08x = plchan->host; 1112 struct pl08x_driver_data *pl08x = plchan->host;
1103 struct pl08x_channel_data *cd = plchan->cd;
1104 enum dma_slave_buswidth addr_width; 1113 enum dma_slave_buswidth addr_width;
1105 u32 maxburst; 1114 u32 maxburst;
1106 u32 cctl = 0; 1115 u32 cctl = 0;
@@ -1160,13 +1169,12 @@ static int dma_set_runtime_config(struct dma_chan *chan,
1160 1169
1161 if (plchan->runtime_direction == DMA_FROM_DEVICE) { 1170 if (plchan->runtime_direction == DMA_FROM_DEVICE) {
1162 plchan->src_addr = config->src_addr; 1171 plchan->src_addr = config->src_addr;
1172 plchan->src_cctl = pl08x_cctl(cctl);
1163 } else { 1173 } else {
1164 plchan->dst_addr = config->dst_addr; 1174 plchan->dst_addr = config->dst_addr;
1175 plchan->dst_cctl = pl08x_cctl(cctl);
1165 } 1176 }
1166 1177
1167 /* Modify the default channel data to fit PrimeCell request */
1168 cd->cctl = cctl;
1169
1170 dev_dbg(&pl08x->adev->dev, 1178 dev_dbg(&pl08x->adev->dev,
1171 "configured channel %s (%s) for %s, data width %d, " 1179 "configured channel %s (%s) for %s, data width %d, "
1172 "maxburst %d words, LE, CCTL=0x%08x\n", 1180 "maxburst %d words, LE, CCTL=0x%08x\n",
@@ -1385,24 +1393,16 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1385 txd->direction = direction; 1393 txd->direction = direction;
1386 txd->len = sgl->length; 1394 txd->len = sgl->length;
1387 1395
1388 txd->cctl = plchan->cd->cctl &
1389 ~(PL080_CONTROL_SRC_AHB2 | PL080_CONTROL_DST_AHB2 |
1390 PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR |
1391 PL080_CONTROL_PROT_MASK);
1392
1393 /* Access the cell in privileged mode, non-bufferable, non-cacheable */
1394 txd->cctl |= PL080_CONTROL_PROT_SYS;
1395
1396 if (direction == DMA_TO_DEVICE) { 1396 if (direction == DMA_TO_DEVICE) {
1397 txd->ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1397 txd->ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1398 txd->cctl |= PL080_CONTROL_SRC_INCR; 1398 txd->cctl = plchan->dst_cctl | PL080_CONTROL_SRC_INCR;
1399 txd->src_addr = sgl->dma_address; 1399 txd->src_addr = sgl->dma_address;
1400 txd->dst_addr = plchan->dst_addr; 1400 txd->dst_addr = plchan->dst_addr;
1401 src_buses = pl08x->mem_buses; 1401 src_buses = pl08x->mem_buses;
1402 dst_buses = plchan->cd->periph_buses; 1402 dst_buses = plchan->cd->periph_buses;
1403 } else if (direction == DMA_FROM_DEVICE) { 1403 } else if (direction == DMA_FROM_DEVICE) {
1404 txd->ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1404 txd->ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1405 txd->cctl |= PL080_CONTROL_DST_INCR; 1405 txd->cctl = plchan->src_cctl | PL080_CONTROL_DST_INCR;
1406 txd->src_addr = plchan->src_addr; 1406 txd->src_addr = plchan->src_addr;
1407 txd->dst_addr = sgl->dma_address; 1407 txd->dst_addr = sgl->dma_address;
1408 src_buses = plchan->cd->periph_buses; 1408 src_buses = plchan->cd->periph_buses;
@@ -1701,6 +1701,8 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1701 chan->cd = &pl08x->pd->slave_channels[i]; 1701 chan->cd = &pl08x->pd->slave_channels[i];
1702 chan->src_addr = chan->cd->addr; 1702 chan->src_addr = chan->cd->addr;
1703 chan->dst_addr = chan->cd->addr; 1703 chan->dst_addr = chan->cd->addr;
1704 chan->src_cctl = pl08x_cctl(chan->cd->cctl);
1705 chan->dst_cctl = pl08x_cctl(chan->cd->cctl);
1704 } else { 1706 } else {
1705 chan->cd = &pl08x->pd->memcpy_channel; 1707 chan->cd = &pl08x->pd->memcpy_channel;
1706 chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i); 1708 chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i);