All of lore.kernel.org
 help / color / mirror / Atom feed
* [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements
@ 2015-01-27 15:30 Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 1/4] dmaengine: at_xdmac: wait for in-progress transaction to complete after pausing a channel Ludovic Desroches
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Ludovic Desroches @ 2015-01-27 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series is based on vkoul/slave-dma/topic/slave_caps_device_control_fix
branch.

Changes from v1:
- put save_cc field addition in a single patch
- update commit log of patch 3/4
- remove AT_XDMAC_CUR_CFG since it is no more used

Cyrille Pitchen (1):
  dmaengine: at_xdmac: wait for in-progress transaction to complete
    after pausing a channel

Ludovic Desroches (3):
  dmaengine: at_xdmac: introduce save_cc field
  dmaengine: at_xdmac: simplify channel configuration stuff
  dmaengine: at_xdmac: allow muliple dwidths when doing slave transfers

 drivers/dma/at_xdmac.c | 60 ++++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 29 deletions(-)

-- 
2.2.0

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

* [RESEND PATCH v2 1/4] dmaengine: at_xdmac: wait for in-progress transaction to complete after pausing a channel
  2015-01-27 15:30 [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Ludovic Desroches
@ 2015-01-27 15:30 ` Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 2/4] dmaengine: at_xdmac: introduce save_cc field Ludovic Desroches
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Ludovic Desroches @ 2015-01-27 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

From: Cyrille Pitchen <cyrille.pitchen@atmel.com>

Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/dma/at_xdmac.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 8c799f6..5e3f072 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1136,9 +1136,14 @@ static int at_xdmac_device_pause(struct dma_chan *chan)
 
 	dev_dbg(chan2dev(chan), "%s\n", __func__);
 
+	if (test_and_set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status))
+		return 0;
+
 	spin_lock_bh(&atchan->lock);
 	at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask);
-	set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
+	while (at_xdmac_chan_read(atchan, AT_XDMAC_CC)
+	       & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP))
+		cpu_relax();
 	spin_unlock_bh(&atchan->lock);
 
 	return 0;
-- 
2.2.0

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

* [RESEND PATCH v2 2/4] dmaengine: at_xdmac: introduce save_cc field
  2015-01-27 15:30 [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 1/4] dmaengine: at_xdmac: wait for in-progress transaction to complete after pausing a channel Ludovic Desroches
@ 2015-01-27 15:30 ` Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 3/4] dmaengine: at_xdmac: simplify channel configuration stuff Ludovic Desroches
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Ludovic Desroches @ 2015-01-27 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

When suspending the device, read the channel configuration directly from
the register instead of relying on a software snapshot, it will be
safer.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/dma/at_xdmac.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 5e3f072..6169f83 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -200,6 +200,7 @@ struct at_xdmac_chan {
 	u8				memif;		/* Memory Interface */
 	u32				per_src_addr;
 	u32				per_dst_addr;
+	u32				save_cc;
 	u32				save_cim;
 	u32				save_cnda;
 	u32				save_cndc;
@@ -1276,6 +1277,7 @@ static int atmel_xdmac_suspend(struct device *dev)
 	list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
 		struct at_xdmac_chan	*atchan = to_at_xdmac_chan(chan);
 
+		atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC);
 		if (at_xdmac_chan_is_cyclic(atchan)) {
 			if (!at_xdmac_chan_is_paused(atchan))
 				at_xdmac_device_pause(chan);
@@ -1298,7 +1300,6 @@ static int atmel_xdmac_resume(struct device *dev)
 	struct at_xdmac_chan	*atchan;
 	struct dma_chan		*chan, *_chan;
 	int			i;
-	u32			cfg;
 
 	clk_prepare_enable(atxdmac->clk);
 
@@ -1313,8 +1314,7 @@ static int atmel_xdmac_resume(struct device *dev)
 	at_xdmac_write(atxdmac, AT_XDMAC_GE, atxdmac->save_gs);
 	list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
 		atchan = to_at_xdmac_chan(chan);
-		cfg = atchan->cfg[AT_XDMAC_CUR_CFG];
-		at_xdmac_chan_write(atchan, AT_XDMAC_CC, cfg);
+		at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc);
 		if (at_xdmac_chan_is_cyclic(atchan)) {
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
-- 
2.2.0

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

* [RESEND PATCH v2 3/4] dmaengine: at_xdmac: simplify channel configuration stuff
  2015-01-27 15:30 [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 1/4] dmaengine: at_xdmac: wait for in-progress transaction to complete after pausing a channel Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 2/4] dmaengine: at_xdmac: introduce save_cc field Ludovic Desroches
