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


Groups > linux.kernel > #1400126 > unrolled thread

[PATCH 1/3] dmaengine: at_xdmac: align descriptors on 64 bits

Started byLudovic Desroches <ludovic.desroches@atmel.com>
First post2016-05-12 17:00 +0200
Last post2016-05-30 07:20 +0200
Articles 5 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 1/3] dmaengine: at_xdmac: align descriptors on 64 bits Ludovic Desroches <ludovic.desroches@atmel.com> - 2016-05-12 17:00 +0200
    [PATCH 3/3] dmaengine: at_xdmac: double FIFO flush needed to compute residue Ludovic Desroches <ludovic.desroches@atmel.com> - 2016-05-12 17:00 +0200
      Re: [PATCH 3/3] dmaengine: at_xdmac: double FIFO flush needed to  compute residue Nicolas Ferre <nicolas.ferre@atmel.com> - 2016-05-13 14:30 +0200
    Re: [PATCH 1/3] dmaengine: at_xdmac: align descriptors on 64 bits Nicolas Ferre <nicolas.ferre@atmel.com> - 2016-05-13 14:30 +0200
    Re: [PATCH 1/3] dmaengine: at_xdmac: align descriptors on 64 bits Vinod Koul <vinod.koul@intel.com> - 2016-05-30 07:20 +0200

#1400126 — [PATCH 1/3] dmaengine: at_xdmac: align descriptors on 64 bits

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2016-05-12 17:00 +0200
Subject[PATCH 1/3] dmaengine: at_xdmac: align descriptors on 64 bits
Message-ID<ry0fL-80O-11@gated-at.bofh.it>
Having descriptors aligned on 64 bits allows update CNDA and CUBC in an
atomic way.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel
eXtended DMA Controller driver")
Cc: stable@vger.kernel.org #v4.1 and later
---
 drivers/dma/at_xdmac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 8e304b1..ba9b0b7 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -242,7 +242,7 @@ struct at_xdmac_lld {
 	u32		mbr_dus;	/* Destination Microblock Stride Register */
 };
 
-
+/* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */
 struct at_xdmac_desc {
 	struct at_xdmac_lld		lld;
 	enum dma_transfer_direction	direction;
@@ -253,7 +253,7 @@ struct at_xdmac_desc {
 	unsigned int			xfer_size;
 	struct list_head		descs_list;
 	struct list_head		xfer_node;
-};
+} __aligned(sizeof(u64));
 
 static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb)
 {
-- 
2.5.0

[toc] | [next] | [standalone]


#1400128 — [PATCH 3/3] dmaengine: at_xdmac: double FIFO flush needed to compute residue

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2016-05-12 17:00 +0200
Subject[PATCH 3/3] dmaengine: at_xdmac: double FIFO flush needed to compute residue
Message-ID<ry0fM-80O-17@gated-at.bofh.it>
In reply to#1400126
Due to the way CUBC register is updated, a double flush is needed to
compute an accurate residue. First flush aim is to get data from the DMA
FIFO and second one ensures that we won't report data which are not in
memory.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel
eXtended DMA Controller driver")
Cc: stable@vger.kernel.org #v4.1 and later
---
 drivers/dma/at_xdmac.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index b02494e..75bd662 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1425,7 +1425,16 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	residue = desc->xfer_size;
 	/*
 	 * Flush FIFO: only relevant when the transfer is source peripheral
-	 * synchronized.
+	 * synchronized. Flush is needed before reading CUBC because data in
+	 * the FIFO are not reported by CUBC. Reporting a residue of the
+	 * transfer length while we have data in FIFO can cause issue.
+	 * Usecase: atmel USART has a timeout which means I have received
+	 * characters but there is no more character received for a while. On
+	 * timeout, it requests the residue. If the data are in the DMA FIFO,
+	 * we will return a residue of the transfer length. It means no data
+	 * received. If an application is waiting for these data, it will hang
+	 * since we won't have another USART timeout without receiving new
+	 * data.
 	 */
 	mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
 	value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
@@ -1481,6 +1490,19 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	}
 
 	/*
+	 * Flush FIFO: only relevant when the transfer is source peripheral
+	 * synchronized. Another flush is needed here because CUBC is updated
+	 * when the controller sends the data write command. It can lead to
+	 * report data that are not written in the memory or the device. The
+	 * FIFO flush ensures that data are really written.
+	 */
+	if ((desc->lld.mbr_cfg & mask) == value) {
+		at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
+		while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
+			cpu_relax();
+	}
+
+	/*
 	 * Remove size of all microblocks already transferred and the current
 	 * one. Then add the remaining size to transfer of the current
 	 * microblock.
-- 
2.5.0

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


#1400760 — Re: [PATCH 3/3] dmaengine: at_xdmac: double FIFO flush needed to compute residue

FromNicolas Ferre <nicolas.ferre@atmel.com>
Date2016-05-13 14:30 +0200
SubjectRe: [PATCH 3/3] dmaengine: at_xdmac: double FIFO flush needed to compute residue
Message-ID<ryko9-3d0-3@gated-at.bofh.it>
In reply to#1400128
Le 12/05/2016 16:54, Ludovic Desroches a écrit :
> Due to the way CUBC register is updated, a double flush is needed to
> compute an accurate residue. First flush aim is to get data from the DMA
> FIFO and second one ensures that we won't report data which are not in
> memory.
> 
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
> Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel
> eXtended DMA Controller driver")
> Cc: stable@vger.kernel.org #v4.1 and later

Reviewed-by: Nicolas Ferre <nicolas.ferre@atmel.com>

> ---
>  drivers/dma/at_xdmac.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
> index b02494e..75bd662 100644
> --- a/drivers/dma/at_xdmac.c
> +++ b/drivers/dma/at_xdmac.c
> @@ -1425,7 +1425,16 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
>  	residue = desc->xfer_size;
>  	/*
>  	 * Flush FIFO: only relevant when the transfer is source peripheral
> -	 * synchronized.
> +	 * synchronized. Flush is needed before reading CUBC because data in
> +	 * the FIFO are not reported by CUBC. Reporting a residue of the
> +	 * transfer length while we have data in FIFO can cause issue.
> +	 * Usecase: atmel USART has a timeout which means I have received
> +	 * characters but there is no more character received for a while. On
> +	 * timeout, it requests the residue. If the data are in the DMA FIFO,
> +	 * we will return a residue of the transfer length. It means no data
> +	 * received. If an application is waiting for these data, it will hang
> +	 * since we won't have another USART timeout without receiving new
> +	 * data.
>  	 */
>  	mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
>  	value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
> @@ -1481,6 +1490,19 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
>  	}
>  
>  	/*
> +	 * Flush FIFO: only relevant when the transfer is source peripheral
> +	 * synchronized. Another flush is needed here because CUBC is updated
> +	 * when the controller sends the data write command. It can lead to
> +	 * report data that are not written in the memory or the device. The
> +	 * FIFO flush ensures that data are really written.
> +	 */
> +	if ((desc->lld.mbr_cfg & mask) == value) {
> +		at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
> +		while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
> +			cpu_relax();
> +	}
> +
> +	/*
>  	 * Remove size of all microblocks already transferred and the current
>  	 * one. Then add the remaining size to transfer of the current
>  	 * microblock.
> 


-- 
Nicolas Ferre

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


#1400764

FromNicolas Ferre <nicolas.ferre@atmel.com>
Date2016-05-13 14:30 +0200
Message-ID<rykoa-3d0-17@gated-at.bofh.it>
In reply to#1400126
Le 12/05/2016 16:54, Ludovic Desroches a écrit :
> Having descriptors aligned on 64 bits allows update CNDA and CUBC in an
> atomic way.
> 
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
> Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel
> eXtended DMA Controller driver")
> Cc: stable@vger.kernel.org #v4.1 and later

Reviewed-by: Nicolas Ferre <nicolas.ferre@atmel.com>

> ---
>  drivers/dma/at_xdmac.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
> index 8e304b1..ba9b0b7 100644
> --- a/drivers/dma/at_xdmac.c
> +++ b/drivers/dma/at_xdmac.c
> @@ -242,7 +242,7 @@ struct at_xdmac_lld {
>  	u32		mbr_dus;	/* Destination Microblock Stride Register */
>  };
>  
> -
> +/* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */
>  struct at_xdmac_desc {
>  	struct at_xdmac_lld		lld;
>  	enum dma_transfer_direction	direction;
> @@ -253,7 +253,7 @@ struct at_xdmac_desc {
>  	unsigned int			xfer_size;
>  	struct list_head		descs_list;
>  	struct list_head		xfer_node;
> -};
> +} __aligned(sizeof(u64));
>  
>  static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb)
>  {
> 


-- 
Nicolas Ferre

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


#1408757

FromVinod Koul <vinod.koul@intel.com>
Date2016-05-30 07:20 +0200
Message-ID<rEnMm-8gg-9@gated-at.bofh.it>
In reply to#1400126
On Thu, May 12, 2016 at 04:54:08PM +0200, Ludovic Desroches wrote:
> Having descriptors aligned on 64 bits allows update CNDA and CUBC in an
> atomic way.

Applied all, thanks

-- 
~Vinod

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web