From e537bfe05cc60092c920c5339dc9c22e477502cc Mon Sep 17 00:00:00 2001 From: samin Date: Mon, 22 Nov 2021 17:21:34 +0800 Subject: [PATCH] dmaengine: dw-axi-dmac: add burst_trans_len support. Different peripherals may require different burst_trans_len. Some ALSA devices may require BURST_TRANS_LEN_16, but this parameter may not work properly on some peripherals (spi, etc.). This patch will allow BURST_TRANS_LEN to be passed in from DTS. dmas = <&dma hs_nu burst_trans_len> burst_trans_len: <-1> defalut <0> BURST_TRANS_LEN_1 <1> BURST_TRANS_LEN_4 /*defalut value*/ <2> BURST_TRANS_LEN_8 <3> BURST_TRANS_LEN_16 <4> BURST_TRANS_LEN_32 <5> BURST_TRANS_LEN_64 <6> BURST_TRANS_LEN_128 <7> BURST_TRANS_LEN_256 Signed-off-by: samin --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 18 ++++++++++++++++-- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index 6136844..48e42ca 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -658,6 +658,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan, size_t block_ts; u32 ctllo, ctlhi; u32 burst_len; + u32 burst_trans_len; axi_block_ts = chan->chip->dw->hdata->block_size[chan->id]; @@ -721,8 +722,14 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan, hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1); - ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | - DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS; + if (chan->fixed_burst_trans_len == true) + burst_trans_len = chan->burst_trans_len; + else + burst_trans_len = DWAXIDMAC_BURST_TRANS_LEN_4; + + ctllo |= burst_trans_len << CH_CTL_L_DST_MSIZE_POS | + burst_trans_len << CH_CTL_L_SRC_MSIZE_POS; + hw_desc->lli->ctl_lo = cpu_to_le32(ctllo); set_desc_src_master(hw_desc); @@ -1316,6 +1323,13 @@ static struct dma_chan *dw_axi_dma_of_xlate(struct of_phandle_args *dma_spec, chan = dchan_to_axi_dma_chan(dchan); chan->hw_handshake_num = dma_spec->args[0]; + + /*some per may need fixed-burst_trans_len*/ + if (dma_spec->args_count == 2 && dma_spec->args[1] > 0) { + chan->fixed_burst_trans_len = true; + chan->burst_trans_len = dma_spec->args[1]; + } + return dchan; } diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index 6589eee..8d92ba2 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -66,6 +66,7 @@ struct axi_dma_chan { void __iomem *chan_regs; u8 id; u8 hw_handshake_num; + s8 burst_trans_len; atomic_t descs_allocated; struct dma_pool *desc_pool; @@ -74,6 +75,7 @@ struct axi_dma_chan { struct axi_dma_desc *desc; struct dma_slave_config config; enum dma_transfer_direction direction; + bool fixed_burst_trans_len; bool cyclic; /* these other elements are all protected by vc.lock */ bool is_paused; -- 2.7.4