SPI TFT display

Hi Toradex-Team,

We want to use a SPI TFT display with either a ST7789V2 or a ILI9341 controller together with Torizon core on a colibri-imx6ull-emmc.
We found the “fbtft” kernel driver module (staging) and hoped it would do the job without re-building the kernel.
Bringing the kernel module into Torizon core 5.7.0 seemed to work out well. But we have trouble with the corresponding device tree overlay (find our attempt for ILI9341 below).
Torizon core builder prints this:

=> Handling device-tree subsection

=> Selecting custom device-tree 'device-trees/dts-arm32/imx6ull-colibri-emmc-eval-v3.dts'
'imx6ull-colibri-emmc-eval-v3.dts' compiles successfully.
warning: removing currently applied device tree overlays
Device tree imx6ull-colibri-emmc-eval-v3.dtb successfully applied.

=> Adding device-tree overlay 'dt-overlays/display-ili9341_overlay.dts'
'display-ili9341_overlay.dts' compiles successfully.

Failed to apply '/tmp/tmph0qqrrcl': FDT_ERR_NOTFOUND

error: cannot apply device tree overlays ['/tmp/tmph0qqrrcl'] against device tree /storage/dt/usr/lib/modules/5.4.193-5.7.0+git.f5d73fd6e9f8/dtb/imx6ull-colibri-emmc-eval-v3.dtb.
error: overlay 'dt-overlays/display-ili9341_overlay.dts' is not applicable.

Could you please help with that?

Thank you,
Christian


DT overlay file:

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,colibri-imx6ull-emmc";

	// Enable the SPI controller
	fragment@0 {
		target = <&spi0>;
		__overlay__ {
			status = "okay";
		};
	};

	// Enabling the SPI controller also enables spidev on cs0, so we have disable it
	fragment@1 {
		target = <&spidev0>;
		__overlay__ {
			status = "disabled";
		};
	};

	fragment@2 {
		target = <&spi0>;
		__overlay__ {
			/* needed to avoid dtc warning */
			#address-cells = <1>;
			#size-cells = <0>;

			display: display@0{
				// MIPI DBI compatible driver
				// This driver is used because it can ignore an illegal rotate value
				// and doesn't have a set_gamma() function.
				compatible = "samsung,s6d02a1";
				reg = <0>; // Chip Select 0

				spi-max-frequency = <32000000>; // 32MHz

				reset-gpios = <&gpio 23 1>; // reset is active low hence the 1
				dc-gpios = <&gpio 24 0>;
				led-gpios = <&gpio 18 0>;

				width = <320>;
				height = <240>;
				buswidth = <8>; // Most controllers use this value

				// This is a hack to prevent fb_s6d02a1.c:set_var() from issuing
				// command 0x36 after the init sequence has been applied and thus
				// changing the config.
				rotate = <1>;

				// see drivers/staging/fbtft/fb_ili9341.c:init_display() for how this looks in the driver
				// Command 0x36 is taken from the fb_ili9341.c:set_var() function.
				init = <0x1000001
					0x2000005
					0x1000028
					0x10000cf 0x00 0x83 0x30
					0x10000ed 0x64 0x03 0x12 0x81
					0x10000e8 0x85 0x01 0x79
					0x10000cb 0x39 0x2c 0x00 0x34 0x02
					0x10000f7 0x20
					0x10000ea 0x00 0x00
					0x10000c0 0x26
					0x10000c1 0x11
					0x10000c5 0x35 0x3e
					0x10000c7 0xbe
					0x100003a 0x55
					0x1000036 0x28
					0x10000b1 0x00 0x1b
					0x1000026 0x01
					0x10000f2 0x08
					0x1000026 0x01
					0x10000e0 0x1f 0x1a 0x18 0x0a 0x0f 0x06 0x45 0x87 0x32 0x0a 0x07 0x02 0x07 0x05 0x00
					0x10000e1 0x00 0x25 0x27 0x05 0x10 0x09 0x3a 0x78 0x4d 0x05 0x18 0x0d 0x38 0x3a 0x1f
					0x10000b7 0x07
					0x10000b6 0x0a 0x82 0x27 0x00
					0x1000011
					0x2000064
					0x1000029
					0x2000064>;

				debug = <0x4000000>; // print init commands to the kernel log
			};
		};
	};
};

Hi @cgsasse ,

I took your device tree overlay and ran the same procedure as you and I get the same error:

=> Handling device-tree subsection

=> Selecting custom device-tree 'device-trees/dts-arm32/imx6ull-colibri-emmc-eval-v3.dts'
'imx6ull-colibri-emmc-eval-v3.dts' compiles successfully.
warning: removing currently applied device tree overlays
Device tree imx6ull-colibri-emmc-eval-v3.dtb successfully applied.

=> Adding device-tree overlay 'dts_custom/display-ili9341_overlay.dts'
'display-ili9341_overlay.dts' compiles successfully.

Failed to apply '/tmp/tmpjo3uxwbm': FDT_ERR_NOTFOUND

error: cannot apply device tree overlays ['/tmp/tmpjo3uxwbm'] against device tree /storage/dt/usr/lib/modules/5.4.193-5.7.0+git.f5d73fd6e9f8/dtb/imx6ull-colibri-emmc-eval-v3.dtb.
error: overlay 'dts_custom/display-ili9341_overlay.dts' is not applicable.

I will look at it in more detail.

Best Regards
Kevin

Hi @cgsasse ,

I was also able to reproduce the issue when applying your Device Tree Overlay. I think the problem is in these three lines in your overlay file:

reset-gpios = <&gpio 23 1>; // reset is active low hence the 1
dc-gpios = <&gpio 24 0>;
led-gpios = <&gpio 18 0>;

