Enable more CS pins for SPI - Cannot find /Linux-for-Tegras directory

Hello,
I am working with SPI communication and I have set it up with 2 CS pins with Jetson-IO. Now I was trying to setup with 4 CS pins like this post (Enable more CS pins for SPI1) and for that, I need to change the pinmux, but for all the solutions that I have found all use the /Linux-for-Tegras directory but I don’t have it. Can you tell me what I’m doing wrong?

I’m using Jetpack 5.1.2-b104, with the Developer Kit carrier board.

Thank you.

Hi Ppovoa,

In pinmux spreadsheet, please configure the pins as GPIO.
and add the cs-gpios attribute in device tree to specify which GPIO you want to use fro CS.

This is BSP package directory on your host.
Please check the directory on your host PC, it should be generated when you are using SDKM to flash your board.
Or you can download it from release page.

The files to download are Driver Package (BSP) and Sample Root Filesystem? Is there any documentation to install it?

Please refer to the developer guide for detailed steps.
Quick Start — Jetson Linux Developer Guide documentation (nvidia.com)

Using the pinmux spreadsheet I set the pins 22 and 32 of the 40-pin expansion to GPIO and flashed to the device. Is it possible to check that pins?
In the device I have downloaded the device tree with the following command:

$ dtc -I fs -O dts -o extracted.dts /proc/device-tree

and i have attached to this message.
To use that pins for CS I think I need to write cs-gpios = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_LOW>, <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>; But where exactly in the device tree? In the spi@3210000?

Thank you for the quick response.
extracted.txt (478.8 KB)

Pinmux is configured during MB1 rather than kernel.
You can use devmem to read the pinmux register to check if it is configured correctly.
Or check with the following command

# cat /sys/kernel/debug/pinctrl/2430000.pinmux/pinconf-groups

You should add this line in device tree source and rebuild the kernel image and flash the board to apply the change.

I don’t think I’ve configured the pins correctly because I set the pins to output and enable pull-up and using the # cat /sys/kernel/debug/pinctrl/2430000.pinmux/pinconf-groups command shows me the default values:

20 (can1_en_pbb1): 
	pull=1
	tristate=1
	enable-input=1
	io-reset=0
	rcv-sel=0
	io-hv=0
	schmitt=0
	pull-down-strength=0
	pull-up-strength=0
	drive-type=2
	func=rsvd0
	pad-power=0

59 (soc_gpio21_pq1): 
	pull=1
	tristate=1
	enable-input=1
	open-drain=0
	io-reset=0
	rcv-sel=0
	io-hv=0
	schmitt=0
	pull-down-strength=0
	pull-up-strength=0
	drive-type=0
	func=rsvd0
	pad-power=0

where 20 (can1_en_pbb1) is the pin 32 and 59 (soc_gpio21_pq1) is the pin 22, if I am not mistaken.

Probably I have done something wrong.
I followed this document Jetson Module Adaptation and Bring-Up: Jetson AGX Xavier Series — Jetson Linux Developer Guide documentation.

I will reproduce what I have done:

  • First I configured the pinmux with the spreadsheet and downloaded 3 .dtsi files;
  • Copy the files to Linux_for_Tegra/kernel/pinmux/t19x/ and run the following command:
python pinmux-dts3cfg.py --pinmux addr_info.txt gpio_addr_info.txt por_val.txt --mandatory_pinmux_file mandatory_pinmux.txt tegra19x-jetson_agx-pinmux.dtsi tegra19x-jetson_agx-gpio-default.dtsi 1.0 > galen.cfg

I think my mistake was naming the .cfg file. But I do not know which name should I pick;

  • Then I copy the created .cfg file to the directory Linux_for_Tegra/bootloader/t186ref/BCT;
  • Finally I run sudo ./flash.sh jetson-agx-xavier-devkit mmcblk0p1 in Linux_for_Tegra/ directory

To rebuild the kernel do I need to follow this Kernel Customization — Jetson Linux Developer Guide documentation?

Please just use the original name for the pinmux and make sure it is used during flash (you can check flash log to know which pinmux cfg is used).

Yes

The pinmux is now correct but I was trying to rebuild the kernel and I encountered this error:

Linux_for_Tegra/source/public$ ./nvbuild.sh -o $KERNEL_OUT
Building kernel-5.10 sources
make: Entering directory '/home/ppovoa/nvidia/nvidia_sdk/JetPack_5.1.3_Linux_JETSON_AGX_XAVIER_TARGETS/Linux_for_Tegra/source/public/kernel/kernel-5.10'
make[1]: Entering directory '/home/ppovoa/nvidia/nvidia_sdk/JetPack_5.1.3_Linux_JETSON_AGX_XAVIER_TARGETS/Linux_for_Tegra/source/public/kernel_out'
  GEN     Makefile
  LEX     scripts/kconfig/lexer.lex.c
