Enable SPI iMX8QM

Hello,

The device tree nodes in the fsl-imx8qm-apalis.dts looks as follows (by default):

/* Apalis SPI1 */
&lpspi0 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lpspi0>;
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	spidev0: spi@0 {
		compatible = "toradex,evalspi";
		reg = <0>;
		spi-max-frequency = <4000000>;
	};
};

/* Apalis SPI2 */
&lpspi2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lpspi2>;
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	spidev1: spi@0 {
		compatible = "toradex,evalspi";
		reg = <0>;
		spi-max-frequency = <4000000>;
	};
};

(in the &iomux :slight_smile:

	/* Apalis SPI1 */
	pinctrl_lpspi0: lpspi0grp {
		fsl,pins = <
			SC_P_SPI0_SCK_DMA_SPI0_SCK		0x0600004c
			SC_P_SPI0_SDO_DMA_SPI0_SDO		0x0600004c
			SC_P_SPI0_SDI_DMA_SPI0_SDI		0x0600004c
			SC_P_SPI0_CS0_DMA_SPI0_CS0		0x0600004c
		>;
	};

	/* Apalis SPI2 */
	pinctrl_lpspi2: lpspi2grp {
		fsl,pins = <
			SC_P_SPI2_SCK_DMA_SPI2_SCK		0x0600004c
			SC_P_SPI2_SDO_DMA_SPI2_SDO		0x0600004c
			SC_P_SPI2_SDI_DMA_SPI2_SDI		0x0600004c
			SC_P_SPI2_CS0_DMA_SPI2_CS0		0x0600004c
		>;
	};

I have compiled the device tree and replaced the previous one, but I couldn’t find any of the two SPI devices in /dev.

Is there anything that should be changed to enable the spidev ?
Thanks.

Best regards,
Majd

I assume you have the following commit:

http://git.toradex.com/cgit/linux-toradex.git/commit/?h=toradex_imx_4.14.78_1.0.0_ga-bring_up&id=28acc2ce802f25dd900b5ed0acc9e3c9abac40c3

And did deploy and load the spidev kernel module:

http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm64/configs/defconfig?h=toradex_imx_4.14.78_1.0.0_ga-bring_up#n368

Thank you, I didn’t know that spidev is compiled as a kernel module. Its working after loading the module. But now I have an issue with the SPI frequency. I have set the spi-max-frequency = 23000000 ; (23 Mhz instead of 4 Mhz). I tried to operate the SPI on 20Mhz but it doesnt work. (It worked already with 10Mhz)
I get this message through the serial connection:

[ 666.824565] spi_master spi0: failed to transfer one message from queue

Is it a hardware issue?

Best regards,
Majd

Did you get this message only once?
Is the SPI transfer working?
Could you check other SPI speeds?

Hi jaski.tx,

Did you get this message only once?
yes I get it once per run using ( ioctl(fd, SPI_IOC_MESSAGE(1), &tr); )
Is the SPI transfer working?
The SPI transfer seems to work on 10 Mhz ( MOSI tested with oscilloscope )
Could you check other SPI speeds?
I checked the speeds from 10 to 23 Mhz. SPI stops working starting from 13 Mhz (12 works)
and the kernel gives the mentioned debugging message.

Hi @jaski.tx,

Is the 20Mhz SPI clock tested on iMX8? Is there specified SPI frequencies that can work iMX8?

Thank you in Advance.

Best regards, Majd

hi @majd.m

Is the 20Mhz SPI clock tested on iMX8? Is there specified SPI frequencies that can work iMX8?

Since the module has still Early Access Status, we did not test all the Speeds. The specified SPI frequency can work if you change the parent Clock for the SPI. The parent clock has currently a clock frequency of 24MHz, this limits the SPI speed to 12MHz.

Thank you in Advance.

You are welcome.

Best regards,
Jaski

Hi @jaski.tx,

can I change the parent clock just by adding
assigned-clock-rates = value;
in the spi node in fsl-imx8qm-apalis.dts ?

Best regards,
Majd

Yes, this should work. By the way, did you update to Bsp 3.0b2. The Bring-up Kernel branch is obsolete.

Best regards,
Jaski

Hi @jaski.tx,

I’m using the kernel branch: toradex_4.14-2.0.x-imx. is it correct?

I have set the assigned-clock-rates = 48 000 000 instead of 24 000 000. the SPI works now on 24 Mhz.

The issue now is, when I set the speed in the SPI struct to 20 Mhz the spi transfer keeps running on 24 Mhz (checked by the oscilloscope).
I tried also to set the frequencies 19,18,17 Mhz, but I get the same result: 24 Mhz.
Setting the speed to 16,15,14,13 will result a 16Mhz transfer frequency, 12,11,10 a 12 Mhz frequency and so on…
I would be grateful if you explained it. Is there any way to set the frequency to 20 Mhz?

Best regards, Majd

Hi Majd

The SPI subsystem can only divide its clock input by integers, and you must divide by at least 2.

It is a two stage divider. The first can divide by 1, 2, 4, 8, 16, 32, 64 and, 128. The second by any integer between 2 … 257.

So if you set that clock to 48MHz (assuming that the clock subsystem can generate that exact clock) then your SCK can be e.g.:

48 / 1 / 2 = 24MHz
48 / 1 / 3 = 16MHz
48 / 1 / 4 = 12MHz

Note that if you do not use ‘even’ integers, then the resulting SPI SCK will not be symmetrical.

So if you want 20MHz you should set the assigned clock rate to an even multiple, e.g. to 40MHz or 80MHz.

Max

Hello,

I’m new in using Toradex and TorizonCore, so sorry for refreshing the topic, but need to go to the source. I’m using Apalis IMX8 on Ixora Carrier Board connected to MCT070HDMI-B-CTP touch screen via HDMI. Before I used Apalis TK1 on Ixora. I have made both Quickstart Guides – with building image on TK1 with Yocto, and using containers and Torizon OTA on IMX8 (thank you for them). At this moment I’ve got two different images on my IMX8 boards – one of them is Reference Multimedia Image on IMX8 build with Yocto, and second is .yaml file from your tutorial consisting of two containers – Weston-vivante and kiosk-mode-browser uploaded via Torizon OTA.

In spite of customizing image I’d like to customize hardware – the SPI speed. As you mentioned before SPI on IMX8 is implemented as kernel module. Exploring device-trees for my board I found only option to set SPI max speed, should I add to option “assigned-clock-rates = value;” to device-tree? Why fsl-imx8qm-apalis.dts file is absent in device-tree and overlays repository after running :


torizoncore-builder dt-checkout

Should I use TorizonCore Builder to customize it? I’m not sure how to do this – changing device tree, customize kernel arguments or building external kernel module? What is interesting SPI working properly on image build on Yocto, with speed of 500kB and I can check this out with spidev_test. Unfortunately, spidev_test command can’t be found on second board, where image is based on .yaml file. How can I add it also to this image? On both boards there are spidev in /dev localization. Or, maybe I should resort directly to kernel using spi_ioc_transfer (Linux Kernel: spi_ioc_transfer Struct Reference) ?

And second problem connected with Torizon OTA – during upgrades via OTA something went wrong – upgrade got stuck, one day later after delete and added device again it passed, but at OTA webpage I can’t upgrade board - after update initiation I can’t select component to update – there are no option to select, as it was before. The screenshot showing the problem:

Dear @ml_man,

Thanks for reaching out. Can you please open a new topic with this exact same question as this post was already marked as solved? Therefore, this could help us and other people using the community.

Best regards,
Guilherme

Of course, I’ll do it.