Skip to contentSkip to conversation

dw_dmac: max_mem_width limits value for SRC/DST_TR_WID register

PATCH Superseded Hein Tibosch 3 participants 4 messages Aug 26, 2012 – Aug 31, 2012 1 message not in the archive dmaengine

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 dw_dmac: max_mem_width limits value for SRC/DST_TR_WID register

The dw_dmac driver was earlier adapted to do 64-bit transfers on the memory side (https://lkml.org/lkml/2012/1/18/52)
This works on ARM platforms but for AVR32 (AP700x) the maximum allowed transfer size is 32-bits.
This patch allows the arch to set a new slave property max_mem_width to limit the size.
Allowable values for dw_dma_slave::max_mem_width are:

0 : leave it up to dw_dmac (64 bits)
1 : 16-bits
2 : 32-bits

---
 drivers/dma/dw_dmac.c   |    8 ++++++++
 include/linux/dw_dmac.h |    3 +++
 2 files changed, 11 insertions(+), 0 deletions(-)
drivers/dma/dw_dmac.c +8 -0
index 7212961..a4bdf1d 100644
@@ -754,6 +754,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 				mem_width = 1;
 			else
 				mem_width = 0;
+			/* Some controllers don't support 64-bits mem access */
+			if (dws->max_mem_width &&
+				mem_width > dws->max_mem_width)
+				mem_width = dws->max_mem_width;
 
 slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -821,6 +825,10 @@ slave_sg_todev_fill_desc:
 				mem_width = 1;
 			else
 				mem_width = 0;
+			/* Some controllers don't support 64-bits mem access */
+			if (dws->max_mem_width &&
+				mem_width > dws->max_mem_width)
+				mem_width = dws->max_mem_width;
 
 slave_sg_fromdev_fill_desc:
 			desc = dwc_desc_get(dwc);
include/linux/dw_dmac.h +3 -0
index 2412e02..60b01c3 100644
@@ -51,6 +51,8 @@ enum dw_dma_msize {
  * @cfg_lo: Platform-specific initializer for the CFG_LO register
  * @src_master: src master for transfers on allocated channel.
  * @dst_master: dest master for transfers on allocated channel.
+ * @max_mem_width: max value for SRC/DST_TR_WIDTH register
+ *	default 0 means: leave it up to driver
  */
 struct dw_dma_slave {
 	struct device		*dma_dev;
@@ -58,6 +60,7 @@ struct dw_dma_slave {
 	u32			cfg_lo;
 	u8			src_master;
 	u8			dst_master;
+	u8			max_mem_width;
 };
 
 /* Platform-configurable bits in CFG_HI */
Signature · 1 line
1.7.8.0

A message that is not in the archive (sent off-list or not yet received): CAKohpontcFpMiju1LwO3fL43Oud0jAixYf8ZNN+6-hTj35ownA@mail.gmail.com

#2 lore raw
Quoted 18 lines · Viresh Kumar

On 27 August 2012 02:11, Hein Tibosch <[email protected] <mailto:[email protected]>> wrote:

The dw_dmac driver was earlier adapted to do 64-bit transfers on the memory side (https://lkml.org/lkml/2012/1/18/52)
This works on ARM platforms but for AVR32 (AP700x) the maximum allowed transfer size is 32-bits.
This patch allows the arch to set a new slave property max_mem_width to limit the size.
Allowable values for dw_dma_slave::max_mem_width are:

0 : leave it up to dw_dmac (64 bits)
1 : 16-bits
2 : 32-bits

Either this should be in increasing order or decreasing. That will make it more sensible, isn't it?

Quoted 9 lines

So it should be:
0-64bit
1-32bit
2-16bit

Also, i am not sure if we should actually support 16 bit here at all. Maybe nobody will have 16 bit requirement. So can remove it for now. If in future it is required then can accept that.

Viresh,

If you're OK with the version below, I'll send both dw_dmac patches again as v2

Now cc Vinod Koul and Dan Williams

The dw_dmac driver was earlier adapted to do 64-bit transfers on the memory side (https://lkml.org/lkml/2012/1/18/52)
This works on ARM platforms but for AVR32 (AP700x) the maximum allowed transfer size is 32-bits.

A new 'automatic' config item 'DW_DMAC_MEM_64_BIT' determines if 64-bit memory transfers are allowed. This boolean will be defined on non-AVR32 platforms

No arch code will have to be changed to make this patch work.

---
 drivers/dma/Kconfig   |    8 ++++++++
 drivers/dma/dw_dmac.c |   15 ++++++++++++---
 2 files changed, 20 insertions(+), 3 deletions(-)
drivers/dma/Kconfig +8 -0
index 3635daf..82e958f 100644
@@ -97,6 +97,14 @@ config DW_DMAC_BE
 	  Say yes if access to the Synopsys DesignWare AHB DMA controller
 	  should be big endian, such as for Atmel AT32ap7000
 
+config DW_DMAC_MEM_64_BIT
+	bool "Allow Synopsys DesignWare AHB DMA to do 64-bit mem transfers"
+	default y if !AVR32
+	depends on DW_DMAC
+	help
+	  Say yes if the Synopsys DesignWare AHB DMA controller may do
+	  64-bit memory transfers
+
 config AT_HDMAC
 	tristate "Atmel AHB DMA support"
 	depends on ARCH_AT91
drivers/dma/dw_dmac.c +12 -3
index 7212961..2be010c 100644
@@ -639,9 +639,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	 * We can be a lot more clever here, but this should take care
 	 * of the most common optimization.
 	 */
+#ifdef	DW_DMAC_MEM_64_BIT
 	if (!((src | dest  | len) & 7))
 		src_width = dst_width = 3;
-	else if (!((src | dest  | len) & 3))
+	else
+#endif
+	if (!((src | dest  | len) & 3))
 		src_width = dst_width = 2;
 	else if (!((src | dest | len) & 1))
 		src_width = dst_width = 1;
@@ -746,9 +749,12 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
+#ifdef	DW_DMAC_MEM_64_BIT
 			if (!((mem | len) & 7))
 				mem_width = 3;
-			else if (!((mem | len) & 3))
+			else
+#endif
+			if (!((mem | len) & 3))
 				mem_width = 2;
 			else if (!((mem | len) & 1))
 				mem_width = 1;
@@ -813,9 +819,12 @@ slave_sg_todev_fill_desc:
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
+#ifdef	DW_DMAC_MEM_64_BIT
 			if (!((mem | len) & 7))
 				mem_width = 3;
-			else if (!((mem | len) & 3))
+			else
+#endif
+			if (!((mem | len) & 3))
 				mem_width = 2;
 			else if (!((mem | len) & 1))
 				mem_width = 1;
Signature · 1 line
1.7.8.0
#3 lore raw
Quoted 4 lines · Hein Tibosch

Viresh,

If you're OK with the version below, I'll send both dw_dmac patches again as v2

Yes, they look fine.

viresh

#4 lore raw
In reply to Hein Tibosch
Quoted 8 lines · On Mon, 27 Aug 2012 04:41:04 +0800 Hein Tibosch <[email protected]> wrote:

The dw_dmac driver was earlier adapted to do 64-bit transfers on the memory side (https://lkml.org/lkml/2012/1/18/52)
This works on ARM platforms but for AVR32 (AP700x) the maximum allowed transfer size is 32-bits.
This patch allows the arch to set a new slave property max_mem_width to limit the size.
Allowable values for dw_dma_slave::max_mem_width are:

This patch fails to apply to mainline and to linux-next and I can't work out how to make it to apply to either. And "avr32-linux:
at32ap700x: set DMA slave properties for MCI dw_dmac" is said to depend on this patch.

All confused, giving up.