Skip to content

Commit 82957f6

Browse files
committed
dmaengine: dw-axi-dmac: Per-channel burst limits
The DesignWare AXI DMAC IP can be configured with heterogeneous channel parameters. Allow maximum burst length to be set per-channel by making snps,axi-max-burst-len an array. Signed-off-by: Phil Elwell <[email protected]>
1 parent 4c325ef commit 82957f6

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
809809
ctlhi = CH_CTL_H_LLI_VALID;
810810

811811
if (chan->chip->dw->hdata->restrict_axi_burst_len) {
812-
burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
812+
burst_len = chan->chip->dw->hdata->axi_rw_burst_len[chan->id];
813813
ctlhi |= CH_CTL_H_ARLEN_EN | CH_CTL_H_AWLEN_EN |
814814
burst_len << CH_CTL_H_ARLEN_POS |
815815
burst_len << CH_CTL_H_AWLEN_POS;
@@ -1087,7 +1087,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
10871087

10881088
reg = CH_CTL_H_LLI_VALID;
10891089
if (chan->chip->dw->hdata->restrict_axi_burst_len) {
1090-
u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
1090+
u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len[chan->id];
10911091

10921092
reg |= (CH_CTL_H_ARLEN_EN |
10931093
burst_len << CH_CTL_H_ARLEN_POS |
@@ -1496,6 +1496,7 @@ static int parse_device_properties(struct axi_dma_chip *chip)
14961496
{
14971497
struct device *dev = chip->dev;
14981498
u32 tmp, carr[DMAC_MAX_CHANNELS];
1499+
u32 val;
14991500
int ret;
15001501

15011502
ret = device_property_read_u32(dev, "dma-channels", &tmp);
@@ -1552,15 +1553,21 @@ static int parse_device_properties(struct axi_dma_chip *chip)
15521553
}
15531554

15541555
/* axi-max-burst-len is optional property */
1555-
ret = device_property_read_u32(dev, "snps,axi-max-burst-len", &tmp);
1556-
if (!ret) {
1557-
if (tmp > DWAXIDMAC_ARWLEN_MAX + 1)
1558-
return -EINVAL;
1559-
if (tmp < DWAXIDMAC_ARWLEN_MIN + 1)
1560-
return -EINVAL;
1561-
1556+
ret = device_property_read_u32_array(dev, "snps,axi-max-burst-len", NULL,
1557+
chip->dw->hdata->nr_channels);
1558+
if ((ret > 0) &&
1559+
!device_property_read_u32_array(dev, "snps,axi-max-burst-len",
1560+
carr, ret)) {
15621561
chip->dw->hdata->restrict_axi_burst_len = true;
1563-
chip->dw->hdata->axi_rw_burst_len = tmp;
1562+
for (tmp = 0; tmp < chip->dw->hdata->nr_channels; tmp++) {
1563+
// Replicate the last value to any remaining channels
1564+
val = carr[min(tmp, (u32)ret - 1)];
1565+
if (val > DWAXIDMAC_ARWLEN_MAX + 1)
1566+
return -EINVAL;
1567+
if (val < DWAXIDMAC_ARWLEN_MIN + 1)
1568+
return -EINVAL;
1569+
chip->dw->hdata->axi_rw_burst_len[tmp] = val;
1570+
}
15641571
}
15651572

15661573
return 0;
@@ -1674,7 +1681,7 @@ static int dw_probe(struct platform_device *pdev)
16741681
dma_cap_set(DMA_CYCLIC, dw->dma.cap_mask);
16751682

16761683
/* DMA capabilities */
1677-
dw->dma.max_burst = hdata->axi_rw_burst_len;
1684+
dw->dma.max_burst = hdata->axi_rw_burst_len[0];
16781685
dw->dma.src_addr_widths = AXI_DMA_BUSWIDTHS;
16791686
dw->dma.dst_addr_widths = AXI_DMA_BUSWIDTHS;
16801687
dw->dma.directions = BIT(DMA_MEM_TO_MEM);

drivers/dma/dw-axi-dmac/dw-axi-dmac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct dw_axi_dma_hcfg {
2929
u32 block_size[DMAC_MAX_CHANNELS];
3030
u32 priority[DMAC_MAX_CHANNELS];
3131
/* maximum supported axi burst length */
32-
u32 axi_rw_burst_len;
32+
u32 axi_rw_burst_len[DMAC_MAX_CHANNELS];
3333
/* Register map for DMAX_NUM_CHANNELS <= 8 */
3434
bool reg_map_8_channels;
3535
bool restrict_axi_burst_len;

drivers/misc/rp1-pio.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
#define RP1_PIO_FIFO_RX2 0x18
5151
#define RP1_PIO_FIFO_RX3 0x1c
5252

53-
#define RP1_PIO_DMACTRL_DEFAULT 0x80000104
53+
#define RP1_PIO_DMACTRL_DEFAULT 0x80000110
5454

5555
#define HANDLER(_n, _f) \
5656
[_IOC_NR(PIO_IOC_ ## _n)] = { #_n, rp1_pio_ ## _f, _IOC_SIZE(PIO_IOC_ ## _n) }
@@ -676,6 +676,10 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s
676676
config.src_addr = fifo_addr;
677677
config.dst_addr = fifo_addr;
678678
config.direction = (dir == RP1_PIO_DIR_TO_SM) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
679+
if (dir == RP1_PIO_DIR_TO_SM)
680+
config.dst_maxburst = 16;
681+
else
682+
config.src_maxburst = 16;
679683

680684
ret = dmaengine_slave_config(dma->chan, &config);
681685
if (ret)

0 commit comments

Comments
 (0)