@ 2015-01-27 15:30 ` Ludovic Desroches
  2015-01-27 15:30 ` [RESEND PATCH v2 4/4] dmaengine: at_xdmac: allow muliple dwidths when doing slave transfers Ludovic Desroches
  2015-02-05  7:13 ` [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Vinod Koul
  4 siblings, 0 replies; 6+ messages in thread
From: Ludovic Desroches @ 2015-01-27 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

This patch simplifies the channel configuration register management.
Relying on a "software snapshot" of the configuration is not safe and
too complex.

Multiple dwidths will be introduced for slave transfers. In this case,
it becomes quite difficult to have an accurate snapshot of the channel
configuration register in the way it is done. Using the channel
configuration available in the lli descriptor simplifies this stuff.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/dma/at_xdmac.c | 36 ++++++++++++++----------------------
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 6169f83..37aa4a9 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -191,10 +191,9 @@ struct at_xdmac_chan {
 	struct dma_chan			chan;
 	void __iomem			*ch_regs;
 	u32				mask;		/* Channel Mask */
-	u32				cfg[3];		/* Channel Configuration Register */
-	#define	AT_XDMAC_CUR_CFG	0		/* Current channel conf */
-	#define	AT_XDMAC_DEV_TO_MEM_CFG	1		/* Predifined dev to mem channel conf */
-	#define	AT_XDMAC_MEM_TO_DEV_CFG	2		/* Predifined mem to dev channel conf */
+	u32				cfg[2];		/* Channel Configuration Register */
+	#define	AT_XDMAC_DEV_TO_MEM_CFG	0		/* Predifined dev to mem channel conf */
+	#define	AT_XDMAC_MEM_TO_DEV_CFG	1		/* Predifined mem to dev channel conf */
 	u8				perid;		/* Peripheral ID */
 	u8				perif;		/* Peripheral Interface */
 	u8				memif;		/* Memory Interface */
@@ -358,14 +357,7 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan,
 	 */
 	if (is_slave_direction(first->direction)) {
 		reg = AT_XDMAC_CNDC_NDVIEW_NDV1;
-		if (first->direction == DMA_MEM_TO_DEV)
-			atchan->cfg[AT_XDMAC_CUR_CFG] =
-				atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
-		else
-			atchan->cfg[AT_XDMAC_CUR_CFG] =
-				atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
-		at_xdmac_chan_write(atchan, AT_XDMAC_CC,
-				    atchan->cfg[AT_XDMAC_CUR_CFG]);
+		at_xdmac_chan_write(atchan, AT_XDMAC_CC, first->lld.mbr_cfg);
 	} else {
 		/*
 		 * No need to write AT_XDMAC_CC reg, it will be done when the
@@ -569,7 +561,6 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	struct at_xdmac_desc	*first = NULL, *prev = NULL;
 	struct scatterlist	*sg;
 	int			i;
-	u32			cfg;
 	unsigned int		xfer_size = 0;
 
 	if (!sgl)
@@ -616,17 +607,17 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		if (direction == DMA_DEV_TO_MEM) {
 			desc->lld.mbr_sa = atchan->per_src_addr;
 			desc->lld.mbr_da = mem;
-			cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
+			desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
 		} else {
 			desc->lld.mbr_sa = mem;
 			desc->lld.mbr_da = atchan->per_dst_addr;
-			cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
+			desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
 		}
-		desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1		/* next descriptor view */
-			| AT_XDMAC_MBR_UBC_NDEN				/* next descriptor dst parameter update */
-			| AT_XDMAC_MBR_UBC_NSEN				/* next descriptor src parameter update */
-			| (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE)	/* descriptor fetch */
-			| len / (1 << at_xdmac_get_dwidth(cfg));	/* microblock length */
+		desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1			/* next descriptor view */
+			| AT_XDMAC_MBR_UBC_NDEN					/* next descriptor dst parameter update */
+			| AT_XDMAC_MBR_UBC_NSEN					/* next descriptor src parameter update */
+			| (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE)		/* descriptor fetch */
+			| len / (1 << at_xdmac_get_dwidth(desc->lld.mbr_cfg));	/* microblock length */
 		dev_dbg(chan2dev(chan),
 			 "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n",
 			 __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc);
@@ -890,7 +881,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	enum dma_status		ret;
 	int			residue;
 	u32			cur_nda, mask, value;
-	u8			dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]);
+	u8			dwidth = 0;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_COMPLETE)
@@ -920,7 +911,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	 */
 	mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
 	value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
-	if ((atchan->cfg[AT_XDMAC_CUR_CFG] & mask) == value) {
+	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();
@@ -934,6 +925,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	 */
 	descs_list = &desc->descs_list;
 	list_for_each_entry_safe(desc, _desc, descs_list, desc_node) {
+		dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg);
 		residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth;
 		if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda)
 			break;
-- 
2.2.0

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

* [RESEND PATCH v2 4/4] dmaengine: at_xdmac: allow muliple dwidths when doing slave transfers
  2015-01-27 15:30 [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Ludovic Desroches
                   ` (2 preceding siblings ...)
  2015-01-27 15:30 ` [RESEND PATCH v2 3/4] dmaengine: at_xdmac: simplify channel configuration stuff Ludovic Desroches
@ 2015-01-27 15:30 ` Ludovic Desroches
  2015-02-05  7:13 ` [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Vinod Koul
  4 siblings, 0 replies; 6+ messages in thread
From: Ludovic Desroches @ 2015-01-27 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

When using FIFO, we need to support differents data width in a single
transfer. For example, serial device which usually uses 1-byte data
width will use 4-bytes data width when using the FIFO. If the transfer
size is not aligned on 4-bytes then the end of the transfer will be
performed with 1-byte data-width. For that reason,
at_xdmac_prep_slave_sg() now builds linked list descriptors using view 2
instead of view 1 so each of them can update the DWIDTH field into the
Channel Configuration Register.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/dma/at_xdmac.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 37aa4a9..710546d 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -25,6 +25,7 @@
 #include <linux/dmapool.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of_dma.h>
@@ -351,11 +352,11 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan,
 	at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, reg);
 
 	/*
-	 * When doing memory to memory transfer we need to use the next
+	 * When doing non cyclic transfer we need to use the next
 	 * descriptor view 2 since some fields of the configuration register
 	 * depend on transfer size and src/dest addresses.
 	 */
-	if (is_slave_direction(first->direction)) {
+	if (at_xdmac_chan_is_cyclic(atchan)) {
 		reg = AT_XDMAC_CNDC_NDVIEW_NDV1;
 		at_xdmac_chan_write(atchan, AT_XDMAC_CC, first->lld.mbr_cfg);
 	} else {
@@ -582,7 +583,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	/* Prepare descriptors. */
 	for_each_sg(sgl, sg, sg_len, i) {
 		struct at_xdmac_desc	*desc = NULL;
-		u32			len, mem;
+		u32			len, mem, dwidth, fixed_dwidth;
 
 		len = sg_dma_len(sg);
 		mem = sg_dma_address(sg);
@@ -613,11 +614,15 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 			desc->lld.mbr_da = atchan->per_dst_addr;
 			desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
 		}
-		desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1			/* next descriptor view */
+		dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg);
+		fixed_dwidth = IS_ALIGNED(len, 1 << dwidth)
+			       ? at_xdmac_get_dwidth(desc->lld.mbr_cfg)
+			       : AT_XDMAC_CC_DWIDTH_BYTE;
+		desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV2			/* next descriptor view */
 			| AT_XDMAC_MBR_UBC_NDEN					/* next descriptor dst parameter update */
 			| AT_XDMAC_MBR_UBC_NSEN					/* next descriptor src parameter update */
 			| (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE)		/* descriptor fetch */
-			| len / (1 << at_xdmac_get_dwidth(desc->lld.mbr_cfg));	/* microblock length */
+			| (len >> fixed_dwidth);				/* microblock length */
 		dev_dbg(chan2dev(chan),
 			 "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n",
 			 __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc);
-- 
2.2.0

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

* [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements
  2015-01-27 15:30 [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Ludovic Desroches
                   ` (3 preceding siblings ...)
  2015-01-27 15:30 ` [RESEND PATCH v2 4/4] dmaengine: at_xdmac: allow muliple dwidths when doing slave transfers Ludovic Desroches
@ 2015-02-05  7:13 ` Vinod Koul
  4 siblings, 0 replies; 6+ messages in thread
