Parse input tree error after inclusion of pinmux gpio file for TX2

Hello,

We get an error on line: TEGRA_GPIO(B, 5) when including the generated gpio file from the excell pinmux file.

#include <dt-bindings/gpio/tegra-gpio.h>

/ {
        gpio@2200000 {
                gpio-init-names = "default";
                gpio-init-0 = <&gpio_default>;

                gpio_default: default {
                        gpio-input = < 
                                TEGRA_GPIO(B, 5)
                                TEGRA_GPIO(C, 0)
                                TEGRA_GPIO(J, 5)
                                TEGRA_GPIO(M, 5)
                                TEGRA_GPIO(I, 4)
                                TEGRA_GPIO(I, 6)
                                TEGRA_GPIO(I, 7)
                                TEGRA_GPIO(FF, 1)
                                TEGRA_GPIO(FF, 2)
                                TEGRA_GPIO(FF, 3)
                                TEGRA_GPIO(FF, 4)

Thank you in advance,

Tanguy

The gpio dtsi file is certainly not at the correct place.

In which folder should the pinmux generated .dtsi file go?

hello Ketchup,

suppose you’re following the steps in the [TX2 Configuring Pinmux GPIO and PAD] chapter, right?
could you share the steps and what’s the failure you met to us.
thanks

Hi JerryChang,

I am indeed following the [TX2 Configuring Pinmux GPIO and PAD] chapter.
For the moment, we are not flashing the TX2 as we did not clone it yet.
We want to test our compiled bootloader, linux and dtb by tftpboot them on the TX2.

So, we are not using the .cfg files yet, we only need a .dtb of our custom board.

When I include generated .dtsi files in a copy of tegra186-quill-p3310-1000-c03-00-base.dts, I get a parse error at:

#include <dt-bindings/gpio/tegra-gpio.h>

/ {

When I copy/paste pinmux dtsi code in node pinmux@2430000, it compiles, but not when I add gpio dtsi code in gpio@2200000.

Can you help?

hello Ketchup,

you need to use the .cfg files for your customize pinmux settings.
thanks

What if I don’t want to flash as explained and use my own dtb like here: https://elinux.org/Jetson/TX2_DTB

thanks

As explained here https://devtalk.nvidia.com/default/topic/1022822/?comment=5204511, I want to build my DTB’s with my generated .dtsi files.

Please help.

Is it the creation of a dtb file from dtsi which you are asking about? Or are you asking about installing without flashing?

If it is about creating a dtb file from dtsi, then you have to edit the dtsi within the kernel source, and while configured to match your running system, run “make dtbs”. I do not know which of the many generated dtb files your dtsi will result in modification, but a dtsi is just a header/include file to device trees in the same way that a C “.h” header file is included in multiple source files…the output file is not necessarily a 1-to-1 correspondence…the change of a dtsi may change multiple dtb files, or under some configurations might not change any.

Because the destination of most device tree changes for a TX2 running L4T R28.1 is mmcblk0p15 odds are the particular kernel build target result you are interested in is “arch/arm64/boot/dts/tegra186-quill-p3310-1000-c03-00-base.dtb”.

Hi linuxdev,

It is indeed about creating our custom tegra186-quill-p3310-1000-c03-00-base.dtb but using the generetaed .dtsi files from the excell pinmux sheet.

The nv4lt documentation says copy files to linux, where in the kernel source should these .dtsi files be copied and where to include them?

I don’t know which files are listed, but do you see the “source_sync.sh” script in the “Linux_for_Tegra/” subdirectory of the driver package? This is also part of the JetPack install (which is a front end for the driver package), and is probably the preferred way to get the kernel source since it also brings in some related files. Example:

./source_sync.sh -u tegra-l4t-r28.1

This produces a “sources/” subdirectory. If you cd to that location you can run this command and see a complete list of every dtsi file:

find . -name '*.dtsi'

A more sane list of files starting with “tegra186-quill”:

find . -name 'tegra186-quill*.dtsi'

So a question which might be useful here is “which dtsi files do you have”?

I have all sources and quill dtsi files, thanks.

I have the generated .dtsi files:

tegra18x--gpio-default.dtsi
tegra18x--padvoltage-default.dtsi
tegra18x--pinmux.dtsi

Does find show these within the source_sync.sh tree? If so, then I’d back up the originals and copy yours in in place of the originals. Then configure for kernel build matching your existing system and CONFIG_LOCALVERSION (the suffix of “uname -r”). Just to guarantee proper configuration I’d then make the Image target, although this isn’t strictly needed…I consider it a sanity check even if I don’t need it. Then make the dtbs target, and the dtb file should become available. This is what gets put into mmcblk0p15 (the partition with label “kernel-dtb”).

Once you have this there are a couple of ways to put this in place. The default instructions are typically say to build the dtb file and copy “kernel/arch/arm64/boot/dts/tegra186-quill-p3310-1000-c03-00-base.dtb” to overwrite the “Linux_for_Tegra/kernel/dtb/” version (I suggest backing up the original), then put it in place with:

sudo ./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1

So long as the file is not larger than the partition (and there are a lot of additions which would be required before this would ever happen) this is equivalent to using dd to write to that partition. Extra NULL bytes won’t hurt.

Alternative to flash.sh for dtb install:

An example of doing this with dd is to first check the size of that partition and make a backup:

dd if=/dev/mmcblk0p15 of=original_kernel-dtb.bin bs=512
ls -l original_kernel-dtb.bin
# ...verify the size is evenly divisible by 512, the block size...

On R28.1 of a TX2 it should be 524288 bytes. Strictly speaking, you probably don’t need to extend the smaller “.dtb” file, but it must fit within this original partition size. Just to be thorough I’m going to pad with NULL bytes until I get that size:

cp /where/ever/it/is/tegra186-quill-p3310-1000-c03-00-base.dtb modified_kernel-dtb.bin
truncate --size=524288 modified_kernel-dtb.bin
ls -l modified_kernel-dtb.bin
# ...original and modified should now be the same size...
dd if=modified_kernel-dtb.bin of=/dev/mmcblk0p15 bs=512

After reboot the changes should be visible in “/proc/device-tree/”. Do be careful and verify the dtb file you now have is truly the modification you want.

One tool is to take that original partttion, convert it to a dts, and compare to the one you are about to flash:

dtc -I dtb -O dts -o original_kernel-dtb.dts original_kernel-dtb.bin
# compare original and modified

Thanks linuxdev,

What we don’t know is where to include those .dtsi in the kernel source:

tegra18x--gpio-default.dtsi
tegra18x--padvoltage-default.dtsi
tegra18x--pinmux.dtsi

We get tree parse errors when we include them at the beginning of file tegra186-quill-p3310-1000-c03-00-base.dts.

Thanks for pointing us out where to include those headers.

I don’t know if the forum will work attaching a spreadsheet, but if possible, click on the “paper clip” icon which shows up when you hover the mouse over the quote icon in the upper right of an existing post…then attach the spreadsheet you used. It might be easier if people can just look at it if the forum software allows the attachment.

https://devtalk.nvidia.com/cmd/default/download-comment-attachment/73754/
Where to include the generated .dtsi files (even empty)?
tegra18x-tx2-icarg5-2161-padvoltage-default.dtsi.txt (1.17 KB)
tegra18x-tx2-icarg5-2161-pinmux.dtsi.txt (44.6 KB)
tegra18x-tx2-icarg5-2161-gpio-default.dtsi.txt (2.09 KB)

Unfortunately my LibreOffice is getting a syntax error from the macro itself so I can’t generate the files from the spreadsheet.

You can rename each of those dtsi files by appending “.txt” on the end, e.g., change “file.dtsi” to “file.dtsi.txt” and probably the forum will accept them for attaching. Then you can attach them to your existing comment #16.

Done.

Basically there are two ways to approach this on R28.1. First, modify the dtsi/dts files during a “make dtbs” target for kernel build. Second, extract what is already on the Jetson, edit this, and then overwrite the existing version. I described most of this latter method in the previous post “Alternative to flash.sh for dtb install”.

I am guessing you want to know how to do this directly from the kernel build so future builds include this, but I’ll start with the easier way.

Get the device tree for what is currently in the system. You can get this either from dd of mmcblk0p15, or from “/proc/device-tree/”. I’ll choose the dd method because this may include content the boot loader uses and which gets modified in “/proc/device-tree/” when the kernel loads.

I assume you are logged in as user ubuntu, but adjust for your case:

sudo -s
dd if=/dev/mmcblk0p15 of=original_kernel-dtb.bin bs=512
chown ubuntu.ubuntu original_kernel-dtb.bin
exit
dtc -I dtb -O dts -o original_kernel-dtb.dts original_kernel-dtb.bin
cp original_kernel-dtb.dts edit.dts
chmod ugo-w original_kernel-dtb.*
# Edit "edit.dts" with your favorite editor...you could copy this file to another machine if more convenient.

An alternate way to extract and get “edit.dts” (which might differ from the partition):

dtc -I fs -O dts -o extracted_dtb.dts /proc/device-tree
cp extracted_dtb.dts edit.dts
chmod ugo-w extracted_dtb.dts
# Edit "edit.dts" with your favorite editor...copy to another machine if more convenient.

Starting with your “tegra18x-tx2-icarg5-2161-padvoltage-default.dtsi.txt” I see this has only a single block, the pmc controller at 0xc360000 (“pmc@c3600000”). Looking at edit.dts I search for pmc@c360000. This is the existing default block which will need edit (my Jetson may differ from yours…I don’t know):

pmc@c360000 {
                compatible = "nvidia,tegra186-pmc";
                reg = <0x0 0xc360000 0x0 0x400 0x0 0xc390000 0x0 0x2fff>;
                #padcontroller-cells = <0x1>;
                status = "okay";
                nvidia,restrict-voltage-switch;
                pinctrl-names = "default";
                pinctrl-0 = <0xa7>;
                linux,phandle = <0x10>;
                phandle = <0x10>;

                iopad-defaults {
                        linux,phandle = <0xa7>;
                        phandle = <0xa7>;

                        sdmmc-io-pads {
                                pins = "sdmmc1-hv", "sdmmc2-hv", "sdmmc3-hv";
                                nvidia,enable-voltage-switching;
                        };
                };
        };

Replace this with your version:

pmc@c360000 {
		io-pad-defaults {
			audio_hv {
				nvidia,io-pad-init-voltage = <IO_PAD_VOLTAGE_1_8V>;
			};

			dmic_hv {
				nvidia,io-pad-init-voltage = <IO_PAD_VOLTAGE_1_8V>;
			};

			sdmmc1_hv {
				nvidia,io-pad-init-voltage = <IO_PAD_VOLTAGE_3_3V>;
			};

			sdmmc3_hv {
				nvidia,io-pad-init-voltage = <IO_PAD_VOLTAGE_3_3V>;
			};

			ao_hv {
				nvidia,io-pad-init-voltage = <IO_PAD_VOLTAGE_3_3V>;
			};

			ufs {
				nvidia,io-pad-init-voltage = <IO_PAD_VOLTAGE_1_8V>;
			};

		};
	};

Do the same thing with “gpio@2200000” (which is a single GPIO controller) using your “tegra18x-tx2-icarg5-2161-gpio-default.dtsi.txt” version.

Do the same thing with the much larger “pinmux@2430000” block contained under tegra18x-tx2-icarg5-2161-pinmux.dtsi.txt.

Keep in mind that there is an extra “/ {” at the start of your version, and an extra “};” at the end of your version…these files are processed if built in the kernel source, and those get discarded…you don’t use those in the edit.dts.

Now convert this back to dtb:

dtc -I dts -O dtb -o tegra186-quill-p3310-1000-c03-00-base.dts edit.dts

You can place this in the “Linux_for_Tegra/kernel/dtb/” directory (overwriting the original tegra186-quill-p3310-1000-c03-00-base.dtb), and then do the “sudo ./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1” step to put this in place.

You could also use dd to put this in place on a running Jetson…see the info in #13.

To do this from a kernel build you might want to first configure for build of the whole kernel (“make O=$TEGRA_KERNEL_OUT Image”) for a sanity check, and then:

make O=$TEGRA_KERNEL_OUT dtbs

You’ll see a log of what is built from dtbs, you might want to save this with copy and paste. The “ddot” parts are just two dots/periods “…” in a row…a relative path for parent of that directory.

You’ll find that this is just a dtc compile command exactly the same as if you had compiled from an extracted device tree:

DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dtb

…followed by a copy of a lot of trees. The relevant copy excerpt is:

cp -u ... arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dtb ... arch/arm64/boot/dts/

In theory tegra186-quill-p3310-1000-c03-00-base.dtb from the kernel build will be the same as the one in mmcblk0p15 (extra bytes to fit in the partition are NULL bytes padded to the tail and are irrelevant), but reverse compiling with dtc will sometimes rename something…and will also strip comments…so it may not look exactly the same, but will be a logical match. When using the “sudo ./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1” command the “-r” says to re-use the rootfs, and the “-k kernel-dtb” says to flash the partition with this label…which is mmcblk0p15 (run “sudo gdisk -l /dev/mmcblk0” to see).

Using a “#include” in C to build this in the kernel is why you will see the extra leading/trailing “{}”. I’m not sure what happens if you include the same “controller_name@address”…perhaps it gives an error, or perhaps the one included last is what is used. Technically the build of the device tree is independent of the kernel build, but you might find config options cause different subsets of device trees to be built…when they actually build they are no different than an extracted device tree (other than being originally in pieces connected with the #include). Your individual edits will always be to just a controller_name@address block…statements in the kernel source version such as “FILE” are an aid to putting the pieces together and not relevant if you already have a full tree or are looking only at individual code blocks.

Thanks linuxdev, when I do the same thing with “gpio@2200000” I get:

FATAL ERROR: Unable to parse input tree

at

TEGRA_GPIO(B, 5)

in:

gpio@2200000 {

                gpio-init-names = "default";
                gpio-init-0 = <&gpio_default>;

                sdmmc-wake-support-input {
                        status = "okay";
                };   

                sdmmc-wake-support-output {
                        status = "okay";
                };   
     
                gpio_default: default {
                        gpio-input = <
                                TEGRA_GPIO(B, 5)

It works when I change to:

gpio_default: default {
			gpio-input = <
				TEGRA_MAIN_GPIO(B, 5)
				TEGRA_MAIN_GPIO(C, 0)
				TEGRA_MAIN_GPIO(J, 5)
				TEGRA_MAIN_GPIO(M, 5)
				TEGRA_MAIN_GPIO(I, 4)
				TEGRA_MAIN_GPIO(I, 6)
				TEGRA_MAIN_GPIO(I, 7)
				TEGRA_AON_GPIO(FF, 1)
				TEGRA_AON_GPIO(FF, 2)
				TEGRA_AON_GPIO(FF, 3)
				TEGRA_AON_GPIO(FF, 4)
				TEGRA_AON_GPIO(FF, 0)
				TEGRA_MAIN_GPIO(X, 7)
				TEGRA_MAIN_GPIO(Y, 0)
				TEGRA_MAIN_GPIO(Y, 1)
				TEGRA_MAIN_GPIO(Y, 2)
				TEGRA_MAIN_GPIO(Y, 5)
				TEGRA_MAIN_GPIO(Y, 6)
				TEGRA_AON_GPIO(V, 0)
				TEGRA_AON_GPIO(AA, 2)
				TEGRA_AON_GPIO(AA, 3)
				TEGRA_AON_GPIO(AA, 4)
				TEGRA_AON_GPIO(AA, 5)
				TEGRA_AON_GPIO(AA, 7)
				TEGRA_MAIN_GPIO(R, 5)
				TEGRA_MAIN_GPIO(P, 3)
				TEGRA_MAIN_GPIO(P, 4)
				TEGRA_MAIN_GPIO(P, 5)
				>;
			gpio-output-low = <
				TEGRA_MAIN_GPIO(B, 6)
				TEGRA_MAIN_GPIO(J, 6)
				TEGRA_MAIN_GPIO(M, 4)
				TEGRA_MAIN_GPIO(I, 5)
				TEGRA_MAIN_GPIO(N, 0)
				TEGRA_MAIN_GPIO(N, 2)
				TEGRA_AON_GPIO(U, 3)
				TEGRA_AON_GPIO(S, 3)
				TEGRA_MAIN_GPIO(X, 6)
				TEGRA_MAIN_GPIO(Y, 4)
				TEGRA_MAIN_GPIO(L, 4)
				TEGRA_MAIN_GPIO(L, 5)
				TEGRA_MAIN_GPIO(H, 4)
				TEGRA_MAIN_GPIO(H, 5)
				TEGRA_MAIN_GPIO(H, 6)
				TEGRA_AON_GPIO(V, 5)
				TEGRA_AON_GPIO(AA, 6)
				TEGRA_MAIN_GPIO(R, 1)
				TEGRA_MAIN_GPIO(R, 2)
				TEGRA_MAIN_GPIO(R, 0)
				TEGRA_MAIN_GPIO(P, 6)
				TEGRA_MAIN_GPIO(BB, 0)
				TEGRA_MAIN_GPIO(BB, 1)
				>;
			gpio-output-high = <
				TEGRA_MAIN_GPIO(B, 4)
				TEGRA_MAIN_GPIO(R, 3)
				TEGRA_MAIN_GPIO(R, 4)
				>;

		};

Not sure when to use MAIN or AON.