Re: [PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-07 Thread Baolin Wang
On 5 May 2018 at 13:54, kbuild test robot  wrote:
> Hi Eric,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on slave-dma/next]
> [also build test WARNING on next-20180504]
> [cannot apply to linus/master v4.17-rc3]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Baolin-Wang/dmaengine-sprd-Optimize-the-sprd_dma_prep_dma_memcpy/20180505-071137
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git 
> next
> reproduce:
> # apt-get install sparse
> make ARCH=x86_64 allmodconfig
> make C=1 CF=-D__CHECK_ENDIAN__
>
>
> sparse warnings: (new ones prefixed by >>)
>
>>> drivers/dma/sprd-dma.c:780:57: sparse: mixing different enum types
>drivers/dma/sprd-dma.c:780:57: int enum dma_slave_buswidth  versus
>drivers/dma/sprd-dma.c:780:57: int enum sprd_dma_datawidth
>drivers/dma/sprd-dma.c:787:57: sparse: mixing different enum types
>drivers/dma/sprd-dma.c:787:57: int enum dma_slave_buswidth  versus
>drivers/dma/sprd-dma.c:787:57: int enum sprd_dma_datawidth
>
> vim +780 drivers/dma/sprd-dma.c

Sorry, It's one mistake. Eric will fix it in next version.

-- 
Baolin.wang
Best Regards


Re: [PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-07 Thread Baolin Wang
On 5 May 2018 at 13:54, kbuild test robot  wrote:
> Hi Eric,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on slave-dma/next]
> [also build test WARNING on next-20180504]
> [cannot apply to linus/master v4.17-rc3]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Baolin-Wang/dmaengine-sprd-Optimize-the-sprd_dma_prep_dma_memcpy/20180505-071137
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git 
> next
> reproduce:
> # apt-get install sparse
> make ARCH=x86_64 allmodconfig
> make C=1 CF=-D__CHECK_ENDIAN__
>
>
> sparse warnings: (new ones prefixed by >>)
>
>>> drivers/dma/sprd-dma.c:780:57: sparse: mixing different enum types
>drivers/dma/sprd-dma.c:780:57: int enum dma_slave_buswidth  versus
>drivers/dma/sprd-dma.c:780:57: int enum sprd_dma_datawidth
>drivers/dma/sprd-dma.c:787:57: sparse: mixing different enum types
>drivers/dma/sprd-dma.c:787:57: int enum dma_slave_buswidth  versus
>drivers/dma/sprd-dma.c:787:57: int enum sprd_dma_datawidth
>
> vim +780 drivers/dma/sprd-dma.c

Sorry, It's one mistake. Eric will fix it in next version.

-- 
Baolin.wang
Best Regards


Re: [PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-04 Thread kbuild test robot
Hi Eric,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on slave-dma/next]
[also build test WARNING on next-20180504]
[cannot apply to linus/master v4.17-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Baolin-Wang/dmaengine-sprd-Optimize-the-sprd_dma_prep_dma_memcpy/20180505-071137
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/dma/sprd-dma.c:780:57: sparse: mixing different enum types
   drivers/dma/sprd-dma.c:780:57: int enum dma_slave_buswidth  versus
   drivers/dma/sprd-dma.c:780:57: int enum sprd_dma_datawidth
   drivers/dma/sprd-dma.c:787:57: sparse: mixing different enum types
   drivers/dma/sprd-dma.c:787:57: int enum dma_slave_buswidth  versus
   drivers/dma/sprd-dma.c:787:57: int enum sprd_dma_datawidth

vim +780 drivers/dma/sprd-dma.c

   755  
   756  static struct dma_async_tx_descriptor *
   757  sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
   758 unsigned int sglen, enum dma_transfer_direction 
dir,
   759 unsigned long flags, void *context)
   760  {
   761  struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
   762  struct sprd_dma_config *slave_cfg = >slave_cfg;
   763  struct sprd_dma_desc *sdesc;
   764  struct scatterlist *sg;
   765  int ret, i;
   766  
   767  /* TODO: now we only support one sg for each DMA configuration. 
*/
   768  if (!is_slave_direction(dir) || sglen > 1)
   769  return NULL;
   770  
   771  sdesc = kzalloc(sizeof(*sdesc), GFP_NOWAIT);
   772  if (!sdesc)
   773  return NULL;
   774  
   775  for_each_sg(sgl, sg, sglen, i) {
   776  if (dir == DMA_MEM_TO_DEV) {
   777  slave_cfg->src_addr = sg_dma_address(sg);
   778  slave_cfg->dst_addr = slave_cfg->cfg.dst_addr;
   779  slave_cfg->src_step =
 > 780  
 > sprd_dma_get_step(slave_cfg->cfg.src_addr_width);
   781  slave_cfg->dst_step = SPRD_DMA_NONE_STEP;
   782  } else {
   783  slave_cfg->src_addr = slave_cfg->cfg.src_addr;
   784  slave_cfg->dst_addr = sg_dma_address(sg);
   785  slave_cfg->src_step = SPRD_DMA_NONE_STEP;
   786  slave_cfg->dst_step =
   787  
sprd_dma_get_step(slave_cfg->cfg.dst_addr_width);
   788  }
   789  
   790  slave_cfg->block_len = sg_dma_len(sg);
   791  slave_cfg->transcation_len = sg_dma_len(sg);
   792  }
   793  
   794  slave_cfg->req_mode =
   795  (flags >> SPRD_DMA_REQ_SHIFT) & SPRD_DMA_REQ_MODE_MASK;
   796  slave_cfg->int_mode = flags & SPRD_DMA_INT_MASK;
   797  
   798  ret = sprd_dma_config(chan, sdesc, slave_cfg);
   799  if (ret) {
   800  kfree(sdesc);
   801  return NULL;
   802  }
   803  
   804  return vchan_tx_prep(>vc, >vd, flags);
   805  }
   806  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


