Device tree help for SPI attached device

Hi,

I have been struggling with how the gpios are structured in the device tree. I have 4 spi devices that I wish to attach to my AGX Orin dev kit. I have used the pinmux spreadsheet to enable SPI1 and two software chip select gpios (and CAN0 and CAN1 but this isn’t super important to this post) and as I build and deploy the kernel myself I wish to modify the existing device tree sources and not use the generated dts files and the system image generation scripts.

The pinmux configuration I am interested in transplanting into my device tree sources is specifically

			spi1_sck_pz3 {
				nvidia,pins = "spi1_sck_pz3";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_miso_pz4 {
				nvidia,pins = "spi1_miso_pz4";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_mosi_pz5 {
				nvidia,pins = "spi1_mosi_pz5";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_cs0_pz6 {
				nvidia,pins = "spi1_cs0_pz6";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_cs1_pz7 {
				nvidia,pins = "spi1_cs1_pz7";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

               soc_gpio19_pg6 {                                                     
                   nvidia,pins = "soc_gpio19_pg6";                                  
                   nvidia,function = "gp";                                          
                   nvidia,pull = <TEGRA_PIN_PULL_NONE>;                             
                   nvidia,tristate = <TEGRA_PIN_ENABLE>;                            
                   nvidia,enable-input = <TEGRA_PIN_DISABLE>;                       
                   nvidia,lpdr = <TEGRA_PIN_DISABLE>;                               
              };

             soc_gpio07_pi6 {                                                     
                 nvidia,pins = "soc_gpio07_pi6";                                  
                 nvidia,function = "gp";                                          
                 nvidia,pull = <TEGRA_PIN_PULL_NONE>;                             
                 nvidia,tristate = <TEGRA_PIN_ENABLE>;                            
                 nvidia,enable-input = <TEGRA_PIN_DISABLE>;                       
                 nvidia,lpdr = <TEGRA_PIN_DISABLE>;                               
             };

This I have transplanted into tegra234-soc-base.dtsi under the tegra_pinctrl

     tegra_pinctrl: pinmux: pinmux@2430000 {                                      
         compatible = "nvidia,tegra234-pinmux";                                   
         reg = <0x0 0x2430000 0x0 0x19100                                         
             0x0 0xc300000 0x0 0x4000>;                                           
         #gpio-range-cells = <3>;                                                 
         status = "okay";                                                         
                                                                                  
         pinctl-0 = <&exp_header_pinmux>;                                         
         pinctrl-name = "default";                                                
                                                                                  
         exp_header_pinmux: exp-header-pinmux {
                spi1_sck_pz3 {
		    nvidia,pins = "spi1_sck_pz3";
		    nvidia,function = "spi1";
......

Then finally adding my spi devices to tegra234-soc-spi.dtsi

	spi1: spi@c260000 {
		compatible = "nvidia,tegra186-spi";
		reg = <0x0 0x0c260000 0x0 0x10000>;
		interrupts = <0 37 0x04>;
		#address-cells = <1>;
		#size-cells = <0>;
		iommus = <&smmu_niso0 TEGRA_SID_NISO0_GPCDMA_0>;
		dma-coherent;
		dmas = <&gpcdma 16>, <&gpcdma 16>;
		dma-names = "rx", "tx";
		spi-max-frequency = <65000000>;
		nvidia,clk-parents = "pll_p", "osc";
		clocks = <&bpmp_clks TEGRA234_CLK_SPI2>,
			<&bpmp_clks TEGRA234_CLK_PLLAON>,
			<&bpmp_clks TEGRA234_CLK_OSC>;
		clock-names = "spi", "pll_p", "osc";
		resets = <&bpmp_resets TEGRA234_RESET_SPI2>;
		reset-names = "spi";
		status = "okay";

		num-cs = <4>;
		cs-gpios = <&soc_gpio07_pi6 0>,
				   <&soc_gpio19_pg6 0>,
				   <&spi1_cs0_pz6 0>,
				   <&spi1_cs1_pz7 0>;

		tcan1: tcan4x5x@0 {
			reg = <0>;
			spi-max-frequency = <10000000>;
			compatible = "ti,tcan4x5x";
		};

		tcan2: tcan4x5x@1 {
			reg = <1>;
			spi-max-frequency = <10000000>;
			compatible = "ti,tcan4x5x";
		};

		tcan3: tcan4x5x@2 {
			reg = <2>;
			spi-max-frequency = <10000000>;
			compatible = "ti,tcan4x5x";
		};

		tcan4: tcan4x5x@3 {
			reg = <3>;
			spi-max-frequency = <10000000>;
			compatible = "ti,tcan4x5x";
		};
	};

with the cs-gpios declared external in this file to resolve the handles.

But for the life of me I cannot get the device tree to compile. I am always presented with

FATAL ERROR: Unable to parse input tree

I am after some advice as to how one goes about configuring Nvidia’s GPIOs to interface them with an spi device in an spi driver. I have attached a patch of the modifications in case the above lines are confusing.
spi_device_tree.txt (6.7 KB)

Cheers,

Alex

Hi alxhoff,

What’s the Jetpack version in use?

It is not the expected operation to me since that the device tree of pinmux is loaded in MB1 rather then included in kernel dtb.

May I know what’s your use case so that I could suggest you the appropriate implementation?

Thanks for the reply @KevinFFF, I am using jetpack 5.1.3.

This makes sense. I am looking to enable SPI1 with the 2 default chip select lines as well as two of the GPIOs, ideally gpios 9 and 17 to be software chip selects, ie. pass them through to the SPI1 device as part of “cs-gpios” with "num-cs = <4>, then I can attach my 4 CAN->SPI adapters to the bus. The device is setup with a custom partition layout, the spi part of the partition is default only I do not use a kernel or kernel_dtb partition and load the kernel and dtb from my APP partition. But I still have MB1 of course.

It is just very hard to find documentation on all of this.

It seems you want 2 more SPI CS in your use case.
We would suggest you referring to Changing the Pinmux to configure those 2 pins as following. (Output/Drive 1 for CS usage)
image
image

You can also refer to Enable more CS pins for SPI - Cannot find /Linux-for-Tegras directory - #51 by Ppovoa for the similar case.

Thanks for the reply, I will give it a shot and get back to you

A quick question while I am going over the pinmux sheet. To enable the can0 and can1 busses should I be setting CAN0/1_DOUT to be output/drive 1 as well? By default all the can pins are input/Int PD

Cheers

Are you asking about using SPI or CAN?

If you want to enable CAN interface, please configure the Customer Usage column as CAN0_DOUT/CAN0_DIN.

Yes, they are configured as Input GPIO by default. Please configure them according to your use case.

I am looking to enabel both SPI1 and CAN0/1. Is there a page that details what to set in pinmux for the different functionalities?

For the devkit, you can simply use Jetson-IO tool to enable those functions. It could help you to configure the pinmux during boot up.

I am looking though for something that can be put into either the kernel or the L4T sources as we deploy from those and I cannot go running that tool on each robot sadly.

Essentially I am looking for a reference that tells me, for example, what initial state the CAN_DIN/DOUT pins require for functioning as CAN bus pins. I would also be interested in knowing where the to find the specific GPIO names (ports and pins I think) as used in this post that you mentioned. As in the *-hdr40.dts they are all referenced by other names which are not easily used in other dtsi files.

Please let me share the example configuration in pinmux spreadsheet for SPI and CAN respectively.

SPI:

CAN:
image

You can refer to Pinmux Changes to apply the pinmux change.

Thanks! I just edited my previous reply with my final question :)

You can just check the pinmux spreadsheet with all pin number info and functions.

Or you can check Jetson AGX Orin Developer Kit Carrier Board Specification document (SP-10900-001_v1.2)


Table 3-4. 40-Pin Expansion Header Pin Description shows that information.

Great, thanks!

Following the example you sent me I have no problem setting num-cs = 2 but when I set num-cs = 4 and add in the extra cs-gpios and spi@ nodes to cvb/tegra234-p3737-0000-a04.dtsi for my Orin AGX dev kit I get

FATAL ERROR: Unable to parse input tree

meaning my additions are

2  249         num-cs = <4>;                                                            
2  250                                                                                  
2  251         cs-gpios = <&tegra_main_gpio TEGRA234_MAIN_GPIO(Z, 6) GPIO_ACTIVE_LOW>,                                                    
2  252            <&tegra_main_gpio TEGRA234_MAIN_GPIO(Z, 7) GPIO_ACTIVE_LOW>,          
2  253            <&tegra_main_gpio TEGRA234_MAIN_GPIO(BB, 0) GPIO_ACTIVE_LOW>,         
2  254            <&tegra_main_gpio TEGRA234_MAIN_GPIO(P, 4) GPIO_ACTIVE_LOW>;

with 2 extra spi entries below that have incremeneted reg values and removed enable-hw-based-cs

The syntax error seems to come from the 3rd entry in the cs-gpios. This makes me think that maybe I only need to add the non-hardware CS gpios to cs-gpios as I have not set enable-hw-based-cs in those entries, but this also fails. Failing then one the first entry means that the device tree just does not like TEGRA234_MAIN_GPIO(BB, 0) which I believe is GPIO09.

This looks like

|  246     spi@3210000{ /* SPI1 in 40 pin conn */                                       
-  247         status = "okay";                                                         
2  248         spi-max-frequency = <50000000>;                                          
2  249         num-cs = <4>;                                                            
2  250                                                                                  
2  251         cs-gpios = <&tegra_main_gpio TEGRA234_MAIN_GPIO(BB, 0) GPIO_ACTIVE_LOW>, 
2  252            <&tegra_main_gpio TEGRA234_MAIN_GPIO(P, 4) GPIO_ACTIVE_LOW>;          
2  253                                                                                  
2  254         spi@0 {                                                                  
-  255             compatible = "tegra-spidev";                                         
3  256             reg = <0x0>;                                                         
3  257             spi-max-frequency = <50000000>;                                      
3  258             controller-data {                                                    
-  259                 nvidia,enable-hw-based-cs;                                       
4  260                 nvidia,rx-clk-tap-delay = <0x10>;                                                                                  
4  261                 nvidia,tx-clk-tap-delay = <0x0>;                                 
3  262             };                                                                   
2  263         };                                                                       
2  264         spi@1 {                                                                  
-  265             compatible = "tegra-spidev";                                         
3  266             reg = <0x1>;                                                         
3  267             spi-max-frequency = <50000000>;                                      
3  268             controller-data {                                                    
-  269                 nvidia,enable-hw-based-cs;                                       
4  270                 nvidia,rx-clk-tap-delay = <0x10>;                                
4  271                 nvidia,tx-clk-tap-delay = <0x0>;                                 
3  272             };                                                                   
2  273         };                                                                       
2  274         spi@2 {                                                                  
-  275             compatible = "tegra-spidev";                                         
3  276             reg = <0x2>;                                                         
3  277             spi-max-frequency = <50000000>;                                      
3  278             controller-data {                                                    
-  279                 nvidia,rx-clk-tap-delay = <0x10>;                                
4  280                 nvidia,tx-clk-tap-delay = <0x0>;                                 
3  281             };                                                                   
2  282         };                                                                       
2  283         spi@3 {                                                                  
-  284             compatible = "tegra-spidev";                                         
3  285             reg = <0x3>;                                                         
3  286             spi-max-frequency = <50000000>;                                      
3  287             controller-data {                                                    
-  288                 nvidia,rx-clk-tap-delay = <0x10>;                                
4  289                 nvidia,tx-clk-tap-delay = <0x0>;                                 
3  290             };                                                                   
2  291         };                                                                       
|  292     };                                                                           
|  293                                                                                  
|  294     spi@3230000{ /* SPI3 in 40 pin conn */                                       
-  295         status = "okay";                                                         
2  296         spi@0 { /* chip select 0 */                                              
-  297             compatible = "tegra-spidev";                                         
3  298             reg = <0x0>;                                                         
3  299             spi-max-frequency = <50000000>;                                      
3  300             controller-data {                                                    
-  301                 nvidia,enable-hw-based-cs;                                       
4  302                 nvidia,rx-clk-tap-delay = <0x10>;                                
4  303                 nvidia,tx-clk-tap-delay = <0x0>;                                 
3  304             };                                                                   
2  305         };                                                                       
2  306         spi@1 { /* chips select 1 */                                             
-  307             compatible = "tegra-spidev";                                         
3  308             reg = <0x1>;                                                         
3  309             spi-max-frequency = <50000000>;                                      
3  310             controller-data {                                                    
-  311                 nvidia,enable-hw-based-cs;                                       
4  312                 nvidia,rx-clk-tap-delay = <0x10>;                                
4  313                 nvidia,tx-clk-tap-delay = <0x0>;                                 
3  314             };                                                                   
2  315         };                                                                       
|  316     };

I am unsure why this is a syntax error. Slimming everything down to num-cs = 2 with the first 2 GPIOs it builds. And if I swap to using the SPI3 chip select pins as the GPIOs, ie. Y03 and Y04 it works.

Is the port BB0 and P4 syntax correct?

It would seem that BB0 requires TEGRA234_AON_GPIO

yes, PBB.00 belongs to GPIO AON controller.

Please configure it as following instead.

         cs-gpios = <&tegra_aon_gpio TEGRA234_AON_GPIO(BB, 0) GPIO_ACTIVE_LOW>, 
            <&tegra_main_gpio TEGRA234_MAIN_GPIO(P, 4) GPIO_ACTIVE_LOW>; 

Where are the pins that belong to the AO GPIO controller documented?

Please check Identifying the GPIO Number or 8.4.2.5 GPIO Controller to Ports Mapping of Jetson Orin Series SoC Technical Reference Manual for details.