From: Vinod Koul @ 2015-02-05  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 27, 2015 at 04:30:28PM +0100, Ludovic Desroches wrote:
> Hi,
> 
> This series is based on vkoul/slave-dma/topic/slave_caps_device_control_fix
> branch.
> 
> Changes from v1:
> - put save_cc field addition in a single patch
> - update commit log of patch 3/4
> - remove AT_XDMAC_CUR_CFG since it is no more used
Applied, thanks

-- 
~Vinod

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

end of thread, other threads:[~2015-02-05  7:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-27 15:30 [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Ludovic Desroches
2015-01-27 15:30 ` [RESEND PATCH v2 1/4] dmaengine: at_xdmac: wait for in-progress transaction to complete after pausing a channel Ludovic Desroches
2015-01-27 15:30 ` [RESEND PATCH v2 2/4] dmaengine: at_xdmac: introduce save_cc field Ludovic Desroches
2015-01-27 15:30 ` [RESEND PATCH v2 3/4] dmaengine: at_xdmac: simplify channel configuration stuff Ludovic Desroches
2015-01-27 15:30 ` [RESEND PATCH v2 4/4] dmaengine: at_xdmac: allow muliple dwidths when doing slave transfers Ludovic Desroches
2015-02-05  7:13 ` [RESEND PATCH v2 0/4] dmaengine: at_xdmac: several improvements Vinod Koul

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.