Re: [PATCH] dmaengine: fsl-edma: dma map slave device address

2019-02-03 Thread Vinod Koul
On 18-01-19, 12:06, Laurentiu Tudor wrote:
> This mapping needs to be created in order for slave dma transfers
> to work on systems with SMMU. The implementation mostly mimics the
> one in pl330 dma driver, authored by Robin Murphy.

Applied, thanks

-- 
~Vinod
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] dmaengine: fsl-edma: dma map slave device address

2019-01-21 Thread Laurentiu Tudor
Hi Angelo,

On 18.01.2019 23:50, Angelo Dureghello wrote:
> Hi Laurentiu,
> 
> On Fri, Jan 18, 2019 at 12:06:23PM +0200, Laurentiu Tudor wrote:
>> This mapping needs to be created in order for slave dma transfers
>> to work on systems with SMMU. The implementation mostly mimics the
>> one in pl330 dma driver, authored by Robin Murphy.
>>
>> Signed-off-by: Laurentiu Tudor 
>> Suggested-by: Robin Murphy 
>> ---
>> Original approach was to add the missing mappings in the i2c client driver,
>> see here for discussion: 
>> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.ozlabs.org%2Fpatch%2F1026013%2Fdata=02%7C01%7Claurentiu.tudor%40nxp.com%7C7861dfe95dfb4fceeb8208d67d907488%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C1%7C636834456718898365sdata=XM5shQdcIRgFLtCmuRuFtViR6ttPDWI%2BNHXoPi68Xs8%3Dreserved=0
>>
>>   drivers/dma/fsl-edma-common.c | 66 ---
>>   drivers/dma/fsl-edma-common.h |  4 +++
>>   drivers/dma/fsl-edma.c|  1 +
>>   drivers/dma/mcf-edma.c|  1 +
>>   4 files changed, 68 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
>> index 8876c4c1bb2c..0e95ee24b6d4 100644
>> --- a/drivers/dma/fsl-edma-common.c
>> +++ b/drivers/dma/fsl-edma-common.c
>> @@ -6,6 +6,7 @@
>>   #include 
>>   #include 
>>   #include 
>> +#include 
>>   
>>   #include "fsl-edma-common.h"
>>   
>> @@ -173,12 +174,62 @@ int fsl_edma_resume(struct dma_chan *chan)
>>   }
>>   EXPORT_SYMBOL_GPL(fsl_edma_resume);
>>   
>> +static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan)
>> +{
>> +if (fsl_chan->dma_dir != DMA_NONE)
>> +dma_unmap_resource(fsl_chan->vchan.chan.device->dev,
>> +   fsl_chan->dma_dev_addr,
>> +   fsl_chan->dma_dev_size,
>> +   fsl_chan->dma_dir, 0);
>> +fsl_chan->dma_dir = DMA_NONE;
>> +}
>> +
>> +static bool fsl_edma_prep_slave_dma(struct fsl_edma_chan *fsl_chan,
>> +enum dma_transfer_direction dir)
>> +{
>> +struct device *dev = fsl_chan->vchan.chan.device->dev;
>> +enum dma_data_direction dma_dir;
>> +phys_addr_t addr = 0;
>> +u32 size = 0;
>> +
>> +switch (dir) {
>> +case DMA_MEM_TO_DEV:
>> +dma_dir = DMA_FROM_DEVICE;
>> +addr = fsl_chan->cfg.dst_addr;
>> +size = fsl_chan->cfg.dst_maxburst;
>> +break;
>> +case DMA_DEV_TO_MEM:
>> +dma_dir = DMA_TO_DEVICE;
>> +addr = fsl_chan->cfg.src_addr;
>> +size = fsl_chan->cfg.src_maxburst;
>> +break;
>> +default:
>> +dma_dir = DMA_NONE;
>> +break;
>> +}
>> +
>> +/* Already mapped for this config? */
>> +if (fsl_chan->dma_dir == dma_dir)
>> +return true;
>> +
>> +fsl_edma_unprep_slave_dma(fsl_chan);
>> +
>> +fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0);
>> +if (dma_mapping_error(dev, fsl_chan->dma_dev_addr))
>> +return false;
>> +fsl_chan->dma_dev_size = size;
>> +fsl_chan->dma_dir = dma_dir;
>> +
>> +return true;
>> +}
>> +
>>   int fsl_edma_slave_config(struct dma_chan *chan,
>>   struct dma_slave_config *cfg)
>>   {
>>  struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>>   
>>  memcpy(_chan->cfg, cfg, sizeof(*cfg));
>> +fsl_edma_unprep_slave_dma(fsl_chan);
>>   
>>  return 0;
>>   }
>> @@ -378,6 +429,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
>>  if (!is_slave_direction(direction))
>>  return NULL;
>>   
>> +if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
>> +return NULL;
>> +
>>  sg_len = buf_len / period_len;
>>  fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
>>  if (!fsl_desc)
>> @@ -409,11 +463,11 @@ struct dma_async_tx_descriptor 
>> *fsl_edma_prep_dma_cyclic(
>>   
>>  if (direction == DMA_MEM_TO_DEV) {
>>  src_addr = dma_buf_next;
>> -dst_addr = fsl_chan->cfg.dst_addr;
>> +dst_addr = fsl_chan->dma_dev_addr;
>>  soff = fsl_chan->cfg.dst_addr_width;
>>  doff = 0;
>>  } else {
>> -src_addr = fsl_chan->cfg.src_addr;
>> +src_addr = fsl_chan->dma_dev_addr;
>>  dst_addr = dma_buf_next;
>>  soff = 0;
>>  doff = fsl_chan->cfg.src_addr_width;
>> @@ -444,6 +498,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
>>  if (!is_slave_direction(direction))
>>  return NULL;
>>   
>> +if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
>> +return NULL;
>> +
>>  fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
>>  if (!fsl_desc)
>>  return NULL;
>> @@ -468,11 +525,11 @@ 

Re: [PATCH] dmaengine: fsl-edma: dma map slave device address

2019-01-18 Thread Angelo Dureghello
Hi Laurentiu,

On Fri, Jan 18, 2019 at 12:06:23PM +0200, Laurentiu Tudor wrote:
> This mapping needs to be created in order for slave dma transfers
> to work on systems with SMMU. The implementation mostly mimics the
> one in pl330 dma driver, authored by Robin Murphy.
> 
> Signed-off-by: Laurentiu Tudor 
> Suggested-by: Robin Murphy 
> ---
> Original approach was to add the missing mappings in the i2c client driver,
> see here for discussion: https://patchwork.ozlabs.org/patch/1026013/
> 
>  drivers/dma/fsl-edma-common.c | 66 ---
>  drivers/dma/fsl-edma-common.h |  4 +++
>  drivers/dma/fsl-edma.c|  1 +
>  drivers/dma/mcf-edma.c|  1 +
>  4 files changed, 68 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index 8876c4c1bb2c..0e95ee24b6d4 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -6,6 +6,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "fsl-edma-common.h"
>  
> @@ -173,12 +174,62 @@ int fsl_edma_resume(struct dma_chan *chan)
>  }
>  EXPORT_SYMBOL_GPL(fsl_edma_resume);
>  
> +static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan)
> +{
> + if (fsl_chan->dma_dir != DMA_NONE)
> + dma_unmap_resource(fsl_chan->vchan.chan.device->dev,
> +fsl_chan->dma_dev_addr,
> +fsl_chan->dma_dev_size,
> +fsl_chan->dma_dir, 0);
> + fsl_chan->dma_dir = DMA_NONE;
> +}
> +
> +static bool fsl_edma_prep_slave_dma(struct fsl_edma_chan *fsl_chan,
> + enum dma_transfer_direction dir)
> +{
> + struct device *dev = fsl_chan->vchan.chan.device->dev;
> + enum dma_data_direction dma_dir;
> + phys_addr_t addr = 0;
> + u32 size = 0;
> +
> + switch (dir) {
> + case DMA_MEM_TO_DEV:
> + dma_dir = DMA_FROM_DEVICE;
> + addr = fsl_chan->cfg.dst_addr;
> + size = fsl_chan->cfg.dst_maxburst;
> + break;
> + case DMA_DEV_TO_MEM:
> + dma_dir = DMA_TO_DEVICE;
> + addr = fsl_chan->cfg.src_addr;
> + size = fsl_chan->cfg.src_maxburst;
> + break;
> + default:
> + dma_dir = DMA_NONE;
> + break;
> + }
> +
> + /* Already mapped for this config? */
> + if (fsl_chan->dma_dir == dma_dir)
> + return true;
> +
> + fsl_edma_unprep_slave_dma(fsl_chan);
> +
> + fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0);
> + if (dma_mapping_error(dev, fsl_chan->dma_dev_addr))
> + return false;
> + fsl_chan->dma_dev_size = size;
> + fsl_chan->dma_dir = dma_dir;
> +
> + return true;
> +}
> +
>  int fsl_edma_slave_config(struct dma_chan *chan,
>struct dma_slave_config *cfg)
>  {
>   struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>  
>   memcpy(_chan->cfg, cfg, sizeof(*cfg));
> + fsl_edma_unprep_slave_dma(fsl_chan);
>  
>   return 0;
>  }
> @@ -378,6 +429,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
>   if (!is_slave_direction(direction))
>   return NULL;
>  
> + if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
> + return NULL;
> +
>   sg_len = buf_len / period_len;
>   fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
>   if (!fsl_desc)
> @@ -409,11 +463,11 @@ struct dma_async_tx_descriptor 
> *fsl_edma_prep_dma_cyclic(
>  
>   if (direction == DMA_MEM_TO_DEV) {
>   src_addr = dma_buf_next;
> - dst_addr = fsl_chan->cfg.dst_addr;
> + dst_addr = fsl_chan->dma_dev_addr;
>   soff = fsl_chan->cfg.dst_addr_width;
>   doff = 0;
>   } else {
> - src_addr = fsl_chan->cfg.src_addr;
> + src_addr = fsl_chan->dma_dev_addr;
>   dst_addr = dma_buf_next;
>   soff = 0;
>   doff = fsl_chan->cfg.src_addr_width;
> @@ -444,6 +498,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
>   if (!is_slave_direction(direction))
>   return NULL;
>  
> + if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
> + return NULL;
> +
>   fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
>   if (!fsl_desc)
>   return NULL;
> @@ -468,11 +525,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
>  
>   if (direction == DMA_MEM_TO_DEV) {
>   src_addr = sg_dma_address(sg);
> - dst_addr = fsl_chan->cfg.dst_addr;
> + dst_addr = fsl_chan->dma_dev_addr;
>   soff = fsl_chan->cfg.dst_addr_width;
>   doff = 0;
>   } else {
> -