aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/amba-pl08x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r--drivers/dma/amba-pl08x.c246
1 files changed, 124 insertions, 122 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index e6d7228b1479..196a7378d332 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -156,14 +156,10 @@ struct pl08x_driver_data {
156#define PL08X_BOUNDARY_SHIFT (10) /* 1KB 0x400 */ 156#define PL08X_BOUNDARY_SHIFT (10) /* 1KB 0x400 */
157#define PL08X_BOUNDARY_SIZE (1 << PL08X_BOUNDARY_SHIFT) 157#define PL08X_BOUNDARY_SIZE (1 << PL08X_BOUNDARY_SHIFT)
158 158
159/* Minimum period between work queue runs */
160#define PL08X_WQ_PERIODMIN 20
161
162/* Size (bytes) of each LLI buffer allocated for one transfer */ 159/* Size (bytes) of each LLI buffer allocated for one transfer */
163# define PL08X_LLI_TSFR_SIZE 0x2000 160# define PL08X_LLI_TSFR_SIZE 0x2000
164 161
165/* Maximum times we call dma_pool_alloc on this pool without freeing */ 162/* Maximum times we call dma_pool_alloc on this pool without freeing */
166#define PL08X_MAX_ALLOCS 0x40
167#define MAX_NUM_TSFR_LLIS (PL08X_LLI_TSFR_SIZE/sizeof(struct pl08x_lli)) 163#define MAX_NUM_TSFR_LLIS (PL08X_LLI_TSFR_SIZE/sizeof(struct pl08x_lli))
168#define PL08X_ALIGN 8 164#define PL08X_ALIGN 8
169 165
@@ -495,10 +491,10 @@ static inline u32 pl08x_cctl_bits(u32 cctl, u8 srcwidth, u8 dstwidth,
495 491
496struct pl08x_lli_build_data { 492struct pl08x_lli_build_data {
497 struct pl08x_txd *txd; 493 struct pl08x_txd *txd;
498 struct pl08x_driver_data *pl08x;
499 struct pl08x_bus_data srcbus; 494 struct pl08x_bus_data srcbus;
500 struct pl08x_bus_data dstbus; 495 struct pl08x_bus_data dstbus;
501 size_t remainder; 496 size_t remainder;
497 u32 lli_bus;
502}; 498};
503 499
504/* 500/*
@@ -551,8 +547,7 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd,
551 llis_va[num_llis].src = bd->srcbus.addr; 547 llis_va[num_llis].src = bd->srcbus.addr;
552 llis_va[num_llis].dst = bd->dstbus.addr; 548 llis_va[num_llis].dst = bd->dstbus.addr;
553 llis_va[num_llis].lli = llis_bus + (num_llis + 1) * sizeof(struct pl08x_lli); 549 llis_va[num_llis].lli = llis_bus + (num_llis + 1) * sizeof(struct pl08x_lli);
554 if (bd->pl08x->lli_buses & PL08X_AHB2) 550 llis_va[num_llis].lli |= bd->lli_bus;
555 llis_va[num_llis].lli |= PL080_LLI_LM_AHB2;
556 551
557 if (cctl & PL080_CONTROL_SRC_INCR) 552 if (cctl & PL080_CONTROL_SRC_INCR)
558 bd->srcbus.addr += len; 553 bd->srcbus.addr += len;
@@ -605,9 +600,9 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
605 cctl = txd->cctl; 600 cctl = txd->cctl;
606 601
607 bd.txd = txd; 602 bd.txd = txd;
608 bd.pl08x = pl08x;
609 bd.srcbus.addr = txd->src_addr; 603 bd.srcbus.addr = txd->src_addr;
610 bd.dstbus.addr = txd->dst_addr; 604 bd.dstbus.addr = txd->dst_addr;
605 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0;
611 606
612 /* Find maximum width of the source bus */ 607 /* Find maximum width of the source bus */
613 bd.srcbus.maxwidth = 608 bd.srcbus.maxwidth =
@@ -622,25 +617,15 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
622 /* Set up the bus widths to the maximum */ 617 /* Set up the bus widths to the maximum */
623 bd.srcbus.buswidth = bd.srcbus.maxwidth; 618 bd.srcbus.buswidth = bd.srcbus.maxwidth;
624 bd.dstbus.buswidth = bd.dstbus.maxwidth; 619 bd.dstbus.buswidth = bd.dstbus.maxwidth;
625 dev_vdbg(&pl08x->adev->dev,
626 "%s source bus is %d bytes wide, dest bus is %d bytes wide\n",
627 __func__, bd.srcbus.buswidth, bd.dstbus.buswidth);
628
629 620
630 /* 621 /*
631 * Bytes transferred == tsize * MIN(buswidths), not max(buswidths) 622 * Bytes transferred == tsize * MIN(buswidths), not max(buswidths)
632 */ 623 */
633 max_bytes_per_lli = min(bd.srcbus.buswidth, bd.dstbus.buswidth) * 624 max_bytes_per_lli = min(bd.srcbus.buswidth, bd.dstbus.buswidth) *
634 PL080_CONTROL_TRANSFER_SIZE_MASK; 625 PL080_CONTROL_TRANSFER_SIZE_MASK;
635 dev_vdbg(&pl08x->adev->dev,
636 "%s max bytes per lli = %zu\n",
637 __func__, max_bytes_per_lli);
638 626
639 /* We need to count this down to zero */ 627 /* We need to count this down to zero */
640 bd.remainder = txd->len; 628 bd.remainder = txd->len;
641 dev_vdbg(&pl08x->adev->dev,
642 "%s remainder = %zu\n",
643 __func__, bd.remainder);
644 629
645 /* 630 /*
646 * Choose bus to align to 631 * Choose bus to align to
@@ -649,6 +634,16 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
649 */ 634 */
650 pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl); 635 pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl);
651 636
637 dev_vdbg(&pl08x->adev->dev, "src=0x%08x%s/%u dst=0x%08x%s/%u len=%zu llimax=%zu\n",
638 bd.srcbus.addr, cctl & PL080_CONTROL_SRC_INCR ? "+" : "",
639 bd.srcbus.buswidth,
640 bd.dstbus.addr, cctl & PL080_CONTROL_DST_INCR ? "+" : "",
641 bd.dstbus.buswidth,
642 bd.remainder, max_bytes_per_lli);
643 dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n",
644 mbus == &bd.srcbus ? "src" : "dst",
645 sbus == &bd.srcbus ? "src" : "dst");
646
652 if (txd->len < mbus->buswidth) { 647 if (txd->len < mbus->buswidth) {
653 /* Less than a bus width available - send as single bytes */ 648 /* Less than a bus width available - send as single bytes */
654 while (bd.remainder) { 649 while (bd.remainder) {
@@ -840,15 +835,14 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
840 { 835 {
841 int i; 836 int i;
842 837
838 dev_vdbg(&pl08x->adev->dev,
839 "%-3s %-9s %-10s %-10s %-10s %s\n",
840 "lli", "", "csrc", "cdst", "clli", "cctl");
843 for (i = 0; i < num_llis; i++) { 841 for (i = 0; i < num_llis; i++) {
844 dev_vdbg(&pl08x->adev->dev, 842 dev_vdbg(&pl08x->adev->dev,
845 "lli %d @%p: csrc=0x%08x, cdst=0x%08x, cctl=0x%08x, clli=0x%08x\n", 843 "%3d @%p: 0x%08x 0x%08x 0x%08x 0x%08x\n",
846 i, 844 i, &llis_va[i], llis_va[i].src,
847 &llis_va[i], 845 llis_va[i].dst, llis_va[i].lli, llis_va[i].cctl
848 llis_va[i].src,
849 llis_va[i].dst,
850 llis_va[i].cctl,
851 llis_va[i].lli
852 ); 846 );
853 } 847 }
854 } 848 }
@@ -1054,64 +1048,105 @@ pl08x_dma_tx_status(struct dma_chan *chan,
1054 1048
1055/* PrimeCell DMA extension */ 1049/* PrimeCell DMA extension */
1056struct burst_table { 1050struct burst_table {
1057 int burstwords; 1051 u32 burstwords;
1058 u32 reg; 1052 u32 reg;
1059}; 1053};
1060 1054
1061static const struct burst_table burst_sizes[] = { 1055static const struct burst_table burst_sizes[] = {
1062 { 1056 {
1063 .burstwords = 256, 1057 .burstwords = 256,
1064 .reg = (PL080_BSIZE_256 << PL080_CONTROL_SB_SIZE_SHIFT) | 1058 .reg = PL080_BSIZE_256,
1065 (PL080_BSIZE_256 << PL080_CONTROL_DB_SIZE_SHIFT),
1066 }, 1059 },
1067 { 1060 {
1068 .burstwords = 128, 1061 .burstwords = 128,
1069 .reg = (PL080_BSIZE_128 << PL080_CONTROL_SB_SIZE_SHIFT) | 1062 .reg = PL080_BSIZE_128,
1070 (PL080_BSIZE_128 << PL080_CONTROL_DB_SIZE_SHIFT),
1071 }, 1063 },
1072 { 1064 {
1073 .burstwords = 64, 1065 .burstwords = 64,
1074 .reg = (PL080_BSIZE_64 << PL080_CONTROL_SB_SIZE_SHIFT) | 1066 .reg = PL080_BSIZE_64,
1075 (PL080_BSIZE_64 << PL080_CONTROL_DB_SIZE_SHIFT),
1076 }, 1067 },
1077 { 1068 {
1078 .burstwords = 32, 1069 .burstwords = 32,
1079 .reg = (PL080_BSIZE_32 << PL080_CONTROL_SB_SIZE_SHIFT) | 1070 .reg = PL080_BSIZE_32,
1080 (PL080_BSIZE_32 << PL080_CONTROL_DB_SIZE_SHIFT),
1081 }, 1071 },
1082 { 1072 {
1083 .burstwords = 16, 1073 .burstwords = 16,
1084 .reg = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT) | 1074 .reg = PL080_BSIZE_16,
1085 (PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT),
1086 }, 1075 },
1087 { 1076 {
1088 .burstwords = 8, 1077 .burstwords = 8,
1089 .reg = (PL080_BSIZE_8 << PL080_CONTROL_SB_SIZE_SHIFT) | 1078 .reg = PL080_BSIZE_8,
1090 (PL080_BSIZE_8 << PL080_CONTROL_DB_SIZE_SHIFT),
1091 }, 1079 },
1092 { 1080 {
1093 .burstwords = 4, 1081 .burstwords = 4,
1094 .reg = (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT) | 1082 .reg = PL080_BSIZE_4,
1095 (PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT),
1096 }, 1083 },
1097 { 1084 {
1098 .burstwords = 1, 1085 .burstwords = 0,
1099 .reg = (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) | 1086 .reg = PL080_BSIZE_1,
1100 (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT),
1101 }, 1087 },
1102}; 1088};
1103 1089
1090/*
1091 * Given the source and destination available bus masks, select which
1092 * will be routed to each port. We try to have source and destination
1093 * on separate ports, but always respect the allowable settings.
1094 */
1095static u32 pl08x_select_bus(u8 src, u8 dst)
1096{
1097 u32 cctl = 0;
1098
1099 if (!(dst & PL08X_AHB1) || ((dst & PL08X_AHB2) && (src & PL08X_AHB1)))
1100 cctl |= PL080_CONTROL_DST_AHB2;
1101 if (!(src & PL08X_AHB1) || ((src & PL08X_AHB2) && !(dst & PL08X_AHB2)))
1102 cctl |= PL080_CONTROL_SRC_AHB2;
1103
1104 return cctl;
1105}
1106
1107static u32 pl08x_cctl(u32 cctl)
1108{
1109 cctl &= ~(PL080_CONTROL_SRC_AHB2 | PL080_CONTROL_DST_AHB2 |
1110 PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR |
1111 PL080_CONTROL_PROT_MASK);
1112
1113 /* Access the cell in privileged mode, non-bufferable, non-cacheable */
1114 return cctl | PL080_CONTROL_PROT_SYS;
1115}
1116
1117static u32 pl08x_width(enum dma_slave_buswidth width)
1118{
1119 switch (width) {
1120 case DMA_SLAVE_BUSWIDTH_1_BYTE:
1121 return PL080_WIDTH_8BIT;
1122 case DMA_SLAVE_BUSWIDTH_2_BYTES:
1123 return PL080_WIDTH_16BIT;
1124 case DMA_SLAVE_BUSWIDTH_4_BYTES:
1125 return PL080_WIDTH_32BIT;
1126 default:
1127 return ~0;
1128 }
1129}
1130
1131static u32 pl08x_burst(u32 maxburst)
1132{
1133 int i;
1134
1135 for (i = 0; i < ARRAY_SIZE(burst_sizes); i++)
1136 if (burst_sizes[i].burstwords <= maxburst)
1137 break;
1138
1139 return burst_sizes[i].reg;
1140}
1141
1104static int dma_set_runtime_config(struct dma_chan *chan, 1142static int dma_set_runtime_config(struct dma_chan *chan,
1105 struct dma_slave_config *config) 1143 struct dma_slave_config *config)
1106{ 1144{
1107 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1145 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1108 struct pl08x_driver_data *pl08x = plchan->host; 1146 struct pl08x_driver_data *pl08x = plchan->host;
1109 struct pl08x_channel_data *cd = plchan->cd;
1110 enum dma_slave_buswidth addr_width; 1147 enum dma_slave_buswidth addr_width;
1111 dma_addr_t addr; 1148 u32 width, burst, maxburst;
1112 u32 maxburst;
1113 u32 cctl = 0; 1149 u32 cctl = 0;
1114 int i;
1115 1150
1116 if (!plchan->slave) 1151 if (!plchan->slave)
1117 return -EINVAL; 1152 return -EINVAL;
@@ -1119,11 +1154,9 @@ static int dma_set_runtime_config(struct dma_chan *chan,
1119 /* Transfer direction */ 1154 /* Transfer direction */
1120 plchan->runtime_direction = config->direction; 1155 plchan->runtime_direction = config->direction;
1121 if (config->direction == DMA_TO_DEVICE) { 1156 if (config->direction == DMA_TO_DEVICE) {
1122 addr = config->dst_addr;
1123 addr_width = config->dst_addr_width; 1157 addr_width = config->dst_addr_width;
1124 maxburst = config->dst_maxburst; 1158 maxburst = config->dst_maxburst;
1125 } else if (config->direction == DMA_FROM_DEVICE) { 1159 } else if (config->direction == DMA_FROM_DEVICE) {
1126 addr = config->src_addr;
1127 addr_width = config->src_addr_width; 1160 addr_width = config->src_addr_width;
1128 maxburst = config->src_maxburst; 1161 maxburst = config->src_maxburst;
1129 } else { 1162 } else {
@@ -1132,46 +1165,40 @@ static int dma_set_runtime_config(struct dma_chan *chan,
1132 return -EINVAL; 1165 return -EINVAL;
1133 } 1166 }
1134 1167
1135 switch (addr_width) { 1168 width = pl08x_width(addr_width);
1136 case DMA_SLAVE_BUSWIDTH_1_BYTE: 1169 if (width == ~0) {
1137 cctl |= (PL080_WIDTH_8BIT << PL080_CONTROL_SWIDTH_SHIFT) |
1138 (PL080_WIDTH_8BIT << PL080_CONTROL_DWIDTH_SHIFT);
1139 break;
1140 case DMA_SLAVE_BUSWIDTH_2_BYTES:
1141 cctl |= (PL080_WIDTH_16BIT << PL080_CONTROL_SWIDTH_SHIFT) |
1142 (PL080_WIDTH_16BIT << PL080_CONTROL_DWIDTH_SHIFT);
1143 break;
1144 case DMA_SLAVE_BUSWIDTH_4_BYTES:
1145 cctl |= (PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT) |
1146 (PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT);
1147 break;
1148 default:
1149 dev_err(&pl08x->adev->dev, 1170 dev_err(&pl08x->adev->dev,
1150 "bad runtime_config: alien address width\n"); 1171 "bad runtime_config: alien address width\n");
1151 return -EINVAL; 1172 return -EINVAL;
1152 } 1173 }
1153 1174
1175 cctl |= width << PL080_CONTROL_SWIDTH_SHIFT;
1176 cctl |= width << PL080_CONTROL_DWIDTH_SHIFT;
1177
1154 /* 1178 /*
1155 * Now decide on a maxburst:
1156 * If this channel will only request single transfers, set this 1179 * If this channel will only request single transfers, set this
1157 * down to ONE element. Also select one element if no maxburst 1180 * down to ONE element. Also select one element if no maxburst
1158 * is specified. 1181 * is specified.
1159 */ 1182 */
1160 if (plchan->cd->single || maxburst == 0) { 1183 if (plchan->cd->single)
1161 cctl |= (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) | 1184 maxburst = 1;
1162 (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT); 1185
1186 burst = pl08x_burst(maxburst);
1187 cctl |= burst << PL080_CONTROL_SB_SIZE_SHIFT;
1188 cctl |= burst << PL080_CONTROL_DB_SIZE_SHIFT;
1189
1190 if (plchan->runtime_direction == DMA_FROM_DEVICE) {
1191 plchan->src_addr = config->src_addr;
1192 plchan->src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR |
1193 pl08x_select_bus(plchan->cd->periph_buses,
1194 pl08x->mem_buses);
1163 } else { 1195 } else {
1164 for (i = 0; i < ARRAY_SIZE(burst_sizes); i++) 1196 plchan->dst_addr = config->dst_addr;
1165 if (burst_sizes[i].burstwords <= maxburst) 1197 plchan->dst_cctl = pl08x_cctl(cctl) | PL080_CONTROL_SRC_INCR |
1166 break; 1198 pl08x_select_bus(pl08x->mem_buses,
1167 cctl |= burst_sizes[i].reg; 1199 plchan->cd->periph_buses);
1168 } 1200 }
1169 1201
1170 plchan->runtime_addr = addr;
1171
1172 /* Modify the default channel data to fit PrimeCell request */
1173 cd->cctl = cctl;
1174
1175 dev_dbg(&pl08x->adev->dev, 1202 dev_dbg(&pl08x->adev->dev,
1176 "configured channel %s (%s) for %s, data width %d, " 1203 "configured channel %s (%s) for %s, data width %d, "
1177 "maxburst %d words, LE, CCTL=0x%08x\n", 1204 "maxburst %d words, LE, CCTL=0x%08x\n",
@@ -1270,23 +1297,6 @@ static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
1270 return 0; 1297 return 0;
1271} 1298}
1272 1299
1273/*
1274 * Given the source and destination available bus masks, select which
1275 * will be routed to each port. We try to have source and destination
1276 * on separate ports, but always respect the allowable settings.
1277 */
1278static u32 pl08x_select_bus(struct pl08x_driver_data *pl08x, u8 src, u8 dst)
1279{
1280 u32 cctl = 0;
1281
1282 if (!(dst & PL08X_AHB1) || ((dst & PL08X_AHB2) && (src & PL08X_AHB1)))
1283 cctl |= PL080_CONTROL_DST_AHB2;
1284 if (!(src & PL08X_AHB1) || ((src & PL08X_AHB2) && !(dst & PL08X_AHB2)))
1285 cctl |= PL080_CONTROL_SRC_AHB2;
1286
1287 return cctl;
1288}
1289
1290static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan, 1300static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan,
1291 unsigned long flags) 1301 unsigned long flags)
1292{ 1302{
@@ -1338,8 +1348,8 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
1338 txd->cctl |= PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR; 1348 txd->cctl |= PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR;
1339 1349
1340 if (pl08x->vd->dualmaster) 1350 if (pl08x->vd->dualmaster)
1341 txd->cctl |= pl08x_select_bus(pl08x, 1351 txd->cctl |= pl08x_select_bus(pl08x->mem_buses,
1342 pl08x->mem_buses, pl08x->mem_buses); 1352 pl08x->mem_buses);
1343 1353
1344 ret = pl08x_prep_channel_resources(plchan, txd); 1354 ret = pl08x_prep_channel_resources(plchan, txd);
1345 if (ret) 1355 if (ret)
@@ -1356,7 +1366,6 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1356 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1366 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1357 struct pl08x_driver_data *pl08x = plchan->host; 1367 struct pl08x_driver_data *pl08x = plchan->host;
1358 struct pl08x_txd *txd; 1368 struct pl08x_txd *txd;
1359 u8 src_buses, dst_buses;
1360 int ret; 1369 int ret;
1361 1370
1362 /* 1371 /*
@@ -1390,42 +1399,22 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1390 txd->direction = direction; 1399 txd->direction = direction;
1391 txd->len = sgl->length; 1400 txd->len = sgl->length;
1392 1401
1393 txd->cctl = plchan->cd->cctl &
1394 ~(PL080_CONTROL_SRC_AHB2 | PL080_CONTROL_DST_AHB2 |
1395 PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR |
1396 PL080_CONTROL_PROT_MASK);
1397
1398 /* Access the cell in privileged mode, non-bufferable, non-cacheable */
1399 txd->cctl |= PL080_CONTROL_PROT_SYS;
1400
1401 if (direction == DMA_TO_DEVICE) { 1402 if (direction == DMA_TO_DEVICE) {
1402 txd->ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1403 txd->ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1403 txd->cctl |= PL080_CONTROL_SRC_INCR; 1404 txd->cctl = plchan->dst_cctl;
1404 txd->src_addr = sgl->dma_address; 1405 txd->src_addr = sgl->dma_address;
1405 if (plchan->runtime_addr) 1406 txd->dst_addr = plchan->dst_addr;
1406 txd->dst_addr = plchan->runtime_addr;
1407 else
1408 txd->dst_addr = plchan->cd->addr;
1409 src_buses = pl08x->mem_buses;
1410 dst_buses = plchan->cd->periph_buses;
1411 } else if (direction == DMA_FROM_DEVICE) { 1407 } else if (direction == DMA_FROM_DEVICE) {
1412 txd->ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1408 txd->ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1413 txd->cctl |= PL080_CONTROL_DST_INCR; 1409 txd->cctl = plchan->src_cctl;
1414 if (plchan->runtime_addr) 1410 txd->src_addr = plchan->src_addr;
1415 txd->src_addr = plchan->runtime_addr;
1416 else
1417 txd->src_addr = plchan->cd->addr;
1418 txd->dst_addr = sgl->dma_address; 1411 txd->dst_addr = sgl->dma_address;
1419 src_buses = plchan->cd->periph_buses;
1420 dst_buses = pl08x->mem_buses;
1421 } else { 1412 } else {
1422 dev_err(&pl08x->adev->dev, 1413 dev_err(&pl08x->adev->dev,
1423 "%s direction unsupported\n", __func__); 1414 "%s direction unsupported\n", __func__);
1424 return NULL; 1415 return NULL;
1425 } 1416 }
1426 1417
1427 txd->cctl |= pl08x_select_bus(pl08x, src_buses, dst_buses);
1428
1429 ret = pl08x_prep_channel_resources(plchan, txd); 1418 ret = pl08x_prep_channel_resources(plchan, txd);
1430 if (ret) 1419 if (ret)
1431 return NULL; 1420 return NULL;
@@ -1676,6 +1665,20 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
1676 return mask ? IRQ_HANDLED : IRQ_NONE; 1665 return mask ? IRQ_HANDLED : IRQ_NONE;
1677} 1666}
1678 1667
1668static void pl08x_dma_slave_init(struct pl08x_dma_chan *chan)
1669{
1670 u32 cctl = pl08x_cctl(chan->cd->cctl);
1671
1672 chan->slave = true;
1673 chan->name = chan->cd->bus_id;
1674 chan->src_addr = chan->cd->addr;
1675 chan->dst_addr = chan->cd->addr;
1676 chan->src_cctl = cctl | PL080_CONTROL_DST_INCR |
1677 pl08x_select_bus(chan->cd->periph_buses, chan->host->mem_buses);
1678 chan->dst_cctl = cctl | PL080_CONTROL_SRC_INCR |
1679 pl08x_select_bus(chan->host->mem_buses, chan->cd->periph_buses);
1680}
1681
1679/* 1682/*
1680 * Initialise the DMAC memcpy/slave channels. 1683 * Initialise the DMAC memcpy/slave channels.
1681 * Make a local wrapper to hold required data 1684 * Make a local wrapper to hold required data
@@ -1707,9 +1710,8 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1707 chan->state = PL08X_CHAN_IDLE; 1710 chan->state = PL08X_CHAN_IDLE;
1708 1711
1709 if (slave) { 1712 if (slave) {
1710 chan->slave = true;
1711 chan->name = pl08x->pd->slave_channels[i].bus_id;
1712 chan->cd = &pl08x->pd->slave_channels[i]; 1713 chan->cd = &pl08x->pd->slave_channels[i];
1714 pl08x_dma_slave_init(chan);
1713 } else { 1715 } else {
1714 chan->cd = &pl08x->pd->memcpy_channel; 1716 chan->cd = &pl08x->pd->memcpy_channel;
1715 chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i); 1717 chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i);