diff mbox series

[1/1] dmaengine: fsl-edma: support edma memcpy

Message ID 20211009095502.1230805-1-joy.zou@nxp.com (mailing list archive)
State Superseded
Headers show
Series [1/1] dmaengine: fsl-edma: support edma memcpy | expand

Commit Message

Joy Zou Oct. 9, 2021, 9:55 a.m. UTC
add memcpy in edma.

Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 27 +++++++++++++++++++++++++++
 drivers/dma/fsl-edma-common.h |  4 ++++
 drivers/dma/fsl-edma.c        |  7 +++++++
 3 files changed, 38 insertions(+)

Comments

kernel test robot Oct. 9, 2021, 5:07 p.m. UTC | #1
Hi Joy,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on vkoul-dmaengine/next]
[also build test WARNING on v5.15-rc4 next-20211008]
[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]

url:    https://github.com/0day-ci/linux/commits/Joy-Zou/dmaengine-fsl-edma-support-edma-memcpy/20211009-175846
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next
config: xtensa-randconfig-s032-20211009 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/5ab92681f29355b4b9ff8c603e7d9849c168e636
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Joy-Zou/dmaengine-fsl-edma-support-edma-memcpy/20211009-175846
        git checkout 5ab92681f29355b4b9ff8c603e7d9849c168e636
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=xtensa SHELL=/bin/bash drivers/dma/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
   drivers/dma/fsl-edma-common.c:360:28: sparse: sparse: cast from restricted __le32
   drivers/dma/fsl-edma-common.c:361:28: sparse: sparse: cast from restricted __le32
   drivers/dma/fsl-edma-common.c:363:28: sparse: sparse: cast from restricted __le16
   drivers/dma/fsl-edma-common.c:364:30: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected unsigned short [usertype] val @@     got restricted __le16 [usertype] soff @@
   drivers/dma/fsl-edma-common.c:364:30: sparse:     expected unsigned short [usertype] val
   drivers/dma/fsl-edma-common.c:364:30: sparse:     got restricted __le16 [usertype] soff
   drivers/dma/fsl-edma-common.c:366:28: sparse: sparse: cast from restricted __le32
   drivers/dma/fsl-edma-common.c:367:28: sparse: sparse: cast from restricted __le32
   drivers/dma/fsl-edma-common.c:369:28: sparse: sparse: cast from restricted __le16
   drivers/dma/fsl-edma-common.c:370:28: sparse: sparse: cast from restricted __le16
   drivers/dma/fsl-edma-common.c:371:28: sparse: sparse: cast from restricted __le16
   drivers/dma/fsl-edma-common.c:373:28: sparse: sparse: cast from restricted __le32
>> drivers/dma/fsl-edma-common.c:377:26: sparse: sparse: invalid assignment: |=
>> drivers/dma/fsl-edma-common.c:377:26: sparse:    left side has type restricted __le16
>> drivers/dma/fsl-edma-common.c:377:26: sparse:    right side has type unsigned long
   drivers/dma/fsl-edma-common.c:379:28: sparse: sparse: cast from restricted __le16

vim +377 drivers/dma/fsl-edma-common.c

   344	
   345	static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
   346					  struct fsl_edma_hw_tcd *tcd)
   347	{
   348		struct fsl_edma_engine *edma = fsl_chan->edma;
   349		struct edma_regs *regs = &fsl_chan->edma->regs;
   350		u32 ch = fsl_chan->vchan.chan.chan_id;
   351	
   352		/*
   353		 * TCD parameters are stored in struct fsl_edma_hw_tcd in little
   354		 * endian format. However, we need to load the TCD registers in
   355		 * big- or little-endian obeying the eDMA engine model endian,
   356		 * and this is performed from specific edma_write functions
   357		 */
   358		edma_writew(edma, 0,  &regs->tcd[ch].csr);
   359	
   360		edma_writel(edma, (s32)tcd->saddr, &regs->tcd[ch].saddr);
   361		edma_writel(edma, (s32)tcd->daddr, &regs->tcd[ch].daddr);
   362	
   363		edma_writew(edma, (s16)tcd->attr, &regs->tcd[ch].attr);
   364		edma_writew(edma, tcd->soff, &regs->tcd[ch].soff);
   365	
   366		edma_writel(edma, (s32)tcd->nbytes, &regs->tcd[ch].nbytes);
   367		edma_writel(edma, (s32)tcd->slast, &regs->tcd[ch].slast);
   368	
   369		edma_writew(edma, (s16)tcd->citer, &regs->tcd[ch].citer);
   370		edma_writew(edma, (s16)tcd->biter, &regs->tcd[ch].biter);
   371		edma_writew(edma, (s16)tcd->doff, &regs->tcd[ch].doff);
   372	
   373		edma_writel(edma, (s32)tcd->dlast_sga,
   374				&regs->tcd[ch].dlast_sga);
   375	
   376		if (fsl_chan->is_sw)
 > 377			tcd->csr |= EDMA_TCD_CSR_START;
   378	
   379		edma_writew(edma, (s16)tcd->csr, &regs->tcd[ch].csr);
   380	}
   381	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 930ae268c497..9b12cb60c432 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -373,6 +373,9 @@  static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
 	edma_writel(edma, (s32)tcd->dlast_sga,
 			&regs->tcd[ch].dlast_sga);
 
