* [1/1] dmaengine: dw-axi-dmac: Support src_maxburst and dst_maxburst
@ 2023-09-13 8:32 Tan En De
2023-09-13 10:07 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Tan En De @ 2023-09-13 8:32 UTC (permalink / raw)
To: dmaengine; +Cc: Eugeniy.Paltsev, vkoul, Tan En De
Current implementation has hardcoded CHx_CTL.SRC_MSIZE and
CHx_CTL.DST_MSIZE with a constant, namely DWAXIDMAC_BURST_TRANS_LEN_4.
However, to support hardware with different source/destination burst
transaction length, the aforementioned values shall be configurable
based on dma_slave_config set by client driver.
So, this commit is to allow client driver to configure
- CHx_CTL.SRC_MSIZE via dma_slave_config.src_maxburst
- CHx_CTL.DST_MSIZE via dma_slave_config.dst_maxburst
Signed-off-by: Tan En De <ende.tan@starfivetech.com>
---
.../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 38 +++++++++++++++----
drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 3 +-
2 files changed, 33 insertions(+), 8 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 dd02f84e404d..c0925ffde2f9 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -610,7 +610,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
size_t axi_block_ts;
size_t block_ts;
u32 ctllo, ctlhi;
- u32 burst_len;
+ u32 burst_len, src_burst_trans_len, dst_burst_trans_len;
axi_block_ts = chan->chip->dw->hdata->block_size[chan->id];
@@ -674,8 +674,20 @@ 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;
+ dst_burst_trans_len = chan->config.dst_maxburst ?
+ __ffs(chan->config.dst_maxburst) - 1 :
+ DWAXIDMAC_BURST_TRANS_LEN_4;
+ if (dst_burst_trans_len > DWAXIDMAC_BURST_TRANS_LEN_MAX)
+ return -EINVAL;
+ ctllo |= dst_burst_trans_len << CH_CTL_L_DST_MSIZE_POS;
+
+ src_burst_trans_len = chan->config.src_maxburst ?
+ __ffs(chan->config.src_maxburst) - 1 :
+ DWAXIDMAC_BURST_TRANS_LEN_4;
+ if (src_burst_trans_len > DWAXIDMAC_BURST_TRANS_LEN_MAX)
+ return -EINVAL;
+ ctllo |= src_burst_trans_len << CH_CTL_L_SRC_MSIZE_POS;
+
hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
set_desc_src_master(hw_desc);
@@ -878,7 +890,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
size_t block_ts, max_block_ts, xfer_len;
struct axi_dma_hw_desc *hw_desc = NULL;
struct axi_dma_desc *desc = NULL;
- u32 xfer_width, reg, num;
+ u32 xfer_width, reg, num, src_burst_trans_len, dst_burst_trans_len;
u64 llp = 0;
u8 lms = 0; /* Select AXI0 master for LLI fetching */
@@ -936,9 +948,21 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
}
hw_desc->lli->ctl_hi = cpu_to_le32(reg);
- reg = (DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
- xfer_width << CH_CTL_L_DST_WIDTH_POS |
+ dst_burst_trans_len = chan->config.dst_maxburst ?
+ __ffs(chan->config.dst_maxburst) - 1 :
+ DWAXIDMAC_BURST_TRANS_LEN_4;
+ if (dst_burst_trans_len > DWAXIDMAC_BURST_TRANS_LEN_MAX)
+ return -EINVAL;
+ reg |= dst_burst_trans_len << CH_CTL_L_DST_MSIZE_POS;
+
+ src_burst_trans_len = chan->config.src_maxburst ?
+ __ffs(chan->config.src_maxburst) - 1 :
+ DWAXIDMAC_BURST_TRANS_LEN_4;
+ if (src_burst_trans_len > DWAXIDMAC_BURST_TRANS_LEN_MAX)
+ return -EINVAL;
+ reg |= src_burst_trans_len << CH_CTL_L_SRC_MSIZE_POS;
+
+ reg = (xfer_width << CH_CTL_L_DST_WIDTH_POS |
xfer_width << CH_CTL_L_SRC_WIDTH_POS |
DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS);
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index eb267cb24f67..877bff395740 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -265,7 +265,8 @@ enum {
DWAXIDMAC_BURST_TRANS_LEN_128,
DWAXIDMAC_BURST_TRANS_LEN_256,
DWAXIDMAC_BURST_TRANS_LEN_512,
- DWAXIDMAC_BURST_TRANS_LEN_1024
+ DWAXIDMAC_BURST_TRANS_LEN_1024,
+ DWAXIDMAC_BURST_TRANS_LEN_MAX = DWAXIDMAC_BURST_TRANS_LEN_1024
};
#define CH_CTL_L_DST_WIDTH_POS 11
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [1/1] dmaengine: dw-axi-dmac: Support src_maxburst and dst_maxburst
2023-09-13 8:32 [1/1] dmaengine: dw-axi-dmac: Support src_maxburst and dst_maxburst Tan En De
@ 2023-09-13 10:07 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2023-09-13 10:07 UTC (permalink / raw)
To: Tan En De, dmaengine; +Cc: oe-kbuild-all, Eugeniy.Paltsev, vkoul, Tan En De
Hi Tan,
kernel test robot noticed the following build warnings:
[auto build test WARNING on vkoul-dmaengine/next]
[also build test WARNING on linus/master v6.6-rc1 next-20230913]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Tan-En-De/dmaengine-dw-axi-dmac-Support-src_maxburst-and-dst_maxburst/20230913-163406
base: https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next
patch link: https://lore.kernel.org/r/20230913083249.1244-1-ende.tan%40starfivetech.com
patch subject: [1/1] dmaengine: dw-axi-dmac: Support src_maxburst and dst_maxburst
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230913/202309131749.P3k6i6Fz-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230913/202309131749.P3k6i6Fz-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309131749.P3k6i6Fz-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c: In function 'dma_chan_prep_dma_memcpy':
>> drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:955:32: warning: returning 'int' from a function with return type 'struct dma_async_tx_descriptor *' makes pointer from integer without a cast [-Wint-conversion]
955 | return -EINVAL;
| ^
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c:962:32: warning: returning 'int' from a function with return type 'struct dma_async_tx_descriptor *' makes pointer from integer without a cast [-Wint-conversion]
962 | return -EINVAL;
| ^
vim +955 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
884
885 static struct dma_async_tx_descriptor *
886 dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
887 dma_addr_t src_adr, size_t len, unsigned long flags)
888 {
889 struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
890 size_t block_ts, max_block_ts, xfer_len;
891 struct axi_dma_hw_desc *hw_desc = NULL;
892 struct axi_dma_desc *desc = NULL;
893 u32 xfer_width, reg, num, src_burst_trans_len, dst_burst_trans_len;
894 u64 llp = 0;
895 u8 lms = 0; /* Select AXI0 master for LLI fetching */
896
897 dev_dbg(chan2dev(chan), "%s: memcpy: src: %pad dst: %pad length: %zd flags: %#lx",
898 axi_chan_name(chan), &src_adr, &dst_adr, len, flags);
899
900 max_block_ts = chan->chip->dw->hdata->block_size[chan->id];
901 xfer_width = axi_chan_get_xfer_width(chan, src_adr, dst_adr, len);
902 num = DIV_ROUND_UP(len, max_block_ts << xfer_width);
903 desc = axi_desc_alloc(num);
904 if (unlikely(!desc))
905 goto err_desc_get;
906
907 desc->chan = chan;
908 num = 0;
909 desc->length = 0;
910 while (len) {
911 xfer_len = len;
912
913 hw_desc = &desc->hw_desc[num];
914 /*
915 * Take care for the alignment.
916 * Actually source and destination widths can be different, but
917 * make them same to be simpler.
918 */
919 xfer_width = axi_chan_get_xfer_width(chan, src_adr, dst_adr, xfer_len);
920
921 /*
922 * block_ts indicates the total number of data of width
923 * to be transferred in a DMA block transfer.
924 * BLOCK_TS register should be set to block_ts - 1
925 */
926 block_ts = xfer_len >> xfer_width;
927 if (block_ts > max_block_ts) {
928 block_ts = max_block_ts;
929 xfer_len = max_block_ts << xfer_width;
930 }
931
932 hw_desc->lli = axi_desc_get(chan, &hw_desc->llp);
933 if (unlikely(!hw_desc->lli))
934 goto err_desc_get;
935
936 write_desc_sar(hw_desc, src_adr);
937 write_desc_dar(hw_desc, dst_adr);
938 hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
939
940 reg = CH_CTL_H_LLI_VALID;
941 if (chan->chip->dw->hdata->restrict_axi_burst_len) {
942 u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
943
944 reg |= (CH_CTL_H_ARLEN_EN |
945 burst_len << CH_CTL_H_ARLEN_POS |
946 CH_CTL_H_AWLEN_EN |
947 burst_len << CH_CTL_H_AWLEN_POS);
948 }
949 hw_desc->lli->ctl_hi = cpu_to_le32(reg);
950
951 dst_burst_trans_len = chan->config.dst_maxburst ?
952 __ffs(chan->config.dst_maxburst) - 1 :
953 DWAXIDMAC_BURST_TRANS_LEN_4;
954 if (dst_burst_trans_len > DWAXIDMAC_BURST_TRANS_LEN_MAX)
> 955 return -EINVAL;
956 reg |= dst_burst_trans_len << CH_CTL_L_DST_MSIZE_POS;
957
958 src_burst_trans_len = chan->config.src_maxburst ?
959 __ffs(chan->config.src_maxburst) - 1 :
960 DWAXIDMAC_BURST_TRANS_LEN_4;
961 if (src_burst_trans_len > DWAXIDMAC_BURST_TRANS_LEN_MAX)
962 return -EINVAL;
963 reg |= src_burst_trans_len << CH_CTL_L_SRC_MSIZE_POS;
964
965 reg = (xfer_width << CH_CTL_L_DST_WIDTH_POS |
966 xfer_width << CH_CTL_L_SRC_WIDTH_POS |
967 DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
968 DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS);
969 hw_desc->lli->ctl_lo = cpu_to_le32(reg);
970
971 set_desc_src_master(hw_desc);
972 set_desc_dest_master(hw_desc, desc);
973
974 hw_desc->len = xfer_len;
975 desc->length += hw_desc->len;
976 /* update the length and addresses for the next loop cycle */
977 len -= xfer_len;
978 dst_adr += xfer_len;
979 src_adr += xfer_len;
980 num++;
981 }
982
983 /* Set end-of-link to the last link descriptor of list */
984 set_desc_last(&desc->hw_desc[num - 1]);
985 /* Managed transfer list */
986 do {
987 hw_desc = &desc->hw_desc[--num];
988 write_desc_llp(hw_desc, llp | lms);
989 llp = hw_desc->llp;
990 } while (num);
991
992 return vchan_tx_prep(&chan->vc, &desc->vd, flags);
993
994 err_desc_get:
995 if (desc)
996 axi_desc_put(desc);
997 return NULL;
998 }
999
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-09-13 10:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-13 8:32 [1/1] dmaengine: dw-axi-dmac: Support src_maxburst and dst_maxburst Tan En De
2023-09-13 10:07 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox