linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting
@ 2017-09-12 10:44 Peter Ujfalusi
  2017-09-12 10:44 ` [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst Peter Ujfalusi
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-12 10:44 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, linux-omap, linux-arm-kernel, t-kristo

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst
  2017-09-12 10:44 [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi
@ 2017-09-12 10:44 ` Peter Ujfalusi
  2017-09-21 17:10   ` Vinod Koul
  2017-09-12 10:44 ` [PATCH 2/5] dmaengine: omap-dma: " Peter Ujfalusi
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-12 10:44 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, linux-omap, linux-arm-kernel, t-kristo

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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst
  2017-09-12 10:44 [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi
  2017-09-12 10:44 ` [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst Peter Ujfalusi
@ 2017-09-12 10:44 ` Peter Ujfalusi
  2017-09-21 17:12   ` Vinod Koul
  2017-09-12 10:44 ` [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element) Peter Ujfalusi
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-12 10:44 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, linux-omap, linux-arm-kernel, t-kristo

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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-09-12 10:44 [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi
  2017-09-12 10:44 ` [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst Peter Ujfalusi
  2017-09-12 10:44 ` [PATCH 2/5] dmaengine: omap-dma: " Peter Ujfalusi
@ 2017-09-12 10:44 ` Peter Ujfalusi
  2017-09-21 17:14   ` Vinod Koul
  2017-09-12 10:44 ` [PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback Peter Ujfalusi
  2017-09-12 10:44 ` [PATCH 5/5] dmaengine: omap-dma: " Peter Ujfalusi
  4 siblings, 1 reply; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-12 10:44 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, linux-omap, linux-arm-kernel, t-kristo

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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback
  2017-09-12 10:44 [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi
                   ` (2 preceding siblings ...)
  2017-09-12 10:44 ` [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element) Peter Ujfalusi
@ 2017-09-12 10:44 ` Peter Ujfalusi
  2017-09-12 10:44 ` [PATCH 5/5] dmaengine: omap-dma: " Peter Ujfalusi
  4 siblings, 0 replies; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-12 10:44 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, linux-omap, linux-arm-kernel, t-kristo

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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/5] dmaengine: omap-dma: Implement device_get_max_len callback
  2017-09-12 10:44 [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi
                   ` (3 preceding siblings ...)
  2017-09-12 10:44 ` [PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback Peter Ujfalusi
@ 2017-09-12 10:44 ` Peter Ujfalusi
  4 siblings, 0 replies; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-12 10:44 UTC (permalink / raw)
  To: vinod.koul, dan.j.williams
  Cc: dmaengine, linux-kernel, linux-omap, linux-arm-kernel, t-kristo

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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst
  2017-09-12 10:44 ` [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst Peter Ujfalusi
@ 2017-09-21 17:10   ` Vinod Koul
  0 siblings, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2017-09-21 17:10 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/5] dmaengine: omap-dma: Implement protection for invalid max_burst
  2017-09-12 10:44 ` [PATCH 2/5] dmaengine: omap-dma: " Peter Ujfalusi
@ 2017-09-21 17:12   ` Vinod Koul
  0 siblings, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2017-09-21 17:12 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-09-12 10:44 ` [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element) Peter Ujfalusi
@ 2017-09-21 17:14   ` Vinod Koul
  2017-09-22  9:39     ` Peter Ujfalusi
  0 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2017-09-21 17:14 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-09-21 17:14   ` Vinod Koul
@ 2017-09-22  9:39     ` Peter Ujfalusi
  2017-09-26 16:54       ` Vinod Koul
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Ujfalusi @ 2017-09-22  9:39 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo


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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-09-22  9:39     ` Peter Ujfalusi
@ 2017-09-26 16:54       ` Vinod Koul
  2017-10-02 11:24         ` Peter Ujfalusi
  0 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2017-09-26 16:54 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo

On Fri, Sep 22, 2017 at 12:39:38PM +0300, Peter Ujfalusi wrote:
> 
> 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);

well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1
'items' which IIUC in DMAengine terms for bytes would always refer wrt width
used and burst applied.

Return length in bytes does make sense (from user PoV), but then you need to
"know" the applied  width and burst. How do you decide those?

> 
> 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
> 

-- 
~Vinod

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-09-26 16:54       ` Vinod Koul
@ 2017-10-02 11:24         ` Peter Ujfalusi
  2017-10-08  5:25           ` Vinod Koul
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Ujfalusi @ 2017-10-02 11:24 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo




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

On 2017-09-26 19:54, Vinod Koul wrote:
>>>
>>> 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);
> 
> well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1
> 'items' which IIUC in DMAengine terms for bytes would always refer wrt width
> used and burst applied.

I think we can live with this and let the user to figure out what to do
with this information.

But I'm having hard time to figure out a good name for this. It is not
the number of SGs we can support, but the number of 'items' within one
SG that we have the limit. It could be:
u32 max_bursts_per_sg;

which would also apply to period length (for cyclic) in a similar way.

> Return length in bytes does make sense (from user PoV), but then you need to
> "know" the applied  width and burst. How do you decide those?

The number of items works eDMA and sDMA, but we also have the cpp41. It
is a packet DMA and it has no understanding of bursts, address widths or
any of the 'traditional' things. It only cares about the number of bytes
we want to transfer and it has limitation of 4194303 bytes (21bits for
length). This is again per SG. How this could report the
'max_bursts_per_sg' ?

This was one of the reasons that I have settled with the callback.

What we can also do is to code this within the DMA drivers itself.

When setting up the transfer and we realize that one of the SG will not
going to fit, we destroy what we have done so far, pass the sg list
along with length/sg limit to create a new sg list where all sg item's
length is under the limit. Then using this new sg list we can set up the
transfer.

I'm not sure how hard is to do the sg list optimization, I see that
sg_split() is not what we want so we might need to code this in
dmaengine or in the scatterlist code.

We certainly don't want to verify all slave_sg transfers proactively to
avoid adding latency when it is not necessary.


>>
>> 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
>>
> 

- Péter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-10-02 11:24         ` Peter Ujfalusi
@ 2017-10-08  5:25           ` Vinod Koul
  2017-10-11 15:47             ` Peter Ujfalusi
  0 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2017-10-08  5:25 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo

On Mon, Oct 02, 2017 at 02:24:12PM +0300, Peter Ujfalusi wrote:
> 
> 
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 2017-09-26 19:54, Vinod Koul wrote:
> >>>
> >>> 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);
> > 
> > well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1
> > 'items' which IIUC in DMAengine terms for bytes would always refer wrt width
> > used and burst applied.
> 
> I think we can live with this and let the user to figure out what to do
> with this information.

Right, plus a macro for conversion :) SO that users dont code buggy
conversions all over the place

> But I'm having hard time to figure out a good name for this. It is not
> the number of SGs we can support, but the number of 'items' within one
> SG that we have the limit. It could be:
> u32 max_bursts_per_sg;

this looks fine, another candidate I would use is words_per_sg and while at
it why tie it to sg? should we make it words_per_txn but then people should not
confuse with txn represented by a descriptor which can have multiple ....

> 
> which would also apply to period length (for cyclic) in a similar way.
> 
> > Return length in bytes does make sense (from user PoV), but then you need to
> > "know" the applied  width and burst. How do you decide those?
> 
> The number of items works eDMA and sDMA, but we also have the cpp41. It
> is a packet DMA and it has no understanding of bursts, address widths or
> any of the 'traditional' things. It only cares about the number of bytes
> we want to transfer and it has limitation of 4194303 bytes (21bits for
> length). This is again per SG. How this could report the
> 'max_bursts_per_sg' ?

hmmm that is intresting case, is this number coming from USB side?

> This was one of the reasons that I have settled with the callback.
> 
> What we can also do is to code this within the DMA drivers itself.
> 
> When setting up the transfer and we realize that one of the SG will not
> going to fit, we destroy what we have done so far, pass the sg list
> along with length/sg limit to create a new sg list where all sg item's
> length is under the limit. Then using this new sg list we can set up the
> transfer.
> 
> I'm not sure how hard is to do the sg list optimization, I see that
> sg_split() is not what we want so we might need to code this in
> dmaengine or in the scatterlist code.
> 
> We certainly don't want to verify all slave_sg transfers proactively to
> avoid adding latency when it is not necessary.

latency would be added at prepare, not when submitting..

-- 
~Vinod

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-10-08  5:25           ` Vinod Koul
@ 2017-10-11 15:47             ` Peter Ujfalusi
  2017-10-12 13:57               ` Vinod Koul
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Ujfalusi @ 2017-10-11 15:47 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo


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

On 10/08/2017 08:25 AM, Vinod Koul wrote:
>>>> It is not really static, the size in bytes depends on the dev_width and
>>>> the maxburst:
>>>> dev_width * burst * (SZ_64K - 1);
>>>
>>> well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1
>>> 'items' which IIUC in DMAengine terms for bytes would always refer wrt width
>>> used and burst applied.
>>
>> I think we can live with this and let the user to figure out what to do
>> with this information.
> 
> Right, plus a macro for conversion :) SO that users dont code buggy
> conversions all over the place

OK, but still the naming... ;)

>> But I'm having hard time to figure out a good name for this. It is not
>> the number of SGs we can support, but the number of 'items' within one
>> SG that we have the limit. It could be:
>> u32 max_bursts_per_sg;
> 
> this looks fine, another candidate I would use is words_per_sg and while at
> it why tie it to sg? should we make it words_per_txn but then people should not
> confuse with txn represented by a descriptor which can have multiple ....

Yes, this limit is not only per SG as the same limit actually applies to
cyclic's period_len in a same way.

words_per_txn does not sound right as for me the words would refer to
dev_width number of bytes and I'm seeking on limit on the number of (dev_width
* bursts) sub-chunks.

bursts_per_chunk? With a long comment?

Which would apply to sg_dma_len in slave_sg(), period_len in cyclic() and len
in slave_single().

>>
>> which would also apply to period length (for cyclic) in a similar way.
>>
>>> Return length in bytes does make sense (from user PoV), but then you need to
>>> "know" the applied  width and burst. How do you decide those?
>>
>> The number of items works eDMA and sDMA, but we also have the cpp41. It
>> is a packet DMA and it has no understanding of bursts, address widths or
>> any of the 'traditional' things. It only cares about the number of bytes
>> we want to transfer and it has limitation of 4194303 bytes (21bits for
>> length). This is again per SG. How this could report the
>> 'max_bursts_per_sg' ?
> 
> hmmm that is intresting case, is this number coming from USB side?

No, it is coming from cppi4.1's descriptor. The maximum length of a packet is
stored in 21bits.

But this is a bit more complicated ;) The whole packet have 21bits size limit,
but at the same time the whole sg_dma_len() also have this as we can link a
several host buffer descriptors to one host packet descriptor. Each have
21bits for length, but at the same time the sum of the hpd and the linked hbd
length can not be more than what we can store in 21bits...

> 
>> This was one of the reasons that I have settled with the callback.
>>
>> What we can also do is to code this within the DMA drivers itself.
>>
>> When setting up the transfer and we realize that one of the SG will not
>> going to fit, we destroy what we have done so far, pass the sg list
>> along with length/sg limit to create a new sg list where all sg item's
>> length is under the limit. Then using this new sg list we can set up the
>> transfer.
>>
>> I'm not sure how hard is to do the sg list optimization, I see that
>> sg_split() is not what we want so we might need to code this in
>> dmaengine or in the scatterlist code.
>>
>> We certainly don't want to verify all slave_sg transfers proactively to
>> avoid adding latency when it is not necessary.
> 
> latency would be added at prepare, not when submitting..

Yes, but you submit transfers all the time, and added latency would be crucial.

But this could be done with a DMAengine internal helper, I think.
If a DMA driver figures out that one of the SG length is over the supported
limit, then it could clean up everything and call something like:

struct dma_async_tx_descriptor *dmaengine_fixup_and_prep_slave_sg(
	struct dma_chan *chan, struct scatterlist *sgl,
	unsigned int sg_len, enum dma_transfer_direction dir,
	unsigned long flags, size_t max_sg_dma_len)

and this would split up the original SG list to a temp one meeting the
max_sg_dma_len and call chan->device->device_prep_slave_sg()

In this round the setup would succeed and the caller and I would be happy.

But if the caller already aware of the sg_dma_len limit it can prepare the SG
list correctly and we save time to recreate the list.

-- 
Péter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
  2017-10-11 15:47             ` Peter Ujfalusi
@ 2017-10-12 13:57               ` Vinod Koul
  0 siblings, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2017-10-12 13:57 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: dan.j.williams, dmaengine, linux-kernel, linux-omap,
	linux-arm-kernel, t-kristo

On Wed, Oct 11, 2017 at 06:47:18PM +0300, Peter Ujfalusi wrote:
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 
> On 10/08/2017 08:25 AM, Vinod Koul wrote:
> >>>> It is not really static, the size in bytes depends on the dev_width and
> >>>> the maxburst:
> >>>> dev_width * burst * (SZ_64K - 1);
> >>>
> >>> well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1
> >>> 'items' which IIUC in DMAengine terms for bytes would always refer wrt width
> >>> used and burst applied.
> >>
> >> I think we can live with this and let the user to figure out what to do
> >> with this information.
> > 
> > Right, plus a macro for conversion :) SO that users dont code buggy
> > conversions all over the place
> 
> OK, but still the naming... ;)
> 
> >> But I'm having hard time to figure out a good name for this. It is not
> >> the number of SGs we can support, but the number of 'items' within one
> >> SG that we have the limit. It could be:
> >> u32 max_bursts_per_sg;
> > 
> > this looks fine, another candidate I would use is words_per_sg and while at
> > it why tie it to sg? should we make it words_per_txn but then people should not
> > confuse with txn represented by a descriptor which can have multiple ....
> 
> Yes, this limit is not only per SG as the same limit actually applies to
> cyclic's period_len in a same way.
> 
> words_per_txn does not sound right as for me the words would refer to
> dev_width number of bytes and I'm seeking on limit on the number of (dev_width
> * bursts) sub-chunks.
> 
> bursts_per_chunk? With a long comment?
> 
> Which would apply to sg_dma_len in slave_sg(), period_len in cyclic() and len
> in slave_single().

Sounds much better to me :)

> 
> >>
> >> which would also apply to period length (for cyclic) in a similar way.
> >>
> >>> Return length in bytes does make sense (from user PoV), but then you need to
> >>> "know" the applied  width and burst. How do you decide those?
> >>
> >> The number of items works eDMA and sDMA, but we also have the cpp41. It
> >> is a packet DMA and it has no understanding of bursts, address widths or
> >> any of the 'traditional' things. It only cares about the number of bytes
> >> we want to transfer and it has limitation of 4194303 bytes (21bits for
> >> length). This is again per SG. How this could report the
> >> 'max_bursts_per_sg' ?
> > 
> > hmmm that is intresting case, is this number coming from USB side?
> 
> No, it is coming from cppi4.1's descriptor. The maximum length of a packet is
> stored in 21bits.
> 
> But this is a bit more complicated ;) The whole packet have 21bits size limit,
> but at the same time the whole sg_dma_len() also have this as we can link a
> several host buffer descriptors to one host packet descriptor. Each have
> 21bits for length, but at the same time the sum of the hpd and the linked hbd
> length can not be more than what we can store in 21bits...
> 
> > 
> >> This was one of the reasons that I have settled with the callback.
> >>
> >> What we can also do is to code this within the DMA drivers itself.
> >>
> >> When setting up the transfer and we realize that one of the SG will not
> >> going to fit, we destroy what we have done so far, pass the sg list
> >> along with length/sg limit to create a new sg list where all sg item's
> >> length is under the limit. Then using this new sg list we can set up the
> >> transfer.
> >>
> >> I'm not sure how hard is to do the sg list optimization, I see that
> >> sg_split() is not what we want so we might need to code this in
> >> dmaengine or in the scatterlist code.
> >>
> >> We certainly don't want to verify all slave_sg transfers proactively to
> >> avoid adding latency when it is not necessary.
> > 
> > latency would be added at prepare, not when submitting..
> 
> Yes, but you submit transfers all the time, and added latency would be crucial.
> 
> But this could be done with a DMAengine internal helper, I think.
> If a DMA driver figures out that one of the SG length is over the supported
> limit, then it could clean up everything and call something like:
> 
> struct dma_async_tx_descriptor *dmaengine_fixup_and_prep_slave_sg(
> 	struct dma_chan *chan, struct scatterlist *sgl,
> 	unsigned int sg_len, enum dma_transfer_direction dir,
> 	unsigned long flags, size_t max_sg_dma_len)
> 
> and this would split up the original SG list to a temp one meeting the
> max_sg_dma_len and call chan->device->device_prep_slave_sg()
> 
> In this round the setup would succeed and the caller and I would be happy.
> 
> But if the caller already aware of the sg_dma_len limit it can prepare the SG
> list correctly and we save time to recreate the list.

rather than driver figure out, why don't we add the in prep_ call. Since we
would know the capability of the device we can do that split, that way we
have common split code in middle in the framework and drivers get sg list
which is supported by them. It can also split a list to multipe prep_ calls
based on controller support.

Yes that is a big ask, we can split up and do in stages :)

-- 
~Vinod

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-10-12 13:53 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-12 10:44 [PATCH 0/5] dmaengine: core/edma/omap-dma: maximum SG len reporting Peter Ujfalusi
2017-09-12 10:44 ` [PATCH 1/5] dmaengine: edma: Implement protection for invalid max_burst Peter Ujfalusi
2017-09-21 17:10   ` Vinod Koul
2017-09-12 10:44 ` [PATCH 2/5] dmaengine: omap-dma: " Peter Ujfalusi
2017-09-21 17:12   ` Vinod Koul
2017-09-12 10:44 ` [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element) Peter Ujfalusi
2017-09-21 17:14   ` Vinod Koul
2017-09-22  9:39     ` Peter Ujfalusi
2017-09-26 16:54       ` Vinod Koul
2017-10-02 11:24         ` Peter Ujfalusi
2017-10-08  5:25           ` Vinod Koul
2017-10-11 15:47             ` Peter Ujfalusi
2017-10-12 13:57               ` Vinod Koul
2017-09-12 10:44 ` [PATCH 4/5] dmaengine: edma: Implement device_get_max_len callback Peter Ujfalusi
2017-09-12 10:44 ` [PATCH 5/5] dmaengine: omap-dma: " Peter Ujfalusi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).