+	if (fsl_chan->is_sw)
+		tcd->csr |= EDMA_TCD_CSR_START;
+
 	edma_writew(edma, (s16)tcd->csr, &regs->tcd[ch].csr);
 }
 
@@ -587,6 +590,29 @@  struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
 }
 EXPORT_SYMBOL_GPL(fsl_edma_prep_slave_sg);
 
+struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(
+		struct dma_chan *chan, dma_addr_t dma_dst,
+		dma_addr_t dma_src, size_t len, unsigned long flags)
+{
+	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+	struct fsl_edma_desc *fsl_desc;
+
+	fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
+	if (!fsl_desc)
+		return NULL;
+	fsl_desc->iscyclic = false;
+
+	fsl_chan->is_sw = true;
+
+	/* To match with copy_align and max_seg_size so 1 tcd is enough */
+	fsl_edma_fill_tcd(fsl_desc->tcd[0].vtcd, dma_src, dma_dst,
+			EDMA_TCD_ATTR_SSIZE_32BYTE | EDMA_TCD_ATTR_DSIZE_32BYTE,
+			32, len, 0, 1, 1, 32, 0, true, true, false);
+
+	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
+}
+EXPORT_SYMBOL_GPL(fsl_edma_prep_memcpy);
+
 void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
 {
 	struct virt_dma_desc *vdesc;
@@ -652,6 +678,7 @@  void fsl_edma_free_chan_resources(struct dma_chan *chan)
 	vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
 	dma_pool_destroy(fsl_chan->tcd_pool);
 	fsl_chan->tcd_pool = NULL;
+	fsl_chan->is_sw = false;
 }
 EXPORT_SYMBOL_GPL(fsl_edma_free_chan_resources);
 
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index ec1169741de1..004ec4a6bc86 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -121,6 +121,7 @@  struct fsl_edma_chan {
 	struct fsl_edma_desc		*edesc;
 	struct dma_slave_config		cfg;
 	u32				attr;
+	bool                            is_sw;
 	struct dma_pool			*tcd_pool;
 	dma_addr_t			dma_dev_addr;
 	u32				dma_dev_size;
@@ -240,6 +241,9 @@  struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
 		struct dma_chan *chan, struct scatterlist *sgl,
 		unsigned int sg_len, enum dma_transfer_direction direction,
 		unsigned long flags, void *context);
+struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(
+		struct dma_chan *chan, dma_addr_t dma_dst, dma_addr_t dma_src,
+		size_t len, unsigned long flags);
 void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan);
 void fsl_edma_issue_pending(struct dma_chan *chan);
 int fsl_edma_alloc_chan_resources(struct dma_chan *chan);
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 90bb72af306c..76cbf54aec58 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -17,6 +17,7 @@ 
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_dma.h>
+#include <linux/dma-mapping.h>
 
 #include "fsl-edma-common.h"
 
@@ -372,6 +373,7 @@  static int fsl_edma_probe(struct platform_device *pdev)
 	dma_cap_set(DMA_PRIVATE, fsl_edma->dma_dev.cap_mask);
 	dma_cap_set(DMA_SLAVE, fsl_edma->dma_dev.cap_mask);
 	dma_cap_set(DMA_CYCLIC, fsl_edma->dma_dev.cap_mask);
+	dma_cap_set(DMA_MEMCPY, fsl_edma->dma_dev.cap_mask);
 
 	fsl_edma->dma_dev.dev = &pdev->dev;
 	fsl_edma->dma_dev.device_alloc_chan_resources
@@ -381,6 +383,7 @@  static int fsl_edma_probe(struct platform_device *pdev)
 	fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
 	fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
 	fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
+	fsl_edma->dma_dev.device_prep_dma_memcpy = fsl_edma_prep_memcpy;
 	fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
 	fsl_edma->dma_dev.device_pause = fsl_edma_pause;
 	fsl_edma->dma_dev.device_resume = fsl_edma_resume;
@@ -392,6 +395,10 @@  static int fsl_edma_probe(struct platform_device *pdev)
 	fsl_edma->dma_dev.dst_addr_widths = FSL_EDMA_BUSWIDTHS;
 	fsl_edma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
 
+	fsl_edma->dma_dev.copy_align = DMAENGINE_ALIGN_32_BYTES;
+	/* Per worst case 'nbytes = 1' take CITER as the max_seg_size */
+	dma_set_max_seg_size(fsl_edma->dma_dev.dev, 0x3fff);
+
 	platform_set_drvdata(pdev, fsl_edma);
 
 	ret = dma_async_device_register(&fsl_edma->dma_dev);