On Mon, 2016-03-07 at 10:59 +0100, Boris Brezillon wrote: > Some drivers might need to tweak the block size and wait cycles > values > to get better performances. > Create and export the sun4i_dma_set_chan_config() to do that. > > Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxxxxxxx> > --- > drivers/dma/sun4i-dma.c | 44 ++++++++++++++++++++++++++++++--- > ---------- > include/linux/dma/sun4i-dma.h | 38 > +++++++++++++++++++++++++++++++++++++ > 2 files changed, 69 insertions(+), 13 deletions(-) > create mode 100644 include/linux/dma/sun4i-dma.h > > diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c > index 1661d518..e48f537 100644 > --- a/drivers/dma/sun4i-dma.c > +++ b/drivers/dma/sun4i-dma.c > @@ -12,6 +12,7 @@ > #include <linux/bitops.h> > #include <linux/clk.h> > #include <linux/dmaengine.h> > +#include <linux/dma/sun4i-dma.h> > #include <linux/dmapool.h> > #include <linux/interrupt.h> > #include <linux/module.h> > @@ -138,6 +139,7 @@ struct sun4i_dma_pchan { > struct sun4i_dma_vchan { > struct virt_dma_chan vc; > struct dma_slave_config cfg; > + struct sun4i_dma_chan_config scfg; > struct sun4i_dma_pchan *pchan; > struct sun4i_dma_promise *processing; > struct sun4i_dma_contract *contract; > @@ -779,7 +781,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, > struct scatterlist *sgl, > u8 ram_type, io_mode, linear_mode; > struct scatterlist *sg; > dma_addr_t srcaddr, dstaddr; > - u32 endpoints, para; > + u32 endpoints; > int i; > > if (!sgl) > @@ -825,17 +827,6 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, > struct scatterlist *sgl, > dstaddr = sg_dma_address(sg); > } > > - /* > - * These are the magic DMA engine timings that keep > SPI going. > - * I haven't seen any interface on DMAEngine to > configure > - * timings, and so far they seem to work for > everything we > - * support, so I've kept them here. I don't know if > other > - * devices need different timings because, as usual, > we only > - * have the "para" bitfield meanings, but no comment > on what > - * the values should be when doing a certain > operation :| > - */ > - para = SUN4I_DDMA_MAGIC_SPI_PARAMETERS; > - > /* And make a suitable promise */ > if (vchan->is_dedicated) > promise = generate_ddma_promise(chan, > srcaddr, dstaddr, > @@ -850,7 +841,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, > struct scatterlist *sgl, > return NULL; /* TODO: should we free > everything? */ > > promise->cfg |= endpoints; > - promise->para = para; > + promise->para = vchan->scfg.para; > > /* Then add it to the contract */ > list_add_tail(&promise->list, &contract->demands); > @@ -908,6 +899,21 @@ static int sun4i_dma_config(struct dma_chan > *chan, > return 0; > } > > +int sun4i_dma_set_chan_config(struct dma_chan *dchan, > + const struct sun4i_dma_chan_config > *cfg) > +{ > + struct sun4i_dma_vchan *vchan = to_sun4i_dma_vchan(dchan); > + > + if (!vchan->is_dedicated) > + return -ENOTSUPP; > + > + /* TODO: control cfg value */ > + vchan->scfg = *cfg; > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(sun4i_dma_set_chan_config); > + > static struct dma_chan *sun4i_dma_of_xlate(struct of_phandle_args > *dma_spec, > struct of_dma *ofdma) > { > @@ -1206,6 +1212,18 @@ static int sun4i_dma_probe(struct > platform_device *pdev) > spin_lock_init(&vchan->vc.lock); > vchan->vc.desc_free = sun4i_dma_free_contract; > vchan_init(&vchan->vc, &priv->slave); > + > + /* > + * These are the magic DMA engine timings that keep > SPI going. > + * I haven't seen any interface on DMAEngine to > configure > + * timings, and so far they seem to work for > everything we > + * support, so I've kept them here. I don't know if > other > + * devices need different timings because, as usual, > we only > + * have the "para" bitfield meanings, but no comment > on what > + * the values should be when doing a certain > operation :| > + */ > + vchan->scfg.para = SUN4I_DDMA_MAGIC_SPI_PARAMETERS; Does SPI refer the Serial Peripheral Interface? If yes, then I would point out that current sun4i SPI driver doesn't actually use DMA [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-February/411 722.html > + > } > > ret = clk_prepare_enable(priv->clk); > diff --git a/include/linux/dma/sun4i-dma.h b/include/linux/dma/sun4i > -dma.h > new file mode 100644 > index 0000000..f643539 > --- /dev/null > +++ b/include/linux/dma/sun4i-dma.h > @@ -0,0 +1,38 @@ > +/* > + * Sun4i DMA Engine drivers support header file > + * > + * Copyright (C) 2016 Free Electrons. All rights reserved. > + * > + * This is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published > by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#ifndef _SUN4I_DMA_H > +#define _SUN4I_DMA_H > + > +#include <linux/dma-mapping.h> > +#include <linux/dmaengine.h> > + > +/* Dedicated DMA parameter register layout */ > +#define SUN4I_DDMA_PARA_DST_DATA_BLK_SIZE(n) (((n) - 1) << > 24) > +#define SUN4I_DDMA_PARA_DST_WAIT_CYCLES(n) (((n) - 1) << 16) > +#define SUN4I_DDMA_PARA_SRC_DATA_BLK_SIZE(n) (((n) - 1) << 8) > +#define SUN4I_DDMA_PARA_SRC_WAIT_CYCLES(n) (((n) - 1) << 0) > + > +/** > + * struct sun4i_dma_chan_config - DMA channel config > + * > + * @para: contains information about block size and time before > checking > + * DRQ line. This is device specific and only applicable to > dedicated > + * DMA channels > + */ > +struct sun4i_dma_chan_config { > + u32 para; > +}; > + > +int sun4i_dma_set_chan_config(struct dma_chan *dchan, > + const struct sun4i_dma_chan_config > *cfg); > + > +#endif /* _SUN4I_DMA_H */ > -- > 2.1.4 > -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html