Sfoglia il codice sorgente

dmaengine: at_hdmac: add FIFO configuration parameter to DMA DT binding

For most devices the FIFO configuration is the same i.e. when half FIFO size is
available/filled, a source/destination request is serviced. But USART devices
have to do it when there is enough space/data available to perform a single
AHB access so the ASAP configuration.

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Ludovic Desroches 12 anni fa
parent
commit
62971b2982

+ 5 - 2
Documentation/devicetree/bindings/dma/atmel-dma.txt

@@ -24,8 +24,11 @@ The three cells in order are:
 1. A phandle pointing to the DMA controller.
 1. A phandle pointing to the DMA controller.
 2. The memory interface (16 most significant bits), the peripheral interface
 2. The memory interface (16 most significant bits), the peripheral interface
 (16 less significant bits).
 (16 less significant bits).
-3. The peripheral identifier for the hardware handshaking interface. The
-identifier can be different for tx and rx.
+3. Parameters for the at91 DMA configuration register which are device
+dependant:
+  - bit 7-0: peripheral identifier for the hardware handshaking interface. The
+  identifier can be different for tx and rx.
+  - bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 1 for ASAP.
 
 
 Example:
 Example:
 
 

+ 21 - 4
drivers/dma/at_hdmac.c

@@ -14,6 +14,7 @@
  * found on AT91SAM9263.
  * found on AT91SAM9263.
  */
  */
 
 
+#include <dt-bindings/dma/at91.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
@@ -1320,15 +1321,31 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
 	atslave = devm_kzalloc(&dmac_pdev->dev, sizeof(*atslave), GFP_KERNEL);
 	atslave = devm_kzalloc(&dmac_pdev->dev, sizeof(*atslave), GFP_KERNEL);
 	if (!atslave)
 	if (!atslave)
 		return NULL;
 		return NULL;
+
+	atslave->cfg = ATC_DST_H2SEL_HW | ATC_SRC_H2SEL_HW;
 	/*
 	/*
 	 * We can fill both SRC_PER and DST_PER, one of these fields will be
 	 * We can fill both SRC_PER and DST_PER, one of these fields will be
 	 * ignored depending on DMA transfer direction.
 	 * ignored depending on DMA transfer direction.
 	 */
 	 */
-	per_id = dma_spec->args[1];
-	atslave->cfg = ATC_FIFOCFG_HALFFIFO
-		     | ATC_DST_H2SEL_HW | ATC_SRC_H2SEL_HW
-		     | ATC_DST_PER_MSB(per_id) | ATC_DST_PER(per_id)
+	per_id = dma_spec->args[1] & AT91_DMA_CFG_PER_ID_MASK;
+	atslave->cfg |= ATC_DST_PER_MSB(per_id) | ATC_DST_PER(per_id)
 		     | ATC_SRC_PER_MSB(per_id) | ATC_SRC_PER(per_id);
 		     | ATC_SRC_PER_MSB(per_id) | ATC_SRC_PER(per_id);
+	/*
+	 * We have to translate the value we get from the device tree since
+	 * the half FIFO configuration value had to be 0 to keep backward
+	 * compatibility.
+	 */
+	switch (dma_spec->args[1] & AT91_DMA_CFG_FIFOCFG_MASK) {
+	case AT91_DMA_CFG_FIFOCFG_ALAP:
+		atslave->cfg |= ATC_FIFOCFG_LARGESTBURST;
+		break;
+	case AT91_DMA_CFG_FIFOCFG_ASAP:
+		atslave->cfg |= ATC_FIFOCFG_ENOUGHSPACE;
+		break;
+	case AT91_DMA_CFG_FIFOCFG_HALF:
+	default:
+		atslave->cfg |= ATC_FIFOCFG_HALFFIFO;
+	}
 	atslave->dma_dev = &dmac_pdev->dev;
 	atslave->dma_dev = &dmac_pdev->dev;
 
 
 	chan = dma_request_channel(mask, at_dma_filter, atslave);
 	chan = dma_request_channel(mask, at_dma_filter, atslave);