SPI slave mode for imx6ULL CoM

Hi,
I am using Colibri imx6ULL CoM in my project. In that, we have two linux systems one in SPI master and the other in SPI slave mode. I just have some question regarding the slave mode option.

Does spidev driver maintained by toradex support SPI in slave mode? I believe imx6ULL does support slave mode, but I am not sure how to make the mode change or is it supported out-of-the-box. I am new to embedded Linux, so if that’s possible kindly explain the procedure.

Hi @SurriyaLuavan,

Checking here at the kernel modules that are enabled by default, I can see that the master is enabled and the slave is disabled:

root@colibri-imx6ull-06388420:~# zcat /proc/config.gz | grep SLAVE
# CONFIG_I2C_SLAVE is not set
# CONFIG_SPI_SLAVE is not set
root@colibri-imx6ull-06388420:~# zcat /proc/config.gz | grep MASTER
# CONFIG_NET_L3_MASTER_DEV is not set
# CONFIG_MTD_PARTITIONED_MASTER is not set
CONFIG_SPI_MASTER=y
# CONFIG_HID_THRUSTMASTER is not set

In order to enable the slave mode, you will need to compile a new kernel with the CONFIG_SPI_MASTER disabled and CONFIG_SPI_SLAVE enabled. This should fix your problem.

Let me know if you need anything else.

Best regards,
Hiago.

I couldn’t disable CONFIG_SPI_MASTER. I’ve tried several different techniques to use my own default config with SPI_MASTER=n. But, SPI_MASTER gets overwritten by the build. If I set other configs I can see that it’s getting reflected (CONFIG_SPI_SLAVE, CONFIG_SPI_SLAVE_SYSTEM_CONTROL etc…).

This is my current setting:

recipes-kernel
└── linux
├── linux-toradex
│ ├── defconfig
│ └── imx6ull-colibri-SASI-v1.dts
└── linux-toradex_%.bbappend

Contents of linux-toradex_%.bbappend:
FILESEXTRAPATHS_prepend := “${THISDIR}/linux-toradex:”

unset KBUILD_DEFCONFIG

CUSTOM_DEVICETREE = “imx6ull-colibri-SASI-v1.dts”

SRC_URI += "\
file://${CUSTOM_DEVICETREE}
file://defconfig
"

do_configure_append() {
# For arm32 bit devices
cp ${WORKDIR}/${CUSTOM_DEVICETREE} ${S}/arch/arm/boot/dts
# For arm64 bit freescale/NXP devices
# cp ${WORKDIR}/${CUSTOM_DEVICETREE} ${S}/arch/arm64/boot/dts/freescale
}

Other details:

  1. My layer has the highest priority
  2. I could not find SPI_MASTER in menuconfig either.

Hi @SurriyaLuavan,

Using our linux-toradex (linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules), branch toradex_5.4-2.3.x-imx which is our branch for the downstream kernel, I could find these configs in menuconfig. Just search for SPI_MASTER and SPI_SLAVE.

SPI_SLAVE I could easily enable by setting

---> device drivers
        ---> SPI Support
                [*] SPI Slave protocol handlers

However, I couldn’t disable the SPI_MASTER too.
Could you please enable only the SPI Slave protocol handlers and check if this is enough? Unfortunately, I don’t have any hardware with SPI to test this right now.

Your custom meta-layer seems right to me, remember that the folder linux-toradex should be inside the linux folder, here is an example from my side:

.
├── conf
│   ├── layer.conf
│   └── machine
│       └── colibri-imx6ull-extra.conf
├── COPYING.MIT
├── README
├── recipes-bsp
│   └── u-boot
│       └── u-boot-toradex_%.bbappend
├── recipes-example
│   └── example
│       └── example_0.1.bb
└── recipes-kernel
    └── linux
        ├── linux-toradex
        │   └── imx6ull-colibri-iris-v2-custom.dts
        │   └── defconfig
        └── linux-toradex%.bbappend

Also, I’ve found this good documentation about SPI in the Linux kernel: linux/spi-summary.rst at master · torvalds/linux · GitHub

Best regards,
Hiago.

Hi @hfranco.tx,

Thank you for your quick response. As you have mentioned, I have the linux-toradex inside linux folder and I can see other changes I have made custom config file such as CONFIG_SPI_SLAVE, CONFIG_SPI_DEBUG getting reflected.

I enabled SPI_SLAVE option and tired doing a spidev_test: first I ran the spidev_test from the slave device so that the FIFO will have the data. As soon as the master sends the data, the slave should be able to send the message from it’s end. But the message didn’t go through and hanged at the slave:

root@colibri-imx6ull-06764338:~# spidev_test -D /dev/spidev0.0 -p “SLAVE_HELLO_TO_MASTER” -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
^C
[ 353.574605] spidev spi0.0: SPI transfer failed: -4
[ 353.579893] spi_slave spi0: failed to transfer one message from queue

root@colibri-imx6ull-06764338:~# spidev_test -D /dev/spidev0.0 -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)