/bin/sh: 1: flex: not found
make[2]: *** [scripts/Makefile.host:9: scripts/kconfig/lexer.lex.c] Error 127
make[1]: *** [/home/ppovoa/nvidia/nvidia_sdk/JetPack_5.1.3_Linux_JETSON_AGX_XAVIER_TARGETS/Linux_for_Tegra/source/public/kernel/kernel-5.10/Makefile:645: tegra_defconfig] Error 2
make[1]: Leaving directory '/home/ppovoa/nvidia/nvidia_sdk/JetPack_5.1.3_Linux_JETSON_AGX_XAVIER_TARGETS/Linux_for_Tegra/source/public/kernel_out'
make: *** [Makefile:220: __sub-make] Error 2
make: Leaving directory '/home/ppovoa/nvidia/nvidia_sdk/JetPack_5.1.3_Linux_JETSON_AGX_XAVIER_TARGETS/Linux_for_Tegra/source/public/kernel/kernel-5.10'

I’m using Jetson Linux 35.5. In this case, I was trying to rebuild the kernel without changing the device tree.

Can you assist me?

Thank you.

when you are syncing the source of R35.5, do you use jetson_35.5 as tag?

Please run the following command to install flex on your host.

$ sudo apt-get install flex

Yes I used that tag.

Yes, that was it. I also needed to install libssl-dev.

After successfully rebuilding the kernel without changing the device tree, I attempted to edit the device tree to further rebuild the kernel again but encountered a syntax error.

Original device tree:

I needed to change spi@3210000 from 2 chip-select to 4 chip-select, by adding the pin 22 (soc_gpio21_pq1) and pin 32 (can1_en_pbb1) to chip-select.

spi@3210000 {
		iommus = <0x02 0x20>;
		#address-cells = <0x01>;
		dma-coherent;
		clock-names = "spi\0pll_p\0clk_m";
		nvidia,clk-parents = "pll_p\0clk_m";
		resets = <0x04 0x5b>;
		interrupts = <0x00 0x24 0x04>;
		clocks = <0x04 0x87 0x04 0x66 0x04 0x0e>;
		#size-cells = <0x00>;
		spi-max-frequency = <0x3dfd240>;
		dma-names = "rx\0tx";
		compatible = "nvidia,tegra186-spi";
		status = "okay";
		reg = <0x00 0x3210000 0x00 0x10000>;
		phandle = <0x30d>;
		dmas = <0x24 0x0f 0x24 0x0f>;
		reset-names = "spi";

		spi@1 {
			spi-max-frequency = <0x1f78a40>;
			compatible = "tegra-spidev";
			reg = <0x01>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};

		prod-settings {

			prod_c_cs0 {
				prod = <0x04 0xfff 0x11>;
			};
		};

		spi@0 {
			spi-max-frequency = <0x1f78a40>;
			compatible = "tegra-spidev";
			reg = <0x00>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};
	};

I need to add spi@2 and spi@3, right? I tried adding cs-gpios = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_LOW>, <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>; and also cs-gpios = 0, 0, <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_LOW>, <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>;
but got the following error in both:

Error: output.dts:1767.21-22 syntax error
FATAL ERROR: Unable to parse input tree

Custom device tree:

spi@3210000 {
		...
		
		cs-gpios = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_LOW>, <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>;
		
		prod-settings {

			prod_c_cs0 {
				prod = <0x04 0xfff 0x11>;
			};
		};

		spi@0 {
			spi-max-frequency = <0x1f78a40>;
			compatible = "tegra-spidev";
			reg = <0x00>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};

		spi@1 {
			spi-max-frequency = <0x1f78a40>;
			compatible = "tegra-spidev";
			reg = <0x01>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};
	};

		spi@2 {
			spi-max-frequency = <0x1f78a40>;
			compatible = "tegra-spidev";
			reg = <0x02>;

			controller-data {
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};
	};

		spi@3 {
			spi-max-frequency = <0x1f78a40>;
			compatible = "tegra-spidev";
			reg = <0x03>;

			controller-data {
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};
	};

What is the correct syntax to add 2 extra CS into the spi?

You should modify the source of device tree instead of the device tree decompiled from dtb.
Please find the device tree you are using from <source>/hardware/nvidia

I’m sorry, could you please specify a close location? There seem to be multiple directories further down.

It depends on which module/sku you are using.
Please check your flash log first for the dtb in use and check how it includes other device trees.

In the Jetson, I ran ‘$ dmesg|grep dts’ to get the directory for dtsi file (hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi)

Then, I changed that file in L4T by adding cs-gpios and spi@2 and spi@3 in the spi@3210000 section.

tegra194-p2888-0001-p2822-0000-common.dtsi

spi@3210000 {
		status = "okay";	
+		cs-gpios = 0, 0, <&tegraTEGRA_GPIO(BB, 1) GPIO_ACTIVE_LOW>, <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>;

		spi@0 {
			compatible = "tegra-spidev";
			reg = <0x00>;
			spi-max-frequency = <33000000>;
			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};

		spi@1 {
			compatible = "tegra-spidev";
			reg = <0x01>;
			spi-max-frequency = <33000000>;
			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};

+		spi@2 {
+			compatible = "tegra-spidev";
+			reg = <0x02>;
+			spi-max-frequency = <33000000>;
+			controller-data {
+				nvidia,rx-clk-tap-delay = <0x11>;
+			};
+		};
+		spi@3 {
+			compatible = "tegra-spidev";
+			reg = <0x03>;
+			spi-max-frequency = <33000000>;
+			controller-data {
+				nvidia,rx-clk-tap-delay = <0x11>;
+			};
+		};
	};

But I still got the same error:

syntax error
FATAL ERROR: Unable to parse input tree

What is the correct syntax?

I could overcome the syntax error but at this moment I only changed the default CS pins to pin 22 (Q.01) and pin 32 (BB.01).

tegra194-p2888-0001-p2822-0000-common.dtsi

spi@3210000 {
		status = "okay";	
+		spi-max-frequency = <33000000>;
+		num-cs = <2>;
+		cs-gpios = <TEGRA194_AON_GPIO(BB, 1) GPIO_ACTIVE_LOW>, <TEGRA194_MAIN_GPIO(Q, 1) GPIO_ACTIVE_LOW>;

		spi@0 {
			compatible = "tegra-spidev";
			reg = <0x00>;
			spi-max-frequency = <33000000>;
			controller-data {
-				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};

		spi@1 {
			compatible = "tegra-spidev";
			reg = <0x01>;
			spi-max-frequency = <33000000>;
			controller-data {
-				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
			};
		};
	};

I don’t know why the BB.01 pin was to use TEGRA194_AON_GPIO().

My question is after flashing the board how can I enable SPI on the jetson without running the Jetson-IO because it will overlap the device tree settings? I tried to run a loopback on the spidev_test.c and it doesn’t work.

Port BB is controlled by AON (Always-ON) so that please use TEGRA194_AON_GPIO() for BB.01.

Jetson-IO is used to configured the pinmux for SPI. If you have configured the pinmux through speadsheet and apply the change correctly, then you don’t need to run Jetson-IO.

How do you run loopback test?
It seems the CS is not required in loopback test…

Yes, I know but only works when I configure the pins that way. The only way to check if the pins are set up correctly is by doing in this case a loopback test, or not?

When I say that does not work it is when in the loopback test the receiver is not the same as the transmitter.

By doing: sudo ./spidev_test -D /dev/spidev0.0 -v
But the receiver is only zeros. Does this mean that the MISO and MOSI are not set up?

Jetson-IO and Pinmux spreadsheet are both configuring the pinmux. They are the same.
You could get a scope to check if there’s any signal output from MOSI.

Do you mean that SPI loopback test would work only with configuring SPI through Jetson-IO?

Yes exactly. When I set it up with Jetson-IO the loopback test works but when I set it up with the spreadsheet the receiver only prints zeros.

When I use the pinmux spreadsheet and upon flashing the board is there any extra step?
After flashing I run $ sudo modprobe spidev and then I compile the spidev_test.c and run it using $ sudo ./spidev_test -D /dev/spidev0.0 -v.

I do not know if this helps:

~$sudo dmesg | grep spi
[   12.389260] spi-tegra114 3210000.spi: Adding to iommu group 3
[   12.444702] spi-tegra114 c260000.spi: Adding to iommu group 3
tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg

pinmux.0x0243d040 = 0x00001055; # spi1_sck_pz3: rsvd1, pull-down, tristate-enable, input-enable, lpdr-disable
pinmux.0x0243d020 = 0x00001055; # spi1_miso_pz4: rsvd1, pull-down, tristate-enable, input-enable, lpdr-disable
pinmux.0x0243d058 = 0x00001405; # spi1_mosi_pz5: rsvd1, pull-down, tristate-disable, input-disable, lpdr-disable
pinmux.0x0243d010 = 0x00001059; # spi1_cs0_pz6: rsvd1, pull-up, tristate-enable, input-enable, lpdr-disable
pinmux.0x0243d050 = 0x00001059; # spi1_cs1_pz7: rsvd1, pull-up, tristate-enable, input-enable, lpdr-disable

pinmux.0x0c303048 = 0x0000c408; # can1_en_pbb1: rsvd0, pull-up, tristate-disable, input-disable
pinmux.0x02430058 = 0x00000408; # soc_gpio21_pq1: rsvd0, pull-up, tristate-disable, input-disable, lpdr-disable