FDT_ERR_NOTFOUND indicates that there is a non existent node or property being requested, so I did a quick look in the kernel at the device tree of the Colibri iMX8ULL and I don’t think there’s a node called gpio, without any number appended.

For instance if I replace gpio with gpio1 the error doesn’t happen. See if this helps you.

EDIT: I forgot to say this, but you should also change all references of spi0 to ecspi1. You can keep spidev0 as is.

Best regards,
Lucas Akira

1 Like

Hi @lucas_a.tx,

Thank you for your quick response!

The overlay file has no references to spi. They are already at spi0.

I deleted the three lines you mentioned but unfortunately the torizon-core-builder error is still there!

BTW: I’m using torizoncore-builder 3.7.0.

Do you have any other ideas? Could there be any other wrong references?
Unfortunately I have no experience in writing device-tree overlays!

Best,
Christian

Hi @lucas_a.tx ,

It seems that the references to spi0 are the problem!

When I change the lines containing

target = <&spi0>;

to

target = <&ecspi1>;

the error disappears.

Is this because spi0 is an alias?
How do I correctly assign an alias to the target property?

Best,
Christian

Hi @cgsasse ,

I deleted the three lines you mentioned but unfortunately the torizon-core-builder error is still there!

You shouldn’t need to delete the three lines in question, just change gpio to gpio1 or whatever GPIO bank you’re using, like the example below:

reset-gpios = <&gpio1 23 1>; // reset is active low hence the 1
dc-gpios = <&gpio1 24 0>;
led-gpios = <&gpio1 18 0>;

The reason for this is because there isn’t a node called gpio, but there are nodes called gpio1, gpio2, etc.


It seems that the references to spi0 are the problem!

Yes, changing spi0 to ecspi1 is also needed, because you need to reference a node using its label (ecspi1), not its alias (spi0).

Is this because spi0 is an alias?
How do I correctly assign an alias to the target property?

As you correctly pointed out, spi0 is an alias, as it can be seen from this file imx6ul.dtsi « dts « boot « arm « arch - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules which is part of the include chain called by imx6ull-colibri-emmc-eval-v3.dts.

According to this link – linux - Device Trees: Difference between labels and aliases? - Unix & Linux Stack Exchange – an alias is used by the Linux kernel and can’t be used to reference nodes in a device tree.

So in summary you don’t use an alias to reference a node in a device tree, you use a label.


As a side note, I see that you’re using an old syntax to write your overlay. I suggest using a newer, more compact notation for your overlay. For instance, your overlay in the new syntax would be something like this:

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,colibri-imx6ull-emmc";
};

// Enabling the SPI controller also enables spidev on cs0, so we have disable it
&spidev0 {
	status = "disabled";
};

&ecspi1 {
	// Enable the SPI controller
	status = "okay";

	/* needed to avoid dtc warning */
	#address-cells = <1>;
	#size-cells = <0>;

	display: display@0{
		// MIPI DBI compatible driver
		// This driver is used because it can ignore an illegal rotate value
		// and doesn't have a set_gamma() function.
		compatible = "samsung,s6d02a1";
		reg = <0>; // Chip Select 0

		spi-max-frequency = <32000000>; // 32MHz

		reset-gpios = <&gpio1 23 1>; // reset is active low hence the 1
		dc-gpios = <&gpio1 24 0>;
		led-gpios = <&gpio1 18 0>;

		width = <320>;
		height = <240>;
		buswidth = <8>; // Most controllers use this value

		// This is a hack to prevent fb_s6d02a1.c:set_var() from issuing
		// command 0x36 after the init sequence has been applied and thus
		// changing the config.
		rotate = <1>;

		// see drivers/staging/fbtft/fb_ili9341.c:init_display() for how this looks in the driver
		// Command 0x36 is taken from the fb_ili9341.c:set_var() function.
		init = <0x1000001
			0x2000005
			0x1000028
			0x10000cf 0x00 0x83 0x30
			0x10000ed 0x64 0x03 0x12 0x81
			0x10000e8 0x85 0x01 0x79
			0x10000cb 0x39 0x2c 0x00 0x34 0x02
			0x10000f7 0x20
			0x10000ea 0x00 0x00
			0x10000c0 0x26
			0x10000c1 0x11
			0x10000c5 0x35 0x3e
			0x10000c7 0xbe
			0x100003a 0x55
			0x1000036 0x28
			0x10000b1 0x00 0x1b
			0x1000026 0x01
			0x10000f2 0x08
			0x1000026 0x01
			0x10000e0 0x1f 0x1a 0x18 0x0a 0x0f 0x06 0x45 0x87 0x32 0x0a 0x07 0x02 0x07 0x05 0x00
			0x10000e1 0x00 0x25 0x27 0x05 0x10 0x09 0x3a 0x78 0x4d 0x05 0x18 0x0d 0x38 0x3a 0x1f
			0x10000b7 0x07
			0x10000b6 0x0a 0x82 0x27 0x00
			0x1000011
			0x2000064
			0x1000029
			0x2000064>;

		debug = <0x4000000>; // print init commands to the kernel log
	};
};

Just keep in mind that I didn’t flash the overlay above on a eMMC Colibri iMX6ULL, I just checked that it compiles and applies successfully to the image using TorizonCore Builder.

For more information about the newer syntax I’d recommend reading the following references:

Hope this helps you.

Best regards,
Lucas Akira

Thank you @lucas_a.tx ,

Your input was very helpful!
I saw a boot logo and a spinner on the display!
It was just a short moment and the colors were wrong.
But this is a problem to search in the fbtft kernel module.

Thank you so much for your help we very much appreciate it!

Best regards,
Christian

Hi @cgsasse ,

Did this solve your issue then?

Would you consider @lucas_a.tx answer as a solution, then feel free to to mark it as such :slight_smile:

Best Regards
Kevin