Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1730809 > unrolled thread

[PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting

Started byPeter Ujfalusi <peter.ujfalusi@ti.com>
First post2017-09-12 12:50 +0200
Last post2017-09-12 12:50 +0200
Articles 10 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-12 12:50 +0200
    [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element) Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-12 12:50 +0200
      Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer  length (of an SG element) Vinod Koul <vinod.koul@intel.com> - 2017-09-21 19:20 +0200
        Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer  length (of an SG element) Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-22 11:50 +0200
    [PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-12 12:50 +0200
    [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-12 12:50 +0200
      Re: [PATCH 1/5] dmaengine: edma: Implement protection for invalid  max_burst Vinod Koul <vinod.koul@intel.com> - 2017-09-21 19:40 +0200
    [PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-12 12:50 +0200
      Re: [PATCH 2/5] dmaengine: omap-dma: Implement protection for  invalid max_burst Vinod Koul <vinod.koul@intel.com> - 2017-09-21 19:40 +0200
    [PATCH 5/5] dmaengine: omap-dma: Implement device_get_max_len callback Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-09-12 12:50 +0200

#1730809 — [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-12 12:50 +0200
Subject[PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting
Message-ID<uoQVr-ah-5@gated-at.bofh.it>
Hi,

Both TI eDMA and sDMA have limitation on the number of bursts it can handle
within one trasnfer (CCNT in eDMA and CFN in sDMA are 16bit unsigned counters).

If the the length of the SG in the sglist is bigger than what can be supported
we either have corrupted data or failure in the setup phase.

Add device_get_max_len() callback to devices where they can report such length
restriction to client drivers so they can set up their SGlist that each
element's length is going to be within the supported range.

The first two patch is not strictly related to this issue, but it is needed that
both eDMA and sDMA will have valid max_burst length.

Regards,
Peter
---
Peter Ujfalusi (5):
  dmaengine: edma: Implement protection for invalid max_burst
  dmaengine: omap-dma: Implement protection for invalid max_burst
  dmaengine: Support for querying maximum trasnfer length (of an SG
    element)
  dmaengine: edma: Implement device_get_max_len callback
  dmaengine: omap-dma: Implement device_get_max_len callback

 drivers/dma/edma.c        | 28 ++++++++++++++++++++++++++++
 drivers/dma/omap-dma.c    | 28 ++++++++++++++++++++++++++++
 include/linux/dmaengine.h | 14 ++++++++++++++
 3 files changed, 70 insertions(+)

-- 
2.14.1


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

[toc] | [next] | [standalone]


#1730810 — [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-12 12:50 +0200
Subject[PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
Message-ID<uoQVr-ah-7@gated-at.bofh.it>
In reply to#1730809
Certain DMA engines have limitation on the maximum size of a transfer they
can support. This size limitation is per SG element or for period length in
cyclic transfers.
In TI's eDMA and sDMA this limitation is not really a length limit, but it
is the number of bursts that we can support in one transfer.

With this callback the DMA drivers can provide hints to clients on how they
should set up their buffers (sglist, cyclic buffer). Without this the
clients must have open coded workarounds in place for each and every DMA
engine they might be interfacing with to have correct length for the
transfers.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 include/linux/dmaengine.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8319101170fc..739824b94c1b 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -705,6 +705,9 @@ struct dma_filter {
  * @device_prep_dma_imm_data: DMA's 8 byte immediate data to the dst address
  * @device_config: Pushes a new configuration to a channel, return 0 or an error
  *	code
+ * @device_get_max_len: Get the maximum supported length in bytes of a slave
+ *	transfer based on the set dma_slave_config. The length limitation
+ *	applies to each SG element's length.
  * @device_pause: Pauses any transfer happening on a channel. Returns
  *	0 or an error code
  * @device_resume: Resumes any transfer on a channel previously
@@ -792,6 +795,8 @@ struct dma_device {
 
 	int (*device_config)(struct dma_chan *chan,
 			     struct dma_slave_config *config);
+	u32 (*device_get_max_len)(struct dma_chan *chan,
+				  enum dma_transfer_direction dir);
 	int (*device_pause)(struct dma_chan *chan);
 	int (*device_resume)(struct dma_chan *chan);
 	int (*device_terminate_all)(struct dma_chan *chan);
@@ -812,6 +817,15 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
 	return -ENOSYS;
 }
 
+static inline u32 dmaengine_slave_get_max_len(struct dma_chan *chan,
+					      enum dma_transfer_direction dir)
+{
+	if (chan->device->device_get_max_len)
+		return chan->device->device_get_max_len(chan, dir);
+
+	return 0;
+}
+
 static inline bool is_slave_direction(enum dma_transfer_direction direction)
 {
 	return (direction == DMA_MEM_TO_DEV) || (direction == DMA_DEV_TO_MEM);
-- 
2.14.1


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

[toc] | [prev] | [next] | [standalone]


#1736920 — Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)

FromVinod Koul <vinod.koul@intel.com>
Date2017-09-21 19:20 +0200
SubjectRe: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
Message-ID<usdiP-3Se-47@gated-at.bofh.it>
In reply to#1730810
On Tue, Sep 12, 2017 at 01:44:22PM +0300, Peter Ujfalusi wrote:
> Certain DMA engines have limitation on the maximum size of a transfer they
> can support. This size limitation is per SG element or for period length in
> cyclic transfers.
> In TI's eDMA and sDMA this limitation is not really a length limit, but it
> is the number of bursts that we can support in one transfer.
> 
> With this callback the DMA drivers can provide hints to clients on how they
> should set up their buffers (sglist, cyclic buffer). Without this the
> clients must have open coded workarounds in place for each and every DMA
> engine they might be interfacing with to have correct length for the
> transfers.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  include/linux/dmaengine.h | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 8319101170fc..739824b94c1b 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -705,6 +705,9 @@ struct dma_filter {
>   * @device_prep_dma_imm_data: DMA's 8 byte immediate data to the dst address
>   * @device_config: Pushes a new configuration to a channel, return 0 or an error
>   *	code
> + * @device_get_max_len: Get the maximum supported length in bytes of a slave
> + *	transfer based on the set dma_slave_config. The length limitation
> + *	applies to each SG element's length.
>   * @device_pause: Pauses any transfer happening on a channel. Returns
>   *	0 or an error code
>   * @device_resume: Resumes any transfer on a channel previously
> @@ -792,6 +795,8 @@ struct dma_device {
>  
>  	int (*device_config)(struct dma_chan *chan,
>  			     struct dma_slave_config *config);
> +	u32 (*device_get_max_len)(struct dma_chan *chan,
> +				  enum dma_transfer_direction dir);
>  	int (*device_pause)(struct dma_chan *chan);
>  	int (*device_resume)(struct dma_chan *chan);
>  	int (*device_terminate_all)(struct dma_chan *chan);
> @@ -812,6 +817,15 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
>  	return -ENOSYS;
>  }
>  
> +static inline u32 dmaengine_slave_get_max_len(struct dma_chan *chan,
> +					      enum dma_transfer_direction dir)
> +{
> +	if (chan->device->device_get_max_len)
> +		return chan->device->device_get_max_len(chan, dir);

not another callback :)

on a serious note, why shouldn't this be one more capability in
dma_slave_caps. looking at next patch it seems static

-- 
~Vinod

[toc] | [prev] | [next] | [standalone]


#1737348 — Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-22 11:50 +0200
SubjectRe: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
Message-ID<ussKS-4u6-27@gated-at.bofh.it>
In reply to#1736920

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

On 2017-09-21 20:14, Vinod Koul wrote:
> On Tue, Sep 12, 2017 at 01:44:22PM +0300, Peter Ujfalusi wrote:
>> Certain DMA engines have limitation on the maximum size of a transfer they
>> can support. This size limitation is per SG element or for period length in
>> cyclic transfers.
>> In TI's eDMA and sDMA this limitation is not really a length limit, but it
>> is the number of bursts that we can support in one transfer.
>>
>> With this callback the DMA drivers can provide hints to clients on how they
>> should set up their buffers (sglist, cyclic buffer). Without this the
>> clients must have open coded workarounds in place for each and every DMA
>> engine they might be interfacing with to have correct length for the
>> transfers.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>>  include/linux/dmaengine.h | 14 ++++++++++++++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
>> index 8319101170fc..739824b94c1b 100644
>> --- a/include/linux/dmaengine.h
>> +++ b/include/linux/dmaengine.h
>> @@ -705,6 +705,9 @@ struct dma_filter {
>>   * @device_prep_dma_imm_data: DMA's 8 byte immediate data to the dst address
>>   * @device_config: Pushes a new configuration to a channel, return 0 or an error
>>   *	code
>> + * @device_get_max_len: Get the maximum supported length in bytes of a slave
>> + *	transfer based on the set dma_slave_config. The length limitation
>> + *	applies to each SG element's length.
>>   * @device_pause: Pauses any transfer happening on a channel. Returns
>>   *	0 or an error code
>>   * @device_resume: Resumes any transfer on a channel previously
>> @@ -792,6 +795,8 @@ struct dma_device {
>>  
>>  	int (*device_config)(struct dma_chan *chan,
>>  			     struct dma_slave_config *config);
>> +	u32 (*device_get_max_len)(struct dma_chan *chan,
>> +				  enum dma_transfer_direction dir);
>>  	int (*device_pause)(struct dma_chan *chan);
>>  	int (*device_resume)(struct dma_chan *chan);
>>  	int (*device_terminate_all)(struct dma_chan *chan);
>> @@ -812,6 +817,15 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
>>  	return -ENOSYS;
>>  }
>>  
>> +static inline u32 dmaengine_slave_get_max_len(struct dma_chan *chan,
>> +					      enum dma_transfer_direction dir)
>> +{
>> +	if (chan->device->device_get_max_len)
>> +		return chan->device->device_get_max_len(chan, dir);
> 
> not another callback :)
> 
> on a serious note, why shouldn't this be one more capability in
> dma_slave_caps. looking at next patch it seems static

It is not really static, the size in bytes depends on the dev_width and
the maxburst:
dev_width * burst * (SZ_64K - 1);

The number of (dev_width * burst) is static, yes. Other DMA engines
might have similar interpretation, but returning the maximum length in
bytes sounded more generic for other engines to be able to adopt.

Initially I had maxburst_cnt in struct dma_device for maximum burst
count within one SG, but it felt clumsy and not too intuitive either.

- Péter

[toc] | [prev] | [next] | [standalone]


#1730811 — [PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-12 12:50 +0200
Subject[PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback
Message-ID<uoQVr-ah-9@gated-at.bofh.it>
In reply to#1730809
eDMA can support maximum of 65535 number of bursts in one transfer.
The limitation is because the CCNT counter is 16bit unsigned.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/edma.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 6970355abdc9..14c52574262c 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -900,6 +900,28 @@ static int edma_slave_config(struct dma_chan *chan,
 	return 0;
 }
 
+static u32 edma_get_max_len(struct dma_chan *chan,
+			    enum dma_transfer_direction dir)
+{
+	struct edma_chan *echan = to_edma_chan(chan);
+	enum dma_slave_buswidth dev_width;
+	u32 burst;
+
+	if (!is_slave_direction(dir))
+		return 0;
+
+	if (dir == DMA_DEV_TO_MEM) {
+		dev_width = echan->cfg.src_addr_width;
+		burst = echan->cfg.src_maxburst;
+	} else {
+		burst = echan->cfg.dst_maxburst;
+		dev_width = echan->cfg.dst_addr_width;
+	}
+
+	/* CCNT: 16bit unsigned. Number of bursts */
+	return dev_width * burst * (SZ_64K - 1);
+}
+
 static int edma_dma_pause(struct dma_chan *chan)
 {
 	struct edma_chan *echan = to_edma_chan(chan);
@@ -1850,6 +1872,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
 	s_ddev->device_issue_pending = edma_issue_pending;
 	s_ddev->device_tx_status = edma_tx_status;
 	s_ddev->device_config = edma_slave_config;
+	s_ddev->device_get_max_len = edma_get_max_len;
 	s_ddev->device_pause = edma_dma_pause;
 	s_ddev->device_resume = edma_dma_resume;
 	s_ddev->device_terminate_all = edma_terminate_all;
-- 
2.14.1


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

[toc] | [prev] | [next] | [standalone]


#1730812 — [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-12 12:50 +0200
Subject[PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst
Message-ID<uoQVs-ah-11@gated-at.bofh.it>
In reply to#1730809
Set the device's max_burst to 32767 (CIDX is 16bit signed value) so clients
can take this into consideration when setting up the trasnfer.

During slave transfer preparation check if the requested maxburst is valid.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/edma.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 3879f80a4815..6970355abdc9 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -891,6 +891,10 @@ static int edma_slave_config(struct dma_chan *chan,
 	    cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
 		return -EINVAL;
 
+	if (cfg->src_maxburst > chan->device->max_burst ||
+	    cfg->dst_maxburst > chan->device->max_burst)
+		return -EINVAL;
+
 	memcpy(&echan->cfg, cfg, sizeof(echan->cfg));
 
 	return 0;
@@ -1855,6 +1859,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
 	s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS;
 	s_ddev->directions |= (BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV));
 	s_ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+	s_ddev->max_burst = SZ_32K - 1; /* CIDX: 16bit signed */
 
 	s_ddev->dev = ecc->dev;
 	INIT_LIST_HEAD(&s_ddev->channels);
-- 
2.14.1


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

[toc] | [prev] | [next] | [standalone]


#1736966 — Re: [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst

FromVinod Koul <vinod.koul@intel.com>
Date2017-09-21 19:40 +0200
SubjectRe: [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst
Message-ID<usdC9-3YA-1@gated-at.bofh.it>
In reply to#1730812
On Tue, Sep 12, 2017 at 01:44:20PM +0300, Peter Ujfalusi wrote:
> Set the device's max_burst to 32767 (CIDX is 16bit signed value) so clients
> can take this into consideration when setting up the trasnfer.

/s/trasnfer/transfer

> 
> During slave transfer preparation check if the requested maxburst is valid.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/edma.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
> index 3879f80a4815..6970355abdc9 100644
> --- a/drivers/dma/edma.c
> +++ b/drivers/dma/edma.c
> @@ -891,6 +891,10 @@ static int edma_slave_config(struct dma_chan *chan,
>  	    cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
>  		return -EINVAL;
>  
> +	if (cfg->src_maxburst > chan->device->max_burst ||
> +	    cfg->dst_maxburst > chan->device->max_burst)
> +		return -EINVAL;
> +
>  	memcpy(&echan->cfg, cfg, sizeof(echan->cfg));
>  
>  	return 0;
> @@ -1855,6 +1859,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
>  	s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS;
>  	s_ddev->directions |= (BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV));
>  	s_ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
> +	s_ddev->max_burst = SZ_32K - 1; /* CIDX: 16bit signed */
>  
>  	s_ddev->dev = ecc->dev;
>  	INIT_LIST_HEAD(&s_ddev->channels);
> -- 
> 2.14.1
> 
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> 

-- 
~Vinod

[toc] | [prev] | [next] | [standalone]


#1730813 — [PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-12 12:50 +0200
Subject[PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst
Message-ID<uoQVs-ah-13@gated-at.bofh.it>
In reply to#1730809
Set the device's max_burst to 16777215 (EN is 24bit unsigned value) so
clients can take this into consideration when setting up the trasnfer.

During slave transfer preparation check if the requested maxburst is valid.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 8c1665c8fe33..f6dd849159d8 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -1288,6 +1288,10 @@ static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config
 	    cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
 		return -EINVAL;
 
+	if (cfg->src_maxburst > chan->device->max_burst ||
+	    cfg->dst_maxburst > chan->device->max_burst)
+		return -EINVAL;
+
 	memcpy(&c->cfg, cfg, sizeof(c->cfg));
 
 	return 0;
@@ -1482,6 +1486,7 @@ static int omap_dma_probe(struct platform_device *pdev)
 	od->ddev.dst_addr_widths = OMAP_DMA_BUSWIDTHS;
 	od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
 	od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+	od->ddev.max_burst = SZ_16M - 1; /* CCEN: 24bit unsigned */
 	od->ddev.dev = &pdev->dev;
 	INIT_LIST_HEAD(&od->ddev.channels);
 	spin_lock_init(&od->lock);
-- 
2.14.1


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

[toc] | [prev] | [next] | [standalone]


#1736968 — Re: [PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst

FromVinod Koul <vinod.koul@intel.com>
Date2017-09-21 19:40 +0200
SubjectRe: [PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst
Message-ID<usdC9-3YA-11@gated-at.bofh.it>
In reply to#1730813
On Tue, Sep 12, 2017 at 01:44:21PM +0300, Peter Ujfalusi wrote:
> Set the device's max_burst to 16777215 (EN is 24bit unsigned value) so
> clients can take this into consideration when setting up the trasnfer.

ditto :D

> 
> During slave transfer preparation check if the requested maxburst is valid.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/omap-dma.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
> index 8c1665c8fe33..f6dd849159d8 100644
> --- a/drivers/dma/omap-dma.c
> +++ b/drivers/dma/omap-dma.c
> @@ -1288,6 +1288,10 @@ static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config
>  	    cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
>  		return -EINVAL;
>  
> +	if (cfg->src_maxburst > chan->device->max_burst ||
> +	    cfg->dst_maxburst > chan->device->max_burst)
> +		return -EINVAL;
> +
>  	memcpy(&c->cfg, cfg, sizeof(c->cfg));
>  
>  	return 0;
> @@ -1482,6 +1486,7 @@ static int omap_dma_probe(struct platform_device *pdev)
>  	od->ddev.dst_addr_widths = OMAP_DMA_BUSWIDTHS;
>  	od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
>  	od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
> +	od->ddev.max_burst = SZ_16M - 1; /* CCEN: 24bit unsigned */
>  	od->ddev.dev = &pdev->dev;
>  	INIT_LIST_HEAD(&od->ddev.channels);
>  	spin_lock_init(&od->lock);
> -- 
> 2.14.1
> 
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> 

-- 
~Vinod

[toc] | [prev] | [next] | [standalone]


#1730815 — [PATCH 5/5] dmaengine: omap-dma: Implement device_get_max_len callback

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-09-12 12:50 +0200
Subject[PATCH 5/5] dmaengine: omap-dma: Implement device_get_max_len callback
Message-ID<uoQVs-ah-15@gated-at.bofh.it>
In reply to#1730809
sDMA can support maximum of 65535 number of bursts in one transfer.
The limitation is because the CFN counter is 16bit unsigned.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index f6dd849159d8..6418be98a782 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -1297,6 +1297,28 @@ static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config
 	return 0;
 }
 
+static u32 omap_dma_get_max_len(struct dma_chan *chan,
+				enum dma_transfer_direction dir)
+{
+	struct omap_chan *c = to_omap_dma_chan(chan);
+	enum dma_slave_buswidth dev_width;
+	u32 burst;
+
+	if (!is_slave_direction(dir))
+		return 0;
+
+	if (dir == DMA_DEV_TO_MEM) {
+		dev_width = c->cfg.src_addr_width;
+		burst = c->cfg.src_maxburst;
+	} else {
+		burst = c->cfg.dst_maxburst;
+		dev_width = c->cfg.dst_addr_width;
+	}
+
+	/* CFN: 16bit unsigned. Number of bursts */
+	return dev_width * burst * (SZ_64K - 1);
+}
+
 static int omap_dma_terminate_all(struct dma_chan *chan)
 {
 	struct omap_chan *c = to_omap_dma_chan(chan);
@@ -1478,6 +1500,7 @@ static int omap_dma_probe(struct platform_device *pdev)
 	od->ddev.device_prep_dma_memcpy = omap_dma_prep_dma_memcpy;
 	od->ddev.device_prep_interleaved_dma = omap_dma_prep_dma_interleaved;
 	od->ddev.device_config = omap_dma_slave_config;
+	od->ddev.device_get_max_len = omap_dma_get_max_len;
 	od->ddev.device_pause = omap_dma_pause;
 	od->ddev.device_resume = omap_dma_resume;
 	od->ddev.device_terminate_all = omap_dma_terminate_all;
-- 
2.14.1


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web