PPS input to GPIO on Jetpack 6.1

I have been trying to get one of the GPIO pins from the 40 pin header on the AGX Orin to read the input as a pps device. I know the pps driver is installed because there is a native one through ktimer, found at /dev/pps0 which responds to ppstest /dev/pps0. I’ve been mostly having trouble with assigning the GPIO.

From what I understand, the pinmux sheet is for changing the settings of the pins, which I don’t think I need to do. Using a standard input GPIO should work, and there are plenty of those available on the 40 pin header by default.

The next step is setting up the kernel config and the device tree. After downloading the source code from Jetson Linux | NVIDIA Developer, I updated the kernel config by

-CONFIG_PPS_CLIENT_GPIO=y
+CONFIG_PPS_CLIENT_GPIO=m

This was confirmed by running zcat /proc/config.gz | less | grep PPS after booting into the new Image.

However, there was no /Linux_for_Tegra/sources/hardware/ folder, and the documentation only has a description for how to build the device tree blobs: Kernel Customization — NVIDIA Jetson Linux Developer Guide 1 documentation

When you build the dtbs, the hardware folder is produced, but it’s unclear where you can make edits to the device tree before turning them into blobs.

Thus I was introduced to overlays. I created a custom overlay for the 40 pin header, with the intention of turning pin 7, a.k.a. 106 from chipset0, a.k.a. PQ.06 into a pps input device:

/dts-v1/;
/plugin/;

/ {
    compatible = "nvidia,p3737-0000+p3701-0005";
    overlay-name = "PPS Overlay"; 
    jetson-header-name = "Jetson 40pin Header"; 

    fragment@0 {
        target-path = "/";
        __overlay__ {
            pps-gpio {
                status = "okay";
                compatible = "pps-gpio";
                gpios = <&gpio 106 1>;
            };
        };
    };
};

Using fdtdump to inspect the created device tree blob overlay, it looks like this:

/dts-v1/;
// magic:		0xd00dfeed
// totalsize:		0x1ea (490)
// off_dt_struct:	0x38
// off_dt_strings:	0x198
// off_mem_rsvmap:	0x28
// version:		17
// last_comp_version:	16
// boot_cpuid_phys:	0x0
// size_dt_strings:	0x52
// size_dt_struct:	0x160

/ {
    compatible = "nvidia,p3737-0000+p3701-0005";
    overlay-name = "PPS Overlay";
    jetson-header-name = "Jetson 40pin Header";
    fragment@0 {
        target-path = "/";
        __overlay__ {
            pps-gpio {
                status = "okay";
                compatible = "pps-gpio";
                gpios = <0xffffffff 0x0000006a 0x00000001>;
            };
        };
    };
    __fixups__ {
        gpio = "/fragment@0/__overlay__/pps-gpio:gpios:0";
    };
};

Looking into the device tree blob used in the boot config, I see that gpios are being registered like this:

            gpios = <0x000000f1 0x00000030 0x00000001>;
            gpios = <0x0000010c 0x00000024 0x00000001>;
            gpios = <0x000000f1 0x00000032 0x00000001>;

Which makes me think the &gpio being used is incorrect.

I assigned the overlay using sudo /opt/nvidia/jetson-io/jetson-io.py, where the overlay showed up under the 40 pin header category. I confirmed the overlay is being read on boot in the /boot/extlinux/extlinux.conf and that a folder pps-gpio shows up in /proc/device-tree/.

If you have any suggestions on either fixing the overlay or how to update the base device tree for use with Jetpack 6.1, please let me know.

Hi,
If the device cannot be flashed/booted, please refer to the page to get uart log from the device:
Jetson/General debug - eLinux.org
And get logs of host PC and Jetson device for reference. If you are using custom board, you can compare uart log of developer kit and custom board to get more information.
Also please check FAQs:
Jetson AGX Orin FAQ
If possible, we would suggest follow quick start in developer guide to re-flash the system:
Quick Start — NVIDIA Jetson Linux Developer Guide 1 documentation
And see if the issue still persists on a clean-flashed system.
Thanks!

Hi,

I am using the AGX Orin 64GB Dev Kit, and it was flashed with Jetpack 6.1 right before updating the /boot/Image with the custom kernel config. I’m not having trouble booting or flashing anything, I’m having trouble implementing a custom device tree for the 40 pin header - either through an overlay or by re-building the original device tree.

