Colibri V61 SPI DMA on Linux 4.4.39

Hi.

I did a test run today with the latest Colibri V61 Linux kernel (4.4.39). I was mostly interested to test out the SPI DMA support.

I ran in to a problem:

[    0.239066] fsl-dspi 4002c000.dspi0: rx dma channel not available
[    0.245272] fsl-dspi 4002c000.dspi0: can't get dma channels
[    0.246914] fsl-dspi 4002d000.dspi1: rx dma channel not available
[    0.253101] fsl-dspi 4002d000.dspi1: can't get dma channels

My custom board use dspi1 to communicate with an MCP2515 and dsp0 is used to communicate with an multipurpose chip. And above warnings mean that it falls back to not using DMA. Argh… :slight_smile:

Did some hacking and this diff fixes the above:

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index bf4e804..5d7a418 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -220,8 +220,8 @@
                                clocks = <&clks VF610_CLK_DSPI0>;
                                clock-names = "dspi";
                                spi-num-chipselects = <6>;
-                               dmas = <&edma1 1 12>,
-                                       <&edma1 1 13>;
+                               dmas = <&edma0 0 12>,
+                                       <&edma0 0 13>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
@@ -235,8 +235,8 @@
                                clocks = <&clks VF610_CLK_DSPI1>;
                                clock-names = "dspi";
                                spi-num-chipselects = <4>;
-                               dmas = <&edma1 1 14>,
-                                       <&edma1 1 15>;
+                               dmas = <&edma0 0 14>,
+                                       <&edma0 0 15>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };

Opened up the vybrid reference manual 3.3 DMAMUX Request Sources because I made the above changes blindly and above seems correct to me. Also looking at dspi2 and dspi3, they seem wrong.

The complete diff (have not tested dspi2 and dspi3 though):

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index bf4e804..01f66cb 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -220,8 +220,8 @@
                                clocks = <&clks VF610_CLK_DSPI0>;
                                clock-names = "dspi";
                                spi-num-chipselects = <6>;
-                               dmas = <&edma1 1 12>,
-                                       <&edma1 1 13>;
+                               dmas = <&edma0 0 12>,
+                                       <&edma0 0 13>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
@@ -235,8 +235,8 @@
                                clocks = <&clks VF610_CLK_DSPI1>;
                                clock-names = "dspi";
                                spi-num-chipselects = <4>;
-                               dmas = <&edma1 1 14>,
-                                       <&edma1 1 15>;
+                               dmas = <&edma0 0 14>,
+                                       <&edma0 0 15>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
@@ -636,8 +636,8 @@
                                clocks = <&clks VF610_CLK_DSPI2>;
                                clock-names = "dspi";
                                spi-num-chipselects = <2>;
-                               dmas = <&edma1 0 10>,
-                                       <&edma1 0 11>;
+                               dmas = <&edma0 1 10>,
+                                       <&edma0 1 11>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
@@ -651,8 +651,8 @@
                                clocks = <&clks VF610_CLK_DSPI3>;
                                clock-names = "dspi";
                                spi-num-chipselects = <2>;
-                               dmas = <&edma1 0 12>,
-                                       <&edma1 0 13>;
+                               dmas = <&edma0 1 12>,
+                                       <&edma0 1 13>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };

Am I reading the manual wrong or I am correct? :slight_smile:

Best Regards
Mirza

Do you use our stock 4.4 branch without any other changes? I tried it here with the following diff changes

diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index a5f8bf2f32a7..36d91cf06389 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -70,6 +70,7 @@
                compatible = "gpio-keys";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_gpiokeys>;
+               status = "disabled";
 
                power {
                        label = "Wake-Up";
@@ -95,15 +96,24 @@
        status = "okay";
 };
 
-&dspi1 {
+&dspi0 {
        status = "okay";
 
-
        spidev0: spidev@0 {
                compatible = "toradex,evalspi";
                reg = <0>;
                spi-max-frequency = <50000000>;
        };
+};
+
+&dspi1 {
+       status = "okay";
+
+       spidev1: spidev@1 {
+               compatible = "toradex,evalspi";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+       };
 
        mcp2515can: can@0 {
                compatible = "microchip,mcp2515";
@@ -118,11 +128,31 @@
        };
 };
 
+&dspi2 {
+       status = "okay";
+
+       spidev2: spidev@2 {
+               compatible = "toradex,evalspi";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+       };
+};
+
+&dspi3 {
+       status = "okay";
+
+       spidev3: spidev@3 {
+               compatible = "toradex,evalspi";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+       };
+};
+
 &esdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_esdhc1>;
        bus-width = <4>;
-       status = "okay";
+       status = "disabled";
 };
 
 &fec1 {
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index 6918679fba83..2418351cc62f 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -63,12 +63,30 @@
                                 <&clks VF610_CLK_ENET_50M>;
 };
 
+&dspi0 {
+       bus-num = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dspi0>;
+};
+
 &dspi1 {
        bus-num = <1>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_dspi1>;
 };
 
+&dspi2 {
+       bus-num = <2>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dspi2>;
+};
+
+&dspi3 {
+       bus-num = <3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dspi3>;
+};
+
 &edma0 {
        status = "okay";
 };
@@ -263,6 +281,15 @@
                        >;
                };
 
+               pinctrl_dspi0: dspi0grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB19__DSPI0_CS0      0x33e2
+                               VF610_PAD_PTB20__DSPI0_SIN      0x33e1
+                               VF610_PAD_PTB21__DSPI0_SOUT     0x33e2
+                               VF610_PAD_PTB22__DSPI0_SCK      0x33e2
+                       >;
+               };
+
                pinctrl_dspi1: dspi1grp {
                        fsl,pins = <
                                VF610_PAD_PTD5__DSPI1_CS0               0x33e2
@@ -272,6 +299,24 @@
                        >;
                };
 
+               pinctrl_dspi2: dspi2grp {
+                       fsl,pins = <
+                               VF610_PAD_PTD30__DSPI2_CS0      0x33e2
+                               VF610_PAD_PTD29__DSPI2_SIN      0x33e1
+                               VF610_PAD_PTD28__DSPI2_SOUT     0x33e2
+                               VF610_PAD_PTD27__DSPI2_SCK      0x33e2
+                       >;
+               };
+
+               pinctrl_dspi3: dspi3grp {
+                       fsl,pins = <
+                               VF610_PAD_PTD10__DSPI3_CS0      0x33e2
+                               VF610_PAD_PTD11__DSPI3_SIN      0x33e1
+                               VF610_PAD_PTD12__DSPI3_SOUT     0x33e2
+                               VF610_PAD_PTD13__DSPI3_SCK      0x33e2
+                       >;
+               };
+
                pinctrl_esdhc1: esdhc1grp {
                        fsl,pins = <
                                VF610_PAD_PTA24__ESDHC1_CLK     0x31ef

I do not see any “DMA channel not available message” in the logs.

root@colibri-vf:~# dmesg | grep -i "spi"
root@colibri-vf:~# dmesg | grep -i "dma"
[    0.085160] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.144183] i2c i2c-0: using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers
root@colibri-vf:~# dmesg | grep -i "dspi"                  

and all spidev are in place.

root@colibri-vf:~# ls /dev | grep -i "spidev"
spidev0.0
spidev1.0
spidev2.0
spidev3.0

I am using the 4.4 stock kernel but I do have a custom device tree.

And I found the problem, it is in my device tree.

edma1 was not was not enabled. I enabled it and now I do not get any errors.

Sorry for the noise.

We descided using edma1 for SPI since we at one point thought we saw interference between UART and SPI DMA usage. I think it ended up being a bug in the UART DMA implementation. So as far as I know, either should work fine… But since we have a second DMA controller, we might as well use it…