Re: [PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-04 Thread kbuild test robot
Hi Eric,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on slave-dma/next]
[also build test WARNING on next-20180504]
[cannot apply to linus/master v4.17-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Baolin-Wang/dmaengine-sprd-Optimize-the-sprd_dma_prep_dma_memcpy/20180505-071137
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/dma/sprd-dma.c:780:57: sparse: mixing different enum types
   drivers/dma/sprd-dma.c:780:57: int enum dma_slave_buswidth  versus
   drivers/dma/sprd-dma.c:780:57: int enum sprd_dma_datawidth
   drivers/dma/sprd-dma.c:787:57: sparse: mixing different enum types
   drivers/dma/sprd-dma.c:787:57: int enum dma_slave_buswidth  versus
   drivers/dma/sprd-dma.c:787:57: int enum sprd_dma_datawidth

vim +780 drivers/dma/sprd-dma.c

   755  
   756  static struct dma_async_tx_descriptor *
   757  sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
   758 unsigned int sglen, enum dma_transfer_direction 
dir,
   759 unsigned long flags, void *context)
   760  {
   761  struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
   762  struct sprd_dma_config *slave_cfg = >slave_cfg;
   763  struct sprd_dma_desc *sdesc;
   764  struct scatterlist *sg;
   765  int ret, i;
   766  
   767  /* TODO: now we only support one sg for each DMA configuration. 
*/
   768  if (!is_slave_direction(dir) || sglen > 1)
   769  return NULL;
   770  
   771  sdesc = kzalloc(sizeof(*sdesc), GFP_NOWAIT);
   772  if (!sdesc)
   773  return NULL;
   774  
   775  for_each_sg(sgl, sg, sglen, i) {
   776  if (dir == DMA_MEM_TO_DEV) {
   777  slave_cfg->src_addr = sg_dma_address(sg);
   778  slave_cfg->dst_addr = slave_cfg->cfg.dst_addr;
   779  slave_cfg->src_step =
 > 780  
 > sprd_dma_get_step(slave_cfg->cfg.src_addr_width);
   781  slave_cfg->dst_step = SPRD_DMA_NONE_STEP;
   782  } else {
   783  slave_cfg->src_addr = slave_cfg->cfg.src_addr;
   784  slave_cfg->dst_addr = sg_dma_address(sg);
   785  slave_cfg->src_step = SPRD_DMA_NONE_STEP;
   786  slave_cfg->dst_step =
   787  
sprd_dma_get_step(slave_cfg->cfg.dst_addr_width);
   788  }
   789  
   790  slave_cfg->block_len = sg_dma_len(sg);
   791  slave_cfg->transcation_len = sg_dma_len(sg);
   792  }
   793  
   794  slave_cfg->req_mode =
   795  (flags >> SPRD_DMA_REQ_SHIFT) & SPRD_DMA_REQ_MODE_MASK;
   796  slave_cfg->int_mode = flags & SPRD_DMA_INT_MASK;
   797  
   798  ret = sprd_dma_config(chan, sdesc, slave_cfg);
   799  if (ret) {
   800  kfree(sdesc);
   801  return NULL;
   802  }
   803  
   804  return vchan_tx_prep(>vc, >vd, flags);
   805  }
   806  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


Re: [PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-04 Thread Baolin Wang
Add Vinod new email.

On 4 May 2018 at 16:01, Baolin Wang  wrote:
> From: Eric Long 
>
> This patch adds the 'device_config' and 'device_prep_slave_sg' interfaces
> for users to configure DMA, as well as adding one 'struct sprd_dma_config'
> structure to save Spreadtrum DMA configuration for each DMA channel.
>
> Signed-off-by: Eric Long 
> Signed-off-by: Baolin Wang 
> ---
>  drivers/dma/sprd-dma.c   |  215 
> ++
>  include/linux/dma/sprd-dma.h |4 +
>  2 files changed, 219 insertions(+)
>
> diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
> index a7a89fd..d7c7ffa 100644
> --- a/drivers/dma/sprd-dma.c
> +++ b/drivers/dma/sprd-dma.c
> @@ -100,6 +100,8 @@
>  #define SPRD_DMA_DES_DATAWIDTH_OFFSET  28
>  #define SPRD_DMA_SWT_MODE_OFFSET   26
>  #define SPRD_DMA_REQ_MODE_OFFSET   24
> +#define SPRD_DMA_WRAP_SEL_OFFSET   23
> +#define SPRD_DMA_WRAP_EN_OFFSET22
>  #define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0)
>  #define SPRD_DMA_FIX_SEL_OFFSET21
>  #define SPRD_DMA_FIX_EN_OFFSET 20
> @@ -154,6 +156,35 @@ struct sprd_dma_chn_hw {
> u32 des_blk_step;
>  };
>
> +/*
> + * struct sprd_dma_config - DMA configuration structure
> + * @cfg: dma slave channel runtime config
> + * @src_addr: the source physical address
> + * @dst_addr: the destination physical address
> + * @block_len: specify one block transfer length
> + * @transcation_len: specify one transcation transfer length
> + * @src_step: source transfer step
> + * @dst_step: destination transfer step
> + * @wrap_ptr: wrap pointer address, once the transfer address reaches the
> + * 'wrap_ptr', the next transfer address will jump to the 'wrap_to' address.
> + * @wrap_to: wrap jump to address
> + * @req_mode: specify the DMA request mode
> + * @int_mode: specify the DMA interrupt type
> + */
> +struct sprd_dma_config {
> +   struct dma_slave_config cfg;
> +   phys_addr_t src_addr;
> +   phys_addr_t dst_addr;
> +   u32 block_len;
> +   u32 transcation_len;
> +   u32 src_step;
> +   u32 dst_step;
> +   phys_addr_t wrap_ptr;
> +   phys_addr_t wrap_to;
> +   enum sprd_dma_req_mode req_mode;
> +   enum sprd_dma_int_type int_mode;
> +};
> +
>  /* dma request description */
>  struct sprd_dma_desc {
> struct virt_dma_descvd;
> @@ -164,6 +195,7 @@ struct sprd_dma_desc {
>  struct sprd_dma_chn {
> struct virt_dma_chanvc;
> void __iomem*chn_base;
> +   struct sprd_dma_config  slave_cfg;
> u32 chn_num;
> u32 dev_id;
> struct sprd_dma_desc*cur_desc;
> @@ -552,6 +584,121 @@ static void sprd_dma_issue_pending(struct dma_chan 
> *chan)
> spin_unlock_irqrestore(>vc.lock, flags);
>  }
>
> +static enum sprd_dma_datawidth
> +sprd_dma_get_datawidth(enum dma_slave_buswidth buswidth)
> +{
> +   switch (buswidth) {
> +   case DMA_SLAVE_BUSWIDTH_1_BYTE:
> +   return SPRD_DMA_DATAWIDTH_1_BYTE;
> +
> +   case DMA_SLAVE_BUSWIDTH_2_BYTES:
> +   return SPRD_DMA_DATAWIDTH_2_BYTES;
> +
> +   case DMA_SLAVE_BUSWIDTH_4_BYTES:
> +   return SPRD_DMA_DATAWIDTH_4_BYTES;
> +
> +   case DMA_SLAVE_BUSWIDTH_8_BYTES:
> +   return SPRD_DMA_DATAWIDTH_8_BYTES;
> +
> +   default:
> +   return SPRD_DMA_DATAWIDTH_4_BYTES;
> +   }
> +}
> +
> +static u32 sprd_dma_get_step(enum sprd_dma_datawidth datawidth)
> +{
> +   switch (datawidth) {
> +   case SPRD_DMA_DATAWIDTH_1_BYTE:
> +   return SPRD_DMA_BYTE_STEP;
> +
> +   case SPRD_DMA_DATAWIDTH_2_BYTES:
> +   return SPRD_DMA_SHORT_STEP;
> +
> +   case SPRD_DMA_DATAWIDTH_4_BYTES:
> +   return SPRD_DMA_WORD_STEP;
> +
> +   case SPRD_DMA_DATAWIDTH_8_BYTES:
> +   return SPRD_DMA_DWORD_STEP;
> +
> +   default:
> +   return SPRD_DMA_DWORD_STEP;
> +   }
> +}
> +
> +static int sprd_dma_config(struct dma_chan *chan, struct sprd_dma_desc 
> *sdesc,
> +  struct sprd_dma_config *slave_cfg)
> +{
> +   struct sprd_dma_dev *sdev = to_sprd_dma_dev(chan);
> +   struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
> +   struct sprd_dma_chn_hw *hw = >chn_hw;
> +   u32 fix_mode = 0, fix_en = 0, wrap_en = 0, wrap_mode = 0;
> +   u32 src_datawidth, dst_datawidth;
> +
> +   if (slave_cfg->cfg.slave_id)
> +   schan->dev_id = slave_cfg->cfg.slave_id;
> +
> +   hw->cfg = SPRD_DMA_DONOT_WAIT_BDONE << SPRD_DMA_WAIT_BDONE_OFFSET;
> +   hw->wrap_ptr = (u32)((slave_cfg->wrap_ptr & SPRD_DMA_LOW_ADDR_MASK) |
> +   ((slave_cfg->src_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &
> +SPRD_DMA_HIGH_ADDR_MASK));
> +   hw->wrap_to = (u32)((slave_cfg->wrap_to 

Re: [PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-04 Thread Baolin Wang
Add Vinod new email.

On 4 May 2018 at 16:01, Baolin Wang  wrote:
> From: Eric Long 
>
> This patch adds the 'device_config' and 'device_prep_slave_sg' interfaces
> for users to configure DMA, as well as adding one 'struct sprd_dma_config'
> structure to save Spreadtrum DMA configuration for each DMA channel.
>
> Signed-off-by: Eric Long 
> Signed-off-by: Baolin Wang 
> ---
>  drivers/dma/sprd-dma.c   |  215 
> ++
>  include/linux/dma/sprd-dma.h |4 +
>  2 files changed, 219 insertions(+)
>
> diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
> index a7a89fd..d7c7ffa 100644
> --- a/drivers/dma/sprd-dma.c
> +++ b/drivers/dma/sprd-dma.c
> @@ -100,6 +100,8 @@
>  #define SPRD_DMA_DES_DATAWIDTH_OFFSET  28
>  #define SPRD_DMA_SWT_MODE_OFFSET   26
>  #define SPRD_DMA_REQ_MODE_OFFSET   24
> +#define SPRD_DMA_WRAP_SEL_OFFSET   23
> +#define SPRD_DMA_WRAP_EN_OFFSET22
>  #define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0)
>  #define SPRD_DMA_FIX_SEL_OFFSET21
>  #define SPRD_DMA_FIX_EN_OFFSET 20
> @@ -154,6 +156,35 @@ struct sprd_dma_chn_hw {
> u32 des_blk_step;
>  };
>
> +/*
> + * struct sprd_dma_config - DMA configuration structure
> + * @cfg: dma slave channel runtime config
> + * @src_addr: the source physical address
> + * @dst_addr: the destination physical address
> + * @block_len: specify one block transfer length
> + * @transcation_len: specify one transcation transfer length
> + * @src_step: source transfer step
> + * @dst_step: destination transfer step
> + * @wrap_ptr: wrap pointer address, once the transfer address reaches the
> + * 'wrap_ptr', the next transfer address will jump to the 'wrap_to' address.
> + * @wrap_to: wrap jump to address
> + * @req_mode: specify the DMA request mode
> + * @int_mode: specify the DMA interrupt type
> + */
> +struct sprd_dma_config {
> +   struct dma_slave_config cfg;
> +   phys_addr_t src_addr;
> +   phys_addr_t dst_addr;
> +   u32 block_len;
> +   u32 transcation_len;
> +   u32 src_step;
> +   u32 dst_step;
> +   phys_addr_t wrap_ptr;
> +   phys_addr_t wrap_to;
> +   enum sprd_dma_req_mode req_mode;
> +   enum sprd_dma_int_type int_mode;
> +};
> +
>  /* dma request description */
>  struct sprd_dma_desc {
> struct virt_dma_descvd;
> @@ -164,6 +195,7 @@ struct sprd_dma_desc {
>  struct sprd_dma_chn {
> struct virt_dma_chanvc;
> void __iomem*chn_base;
> +   struct sprd_dma_config  slave_cfg;
> u32 chn_num;
> u32 dev_id;
> struct sprd_dma_desc*cur_desc;
> @@ -552,6 +584,121 @@ static void sprd_dma_issue_pending(struct dma_chan 
> *chan)
> spin_unlock_irqrestore(>vc.lock, flags);
>  }
>
> +static enum sprd_dma_datawidth
> +sprd_dma_get_datawidth(enum dma_slave_buswidth buswidth)
> +{
> +   switch (buswidth) {
> +   case DMA_SLAVE_BUSWIDTH_1_BYTE:
> +   return SPRD_DMA_DATAWIDTH_1_BYTE;
> +
> +   case DMA_SLAVE_BUSWIDTH_2_BYTES:
> +   return SPRD_DMA_DATAWIDTH_2_BYTES;
> +
> +   case DMA_SLAVE_BUSWIDTH_4_BYTES:
> +   return SPRD_DMA_DATAWIDTH_4_BYTES;
> +
> +   case DMA_SLAVE_BUSWIDTH_8_BYTES:
> +   return SPRD_DMA_DATAWIDTH_8_BYTES;
> +
> +   default:
> +   return SPRD_DMA_DATAWIDTH_4_BYTES;
> +   }
> +}
> +
> +static u32 sprd_dma_get_step(enum sprd_dma_datawidth datawidth)
> +{
> +   switch (datawidth) {
> +   case SPRD_DMA_DATAWIDTH_1_BYTE:
> +   return SPRD_DMA_BYTE_STEP;
> +
> +   case SPRD_DMA_DATAWIDTH_2_BYTES:
> +   return SPRD_DMA_SHORT_STEP;
> +
> +   case SPRD_DMA_DATAWIDTH_4_BYTES:
> +   return SPRD_DMA_WORD_STEP;
> +
> +   case SPRD_DMA_DATAWIDTH_8_BYTES:
> +   return SPRD_DMA_DWORD_STEP;
> +
> +   default:
> +   return SPRD_DMA_DWORD_STEP;
> +   }
> +}
> +
> +static int sprd_dma_config(struct dma_chan *chan, struct sprd_dma_desc 
> *sdesc,
> +  struct sprd_dma_config *slave_cfg)
> +{
> +   struct sprd_dma_dev *sdev = to_sprd_dma_dev(chan);
> +   struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
> +   struct sprd_dma_chn_hw *hw = >chn_hw;
> +   u32 fix_mode = 0, fix_en = 0, wrap_en = 0, wrap_mode = 0;
> +   u32 src_datawidth, dst_datawidth;
> +
> +   if (slave_cfg->cfg.slave_id)
> +   schan->dev_id = slave_cfg->cfg.slave_id;
> +
> +   hw->cfg = SPRD_DMA_DONOT_WAIT_BDONE << SPRD_DMA_WAIT_BDONE_OFFSET;
> +   hw->wrap_ptr = (u32)((slave_cfg->wrap_ptr & SPRD_DMA_LOW_ADDR_MASK) |
> +   ((slave_cfg->src_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &
> +SPRD_DMA_HIGH_ADDR_MASK));
> +   hw->wrap_to = (u32)((slave_cfg->wrap_to & SPRD_DMA_LOW_ADDR_MASK) |
> +   ((slave_cfg->dst_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &

[PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-04 Thread Baolin Wang
From: Eric Long 

This patch adds the 'device_config' and 'device_prep_slave_sg' interfaces
for users to configure DMA, as well as adding one 'struct sprd_dma_config'
structure to save Spreadtrum DMA configuration for each DMA channel.

Signed-off-by: Eric Long 
Signed-off-by: Baolin Wang 
---
 drivers/dma/sprd-dma.c   |  215 ++
 include/linux/dma/sprd-dma.h |4 +
 2 files changed, 219 insertions(+)

diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
index a7a89fd..d7c7ffa 100644
--- a/drivers/dma/sprd-dma.c
+++ b/drivers/dma/sprd-dma.c
@@ -100,6 +100,8 @@
 #define SPRD_DMA_DES_DATAWIDTH_OFFSET  28
 #define SPRD_DMA_SWT_MODE_OFFSET   26
 #define SPRD_DMA_REQ_MODE_OFFSET   24
+#define SPRD_DMA_WRAP_SEL_OFFSET   23
+#define SPRD_DMA_WRAP_EN_OFFSET22
 #define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0)
 #define SPRD_DMA_FIX_SEL_OFFSET21
 #define SPRD_DMA_FIX_EN_OFFSET 20
@@ -154,6 +156,35 @@ struct sprd_dma_chn_hw {
u32 des_blk_step;
 };
 
+/*
+ * struct sprd_dma_config - DMA configuration structure
+ * @cfg: dma slave channel runtime config
+ * @src_addr: the source physical address
+ * @dst_addr: the destination physical address
+ * @block_len: specify one block transfer length
+ * @transcation_len: specify one transcation transfer length
+ * @src_step: source transfer step
+ * @dst_step: destination transfer step
+ * @wrap_ptr: wrap pointer address, once the transfer address reaches the
+ * 'wrap_ptr', the next transfer address will jump to the 'wrap_to' address.
+ * @wrap_to: wrap jump to address
+ * @req_mode: specify the DMA request mode
+ * @int_mode: specify the DMA interrupt type
+ */
+struct sprd_dma_config {
+   struct dma_slave_config cfg;
+   phys_addr_t src_addr;
+   phys_addr_t dst_addr;
+   u32 block_len;
+   u32 transcation_len;
+   u32 src_step;
+   u32 dst_step;
+   phys_addr_t wrap_ptr;
+   phys_addr_t wrap_to;
+   enum sprd_dma_req_mode req_mode;
+   enum sprd_dma_int_type int_mode;
+};
+
 /* dma request description */
 struct sprd_dma_desc {
struct virt_dma_descvd;
@@ -164,6 +195,7 @@ struct sprd_dma_desc {
 struct sprd_dma_chn {
struct virt_dma_chanvc;
void __iomem*chn_base;
+   struct sprd_dma_config  slave_cfg;
u32 chn_num;
u32 dev_id;
struct sprd_dma_desc*cur_desc;
@@ -552,6 +584,121 @@ static void sprd_dma_issue_pending(struct dma_chan *chan)
spin_unlock_irqrestore(>vc.lock, flags);
 }
 
+static enum sprd_dma_datawidth
+sprd_dma_get_datawidth(enum dma_slave_buswidth buswidth)
+{
+   switch (buswidth) {
+   case DMA_SLAVE_BUSWIDTH_1_BYTE:
+   return SPRD_DMA_DATAWIDTH_1_BYTE;
+
+   case DMA_SLAVE_BUSWIDTH_2_BYTES:
+   return SPRD_DMA_DATAWIDTH_2_BYTES;
+
+   case DMA_SLAVE_BUSWIDTH_4_BYTES:
+   return SPRD_DMA_DATAWIDTH_4_BYTES;
+
+   case DMA_SLAVE_BUSWIDTH_8_BYTES:
+   return SPRD_DMA_DATAWIDTH_8_BYTES;
+
+   default:
+   return SPRD_DMA_DATAWIDTH_4_BYTES;
+   }
+}
+
+static u32 sprd_dma_get_step(enum sprd_dma_datawidth datawidth)
+{
+   switch (datawidth) {
+   case SPRD_DMA_DATAWIDTH_1_BYTE:
+   return SPRD_DMA_BYTE_STEP;
+
+   case SPRD_DMA_DATAWIDTH_2_BYTES:
+   return SPRD_DMA_SHORT_STEP;
+
+   case SPRD_DMA_DATAWIDTH_4_BYTES:
+   return SPRD_DMA_WORD_STEP;
+
+   case SPRD_DMA_DATAWIDTH_8_BYTES:
+   return SPRD_DMA_DWORD_STEP;
+
+   default:
+   return SPRD_DMA_DWORD_STEP;
+   }
+}
+
+static int sprd_dma_config(struct dma_chan *chan, struct sprd_dma_desc *sdesc,
+  struct sprd_dma_config *slave_cfg)
+{
+   struct sprd_dma_dev *sdev = to_sprd_dma_dev(chan);
+   struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
+   struct sprd_dma_chn_hw *hw = >chn_hw;
+   u32 fix_mode = 0, fix_en = 0, wrap_en = 0, wrap_mode = 0;
+   u32 src_datawidth, dst_datawidth;
+
+   if (slave_cfg->cfg.slave_id)
+   schan->dev_id = slave_cfg->cfg.slave_id;
+
+   hw->cfg = SPRD_DMA_DONOT_WAIT_BDONE << SPRD_DMA_WAIT_BDONE_OFFSET;
+   hw->wrap_ptr = (u32)((slave_cfg->wrap_ptr & SPRD_DMA_LOW_ADDR_MASK) |
+   ((slave_cfg->src_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &
+SPRD_DMA_HIGH_ADDR_MASK));
+   hw->wrap_to = (u32)((slave_cfg->wrap_to & SPRD_DMA_LOW_ADDR_MASK) |
+   ((slave_cfg->dst_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &
+SPRD_DMA_HIGH_ADDR_MASK));
+
+   hw->src_addr = (u32)(slave_cfg->src_addr & SPRD_DMA_LOW_ADDR_MASK);
+   hw->des_addr = (u32)(slave_cfg->dst_addr & SPRD_DMA_LOW_ADDR_MASK);
+
+   if ((slave_cfg->src_step != 0 && 

[PATCH 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration

2018-05-04 Thread Baolin Wang
From: Eric Long 

This patch adds the 'device_config' and 'device_prep_slave_sg' interfaces
for users to configure DMA, as well as adding one 'struct sprd_dma_config'
structure to save Spreadtrum DMA configuration for each DMA channel.

Signed-off-by: Eric Long 
Signed-off-by: Baolin Wang 
---
 drivers/dma/sprd-dma.c   |  215 ++
 include/linux/dma/sprd-dma.h |4 +
 2 files changed, 219 insertions(+)

diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
index a7a89fd..d7c7ffa 100644
--- a/drivers/dma/sprd-dma.c
+++ b/drivers/dma/sprd-dma.c
@@ -100,6 +100,8 @@
 #define SPRD_DMA_DES_DATAWIDTH_OFFSET  28
 #define SPRD_DMA_SWT_MODE_OFFSET   26
 #define SPRD_DMA_REQ_MODE_OFFSET   24
+#define SPRD_DMA_WRAP_SEL_OFFSET   23
+#define SPRD_DMA_WRAP_EN_OFFSET22
 #define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0)
 #define SPRD_DMA_FIX_SEL_OFFSET21
 #define SPRD_DMA_FIX_EN_OFFSET 20
@@ -154,6 +156,35 @@ struct sprd_dma_chn_hw {
u32 des_blk_step;
 };
 
+/*
+ * struct sprd_dma_config - DMA configuration structure
+ * @cfg: dma slave channel runtime config
+ * @src_addr: the source physical address
+ * @dst_addr: the destination physical address
+ * @block_len: specify one block transfer length
+ * @transcation_len: specify one transcation transfer length
+ * @src_step: source transfer step
+ * @dst_step: destination transfer step
+ * @wrap_ptr: wrap pointer address, once the transfer address reaches the
+ * 'wrap_ptr', the next transfer address will jump to the 'wrap_to' address.
+ * @wrap_to: wrap jump to address
+ * @req_mode: specify the DMA request mode
+ * @int_mode: specify the DMA interrupt type
+ */
+struct sprd_dma_config {
+   struct dma_slave_config cfg;
+   phys_addr_t src_addr;
+   phys_addr_t dst_addr;
+   u32 block_len;
+   u32 transcation_len;
+   u32 src_step;
+   u32 dst_step;
+   phys_addr_t wrap_ptr;
+   phys_addr_t wrap_to;
+   enum sprd_dma_req_mode req_mode;
+   enum sprd_dma_int_type int_mode;
+};
+
 /* dma request description */
 struct sprd_dma_desc {
struct virt_dma_descvd;
@@ -164,6 +195,7 @@ struct sprd_dma_desc {
 struct sprd_dma_chn {
struct virt_dma_chanvc;
void __iomem*chn_base;
+   struct sprd_dma_config  slave_cfg;
u32 chn_num;
u32 dev_id;
struct sprd_dma_desc*cur_desc;
@@ -552,6 +584,121 @@ static void sprd_dma_issue_pending(struct dma_chan *chan)
spin_unlock_irqrestore(>vc.lock, flags);
 }
 
+static enum sprd_dma_datawidth
+sprd_dma_get_datawidth(enum dma_slave_buswidth buswidth)
+{
+   switch (buswidth) {
+   case DMA_SLAVE_BUSWIDTH_1_BYTE:
+   return SPRD_DMA_DATAWIDTH_1_BYTE;
+
+   case DMA_SLAVE_BUSWIDTH_2_BYTES:
+   return SPRD_DMA_DATAWIDTH_2_BYTES;
+
+   case DMA_SLAVE_BUSWIDTH_4_BYTES:
+   return SPRD_DMA_DATAWIDTH_4_BYTES;
+
+   case DMA_SLAVE_BUSWIDTH_8_BYTES:
+   return SPRD_DMA_DATAWIDTH_8_BYTES;
+
+   default:
+   return SPRD_DMA_DATAWIDTH_4_BYTES;
+   }
+}
+
+static u32 sprd_dma_get_step(enum sprd_dma_datawidth datawidth)
+{
+   switch (datawidth) {
+   case SPRD_DMA_DATAWIDTH_1_BYTE:
+   return SPRD_DMA_BYTE_STEP;
+
+   case SPRD_DMA_DATAWIDTH_2_BYTES:
+   return SPRD_DMA_SHORT_STEP;
+
+   case SPRD_DMA_DATAWIDTH_4_BYTES:
+   return SPRD_DMA_WORD_STEP;
+
+   case SPRD_DMA_DATAWIDTH_8_BYTES:
+   return SPRD_DMA_DWORD_STEP;
+
+   default:
+   return SPRD_DMA_DWORD_STEP;
+   }
+}
+
+static int sprd_dma_config(struct dma_chan *chan, struct sprd_dma_desc *sdesc,
+  struct sprd_dma_config *slave_cfg)
+{
+   struct sprd_dma_dev *sdev = to_sprd_dma_dev(chan);
+   struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
+   struct sprd_dma_chn_hw *hw = >chn_hw;
+   u32 fix_mode = 0, fix_en = 0, wrap_en = 0, wrap_mode = 0;
+   u32 src_datawidth, dst_datawidth;
+
+   if (slave_cfg->cfg.slave_id)
+   schan->dev_id = slave_cfg->cfg.slave_id;
+
+   hw->cfg = SPRD_DMA_DONOT_WAIT_BDONE << SPRD_DMA_WAIT_BDONE_OFFSET;
+   hw->wrap_ptr = (u32)((slave_cfg->wrap_ptr & SPRD_DMA_LOW_ADDR_MASK) |
+   ((slave_cfg->src_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &
+SPRD_DMA_HIGH_ADDR_MASK));
+   hw->wrap_to = (u32)((slave_cfg->wrap_to & SPRD_DMA_LOW_ADDR_MASK) |
+   ((slave_cfg->dst_addr >> SPRD_DMA_HIGH_ADDR_OFFSET) &
+SPRD_DMA_HIGH_ADDR_MASK));
+
+   hw->src_addr = (u32)(slave_cfg->src_addr & SPRD_DMA_LOW_ADDR_MASK);
+   hw->des_addr = (u32)(slave_cfg->dst_addr & SPRD_DMA_LOW_ADDR_MASK);
+
+   if ((slave_cfg->src_step != 0 && slave_cfg->dst_step != 0)
+   || (slave_cfg->src_step | slave_cfg->dst_step) == 0) {