By only using an overlay, I don’t have any trouble with booting. If I royally screw up the base device tree, then it might require a flash, which is why I am asking for guidance before messing that up - especially considering how different it is with Jetpack 6.1 compared to the Jetpack 5 series.

Hi erik93,

Which PIN from 40 pins expansion header you want to use for PPS-GPIO?
Do you connect any PPS source physically?

To use PPS with JP6.1, you can refer to Pps_gpio interrupt not asserted - #8 by KevinFFF for details.

Hi Kevin,

I was planning to use pin 7 of the 40 pin header (PQ.06), but I’m open to using any of the GPIO pins. https://jetsonhacks.com/nvidia-jetson-agx-orin-gpio-header-pinout/

I’m not currently connecting anything physically, but I’m also not getting anything in dmesg about trying to create a pps device, like they do in the link you posted (even though the gpio int was wrong). Does the device need to be associated with an Always On (AON) gpio? It seems like the only one on the header is pin 32 (i.e. PBB.00).

It looks like they had access to the base device tree in the link you posted, which I currently don’t. I checked inside the public_sources.tar.gz available for jetpack 6.1, and the only device tree for the AGX Orin is tegra234-p3737-0000+p3701-0000.dts, while the sdk manager flashes with tegra234-p3737-0000+p3701-0005.dtb. I checked the folders created by the sdk manager and I only found these files associated with that device tree:

./rootfs/boot/kernel_tegra234-p3737-0000+p3701-0005-nv.dtb
./bootloader/kernel_tegra234-p3737-0000+p3701-0005-nv.dtb
./bootloader/kernel_tegra234-p3737-0000+p3701-0005-nv.dtb.sb

None of which are editable to add the pps_gpio code directly to the device tree. Hence the request either for a method to modify the device tree for jetpack 6.1, or a recommendation of how to use an overlay that doesn’t have access to the header files that define TEGRA234_AON_GPIO or otherwise.

Best,
Erik

MAIN_GPIO or AON_GPIO should both work as PPS input.

This is the final DTB used to flash to your board.
There are many dts files included to generate the final DTB.
Please refer to Kernel Customization — NVIDIA Jetson Linux Developer Guide 1 documentation to download the kernel source and you can find all dts files there.

To add custom configurations in device tree with JP6, you can just modify nv-platform/tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi

Thanks for the feedback.

The issue actually lied in my original config:

-CONFIG_PPS_CLIENT_GPIO=y
+CONFIG_PPS_CLIENT_GPIO=m

If you make this change, it seems to activate pps_gpio, you must run sudo modprobe pps_gpio and then you can find the driver in lsmod | grep gpio.

If you leave the config file as CONFIG_PPS_CLIENT_GPIO=y, then pps_gpio is always available, but does NOT show up in lsmod | grep gpio.

I did end up getting this overlay to work for pin 16 on the header with the CONFIG_PPS_CLIENT_GPIO=y config using this source (dts):

/dts-v1/;
/plugin/;

/ {
    compatible = "nvidia,p3737-0000+p3701-0005";
    overlay-name = "PPS Overlay"; 
    jetson-header-name = "Jetson 40pin Header"; 

    fragment@0 {
        target-path = "/";
        __overlay__ {
            pps: pps-gpio {
                status = "okay";
                compatible = "pps-gpio";
                gpios = <&gpio 16 1>;
                assert-falling-edge;
            };
        };
    };
};

The overlay can be turned in a blob overlay (dtbo) with dtc -I dts -O dtb -o /boot/pps-overlay.dtbo /boot/pps-overlay.dts

And adding the overlay to the boot option in /boot/extlinux/extlinux.conf

+OVERLAYS /boot/pps-overlay.dtbo

This doesn’t require any of the source code from the kernels and is less likely to break your setup, so I’m pleased with the result. For anyone wondering how 16 comes from Pin 16 on the 40 pin header, it took a bit of digging. Pin 16 is called GPIO8, but is actually gpio-357 or PC.00 on the pinmux sheet. Looking into the header file using grep -rn "TEGRA_GPIO" in the kernel source files, we can find that the function TEGRA_GPIO is defined as:

#define TEGRA_GPIO(port, offset)
((TEGRA_GPIO_PORT_##port * 8) + offset)

So gpio PC.00 hasPC from #define TEGRA_GPIO_PORT_C 2, and offset is the value 00, which results in 16.

With one last confirmation, run sudo cat /sys/kernel/debug/gpio | grep PC.00 to see the output:

 gpio-357 (PC.00               |pps-gpio            ) in  lo IRQ ACTIVE LOW

Success!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.