This is my dmesg output for spi:

root@colibri-imx6ull-06764338:~# dmesg | grep spi
[ 1.611538] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.244455] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.260039] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.261089] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 11.623166] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 11.763420] spi_imx 2008000.spi: registered slave spi0
[ 11.788439] spi_slave spi0: /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0 is not called ‘slave’
[ 11.802239] spi_slave spi0: Failed to create SPI device for /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0
[ 12.055306] spi spi0.0: spi_imx_setup: mode 0, 8 bpw, 0 hz
[ 12.055349] spi spi0.0: setup mode 0, 8 bits/w, 0 Hz max → 0
[ 12.067312] spi_imx 2008000.spi: registered child spi0.0
[ 12.067333] spi_imx 2008000.spi: probed

FYI, this is my device tree definition of spi for the slave device:

&ecspi1 {
	pinctrl-0 = <&pinctrl_ecspi1_cs &pinctrl_ecspi1>;
	status = "okay";
	spi-slave;
	
	slave@0 {
		compatible = "toradex,evalspi";
		spi-max-frequency = <20000000>;
		reg = <0>;
		status = "okay";
	};
};

pinctrl_ecspi1_cs: ecspi1-cs-grp {
			fsl,pins = <
				MX6UL_PAD_LCD_DATA21__ECSPI1_SS0	0x70a0 /* SODIMM 86 */
			>;
		};

pinctrl_ecspi1: ecspi1-grp {
			fsl,pins = <
				MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK	0x000a0 /* SODIMM 88 */
				MX6UL_PAD_LCD_DATA23__ECSPI1_MISO	0x100a0 /* SODIMM 90 */
				MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI	0x000a0 /* SODIMM 92 */	
			>;
};

I am not sure if this is because both the the SPI_MASTER and SPI_SLAVE option are set.

Hi @SurriyaLuavan,

The device tree is looking fine for me. I’m still trying to get it working here on my side, but I’m getting the same error as you mentioned.
I looked into the NXP community, and I found this thread: https://community.nxp.com/t5/i-MX-Processors/ECSPI-Slave-Mode-TXFIFO-problem/m-p/967962

Apparently, there is an error on iMX6ULL, and slave mode isn’t working. You can check it here: https://www.nxp.com/docs/en/errata/IMX6ULLCE.pdf

I don’t know if this is still valid or not, I’ll need to investigate a little bit more. However, this is not good news. I’ll let you know if I get something here on my side.

Could you please also open a ticket in the NXP community?

Best regards,
Hiago.

Hi @hfranco.tx,

Actually, the data sent from the slave is being received at the master, but, the data is spaced out with empty bits and takes 4 times the data to be sent from the master to receive the data from slave. I.e., For ex, I have to send 64 bytes from master to get the 16 bytes of data from the slave, and the data received also misses some data and is filled with empty bits in between. I’ll attach the screenshot of the master and slave console during testing to give you a better picture of what’s happening.

The one to the left is master and the one to the right is slave. These results are repeatable and there is a pattern that I could see. I have adjusted the maximum frequency in both the device tree and spidev_test arguments, but can see the same thing happening. Is this a hardware limitation or am I missing something here?

Hi @SurriyaLuavan,

There is no hardware limitation that I’m aware of. I’ll need to try this on my side, can you send me your entire device tree? With that, I will be able to take a deeper look into this problem.

Did you check the SPI frequency on both modules (master and slave) to see if they’re equal?
One thing that I suggested you do is to lower the frequency, maybe to 10MHz or 5MHz, and check if the problem still occurs. Can you do that and tell me what happened?

Best regards,
Hiago.

Hi @hfranco.tx,

I tried lowering the speed down to till 100kHz. Still, it’s behaving the same way.

I am attaching the device tree file for both the master and slave:

Slave device (Custom board): imx6ull-colibri-GRIPS-v1.dts (4.3 KB)
Master device (Iris-v2): imx6ull-colibri-iris-v2.dts (3.4 KB)

Both run on colibri imx6ULL COM.

Hi @SurriyaLuavan,

Could you please send me your dmesg logs?

Best Regards,
Hiago.

Hi,

This is the dmesg from the slave side for the same experiment attached in my previous reply,

root@colibri-imx6ull-06765032:~# dmesg | grep spi
[ 1.606434] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.345436] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.362073] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.363274] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.386198] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 10.347997] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 10.641870] spi_imx 2008000.spi: registered slave spi0
[ 10.682550] spi_slave spi0: /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0 is not called ‘slave’
[ 10.696214] spi_slave spi0: Failed to create SPI device for /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0
[ 10.930901] spi spi0.0: spi_imx_setup: mode 0, 8 bpw, 0 hz
[ 10.930930] spi spi0.0: setup mode 0, 8 bits/w, 0 Hz max → 0
[ 10.931729] spi_imx 2008000.spi: registered child spi0.0
[ 10.931745] spi_imx 2008000.spi: probed
[ 49.693120] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 0 hz
[ 49.693186] spidev spi0.0: setup mode 0, 8 bits/w, 0 Hz max → 0
[ 49.693219] spidev spi0.0: spi mode 0
[ 49.693280] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 0 hz
[ 49.693327] spidev spi0.0: setup mode 0, 8 bits/w, 0 Hz max → 0
[ 49.693360] spidev spi0.0: 8 bits per word
[ 49.693414] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 500000 hz
[ 49.693463] spidev spi0.0: setup mode 0, 8 bits/w, 500000 Hz max → 0
[ 49.693493] spidev spi0.0: 500000 Hz (max)
[ 49.695124] spi_imx 2008000.spi: mx51_ecspi_clkdiv: fin: 60000000, fspi: 500000, post: 3, pre: 14

This is the dmesg at the master side:

root@colibri-imx6ull-06764338:~# dmesg | grep spi
[ 1.682900] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.398975] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.514151] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.515207] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.908765] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 3.525861] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 4.669680] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 10.294692] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 10.599072] spi_imx 2008000.spi: registered master spi0
[ 10.655870] spi spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 10.655905] spi spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 10.656691] spi_imx 2008000.spi: registered child spi0.0
[ 10.656747] spi_imx 2008000.spi: probed
[ 90.427161] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 90.427501] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 90.427541] spidev spi0.0: spi mode 0
[ 90.428304] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 90.428451] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 90.428727] spidev spi0.0: 8 bits per word
[ 90.431727] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 500000 hz
[ 90.431759] spidev spi0.0: setup mode 0, 8 bits/w, 500000 Hz max → 0
[ 90.431771] spidev spi0.0: 500000 Hz (max)
[ 90.432443] spi_imx 2008000.spi: mx51_ecspi_clkdiv: fin: 60000000, fspi: 500000, post: 3, pre: 14
[ 96.719298] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 96.719386] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 96.719422] spidev spi0.0: spi mode 0
[ 96.719487] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 96.719543] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 96.719576] spidev spi0.0: 8 bits per word
[ 96.719631] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 500000 hz
[ 96.719683] spidev spi0.0: setup mode 0, 8 bits/w, 500000 Hz max → 0
[ 96.719714] spidev spi0.0: 500000 Hz (max)
[ 96.721361] spi_imx 2008000.spi: mx51_ecspi_clkdiv: fin: 60000000, fspi: 500000, post: 3, pre: 14
[ 98.609465] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 98.609551] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 98.609585] spidev spi0.0: spi mode 0
[ 98.609647] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 98.609700] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 98.609733] spidev spi0.0: 8 bits per word
[ 98.609788] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 500000 hz
[ 98.609841] spidev spi0.0: setup mode 0, 8 bits/w, 500000 Hz max → 0
[ 98.609872] spidev spi0.0: 500000 Hz (max)
[ 98.611467] spi_imx 2008000.spi: mx51_ecspi_clkdiv: fin: 60000000, fspi: 500000, post: 3, pre: 14
[ 100.059481] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 100.059570] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 100.059607] spidev spi0.0: spi mode 0
[ 100.059669] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 20000000 hz
[ 100.059725] spidev spi0.0: setup mode 0, 8 bits/w, 20000000 Hz max → 0
[ 100.059757] spidev spi0.0: 8 bits per word
[ 100.059811] spidev spi0.0: spi_imx_setup: mode 0, 8 bpw, 500000 hz
[ 100.059864] spidev spi0.0: setup mode 0, 8 bits/w, 500000 Hz max → 0
[ 100.059898] spidev spi0.0: 500000 Hz (max)
[ 100.061475] spi_imx 2008000.spi: mx51_ecspi_clkdiv: fin: 60000000, fspi: 500000, post: 3, pre: 14

I have also opened a ticket in NXP community and haven’t got any responce. Also, I have seen other who faced the same issue post in the NXP community, with no solutions posted.

Hi @hfranco.tx,

Is there any fix you could come up with for this issue on your side?

Hi @SurriyaLuavan,

Sorry for the delay, I couldn’t reproduce this issue on my side.
The only problem that I see is on these lines:

[ 10.682550] spi_slave spi0: /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0 is not called ‘slave’
[ 10.696214] spi_slave spi0: Failed to create SPI device for /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0

Somehow the kernel is failing to initialize your SPI. I’ll need to test more here on my side.

Best Regards,
Hiago.

Hi @hfranco.tx,

I got the spi-slave to work on i.MX 6ULL Colibri module. Turns out NXP has provided a recent patch to the spi-imx driver file to include DMA functionality, which turns off by default in slave mode for SPI in pervious versions (Uses PIO). There is also a application note(AN13633) from NXP for i.MX 8 (ECSPI), that helped me working with slave functionality.

Hi @SurriyaLuavan,

I’m sorry I couldn’t find this on my side, but I’m glad you found it and solved your issue!

Best Regards,
Hiago.

1 Like