aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt56
-rw-r--r--drivers/dma/imx-sdma.c40
2 files changed, 96 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
index d1e3f443e20..68cee4f5539 100644
--- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
@@ -4,14 +4,70 @@ Required properties:
- compatible : Should be "fsl,<chip>-sdma"
- reg : Should contain SDMA registers location and length
- interrupts : Should contain SDMA interrupt
+- #dma-cells : Must be <3>.
+ The first cell specifies the DMA request/event ID. See details below
+ about the second and third cell.
- fsl,sdma-ram-script-name : Should contain the full path of SDMA RAM
scripts firmware
+The second cell of dma phandle specifies the peripheral type of DMA transfer.
+The full ID of peripheral types can be found below.
+
+ ID transfer type
+ ---------------------
+ 0 MCU domain SSI
+ 1 Shared SSI
+ 2 MMC
+ 3 SDHC
+ 4 MCU domain UART
+ 5 Shared UART
+ 6 FIRI
+ 7 MCU domain CSPI
+ 8 Shared CSPI
+ 9 SIM
+ 10 ATA
+ 11 CCM
+ 12 External peripheral
+ 13 Memory Stick Host Controller
+ 14 Shared Memory Stick Host Controller
+ 15 DSP
+ 16 Memory
+ 17 FIFO type Memory
+ 18 SPDIF
+ 19 IPU Memory
+ 20 ASRC
+ 21 ESAI
+
+The third cell specifies the transfer priority as below.
+
+ ID transfer priority
+ -------------------------
+ 0 High
+ 1 Medium
+ 2 Low
+
Examples:
sdma@83fb0000 {
compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
reg = <0x83fb0000 0x4000>;
interrupts = <6>;
+ #dma-cells = <3>;
fsl,sdma-ram-script-name = "sdma-imx51.bin";
};
+
+DMA clients connected to the i.MX SDMA controller must use the format
+described in the dma.txt file.
+
+Examples:
+
+ssi2: ssi@70014000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x70014000 0x4000>;
+ interrupts = <30>;
+ clocks = <&clks 49>;
+ dmas = <&sdma 24 1 0>,
+ <&sdma 25 1 0>;
+ dma-names = "rx", "tx";
+ fsl,fifo-depth = <15>;
+};
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 092867bf795..1e44b8cf95d 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -36,6 +36,7 @@
#include <linux/dmaengine.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_dma.h>
#include <asm/irq.h>
#include <linux/platform_data/dma-imx-sdma.h>
@@ -1296,6 +1297,35 @@ err_dma_alloc:
return ret;
}
+static bool sdma_filter_fn(struct dma_chan *chan, void *fn_param)
+{
+ struct imx_dma_data *data = fn_param;
+
+ if (!imx_dma_is_general_purpose(chan))
+ return false;
+
+ chan->private = data;
+
+ return true;
+}
+
+static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct sdma_engine *sdma = ofdma->of_dma_data;
+ dma_cap_mask_t mask = sdma->dma_device.cap_mask;
+ struct imx_dma_data data;
+
+ if (dma_spec->args_count != 3)
+ return NULL;
+
+ data.dma_request = dma_spec->args[0];
+ data.peripheral_type = dma_spec->args[1];
+ data.priority = dma_spec->args[2];
+
+ return dma_request_channel(mask, sdma_filter_fn, &data);
+}
+
static int __init sdma_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
@@ -1443,10 +1473,20 @@ static int __init sdma_probe(struct platform_device *pdev)
goto err_init;
}
+ if (np) {
+ ret = of_dma_controller_register(np, sdma_xlate, sdma);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register controller\n");
+ goto err_register;
+ }
+ }
+
dev_info(sdma->dev, "initialized\n");
return 0;
+err_register:
+ dma_async_device_unregister(&sdma->dma_device);
err_init:
kfree(sdma->script_addrs);
err_alloc: