Setting up device tree overlay for PPS on Xavier NX

Looking for some help getting a PPS signal into ntp from a uBlox GPS. Serial is working and there appears to be activity on the GPIO1 which is connected to the PPS signal however /dev/pps0 doesn’t seem to work (time_pps_fetch() error -1, timeout).

CONFIG_PPS=y and CONFIG_PPS_CLIENT_GPIO=y in kernel config

I think the problem is the device tree and am trying to figure out the appropriate numbers for an overlay. I’ve seen a few examples with different macros/labels and tried the pinmux spreadsheet but not getting it yet. Can anyone help ?


/ {
    overlay-name = "Jetson PPS";
    compatible = "nvidia,jetson-xaviernvidia,tegra194";
    fragment {
        target-path = "/";
        __overlay__ {
                        pps: pps_gpio {
                                compatible = "pps-gpio";
                                gpios = <&tegra_main_gpio ??? 1>;    # what number goes here ??? for gpio1 ?
                                status = "okay";

I think once this is compiled and added to the device tree it should work. I am currently limited by remote access and no room for full install of SDK so if this can be done via CLI on Jetson it would be nice.

Any help.pointers appreciated.

hello niall99,

did you confirm you’ve compile the device tree, and it’s loaded correctly.
you may push the binary to the target, and specify the path to the FDT entry in the /boot/extlinux/extlinux.conf.

if you’re using GPIO pins under AON category to feed PPS signals, you may also use low-level APIs to capture timestamps for system synchronization.
please also check this thread, Jetson Xavier hardware pps_out - #16 by shgarg for reference,

The fragment compiles (with a guess for ??? cell, thinking 421 as that corresponds to gpio in /sys/class/gpio) but gives warnings it can’t get phandle reference (likely need some more includes ?)

I copied the fragment from Time sensitive networking [TSN] on NX - #30 by gtj but that example gives no feedback on warnings.

In the next step using fdtoverlay it is unclear where the base .dtb and the extra .dtbo comes from (our board uses tegra194-xavier-nx-cti-NGX004-RPI-IMX219-2CAM.dts according to dmesg and /boot/dtb has kernel_tegra194-xavier-nx-cti-NGX004-IMX219-2CAM.dtb)

I’m feeling I jumped into the deep end and need to step back … :-/ … is there a tutorial that would be good to start with ?


hello niall99,

note, device tree overlay only update the fields you’ve defined.
the best practice is include the changes to use the base device tree blob.

@niall99 When you say “GPIO1” do you mean pin 29 labelled “GPIO01” on the Devkit’s 40 pin header or something else? Pin 29 on the Devkit’s 40 pin header is actually pin 118 on the module and is labelled SOC_GPIO41. It’s logical name is GPIO3_PQ.05. It’s the “Q.05” (port.offset) that determines the number to use in the DTS. There are 8 logical pins on each port so the the formula for the main gpios is as follows…

pin = (port * 8 ) + offset
where port is 
A = 0,
B = 1,
Q = 16,
Z = 25,
FF = 26,
GG = 27

So the proper gpio for Q.05 on the &tegra_main_gpio would be

(16 * 8) + 5 = 133

Now, if you’re using tools like gpioinfo on the NX, it’s a little more confusing because in reality, ports may not actually have 8 pins so the gpiochip and line numbering may not match the logical numbering you need for the overlay.


OK, now I’m getting somewhere. We are using the CTI Quark carrier board instead of the dev kit, so GPIO01 corresponds to pin 26 instead of pin 29. From it indicates this is gpio421 in sysfs and this matches where I am seeing activity.

GPIO01 maps to 118 in the datasheet but I’m not seeing the label (SOC_GPIO41) or logical name (GPIO3_PQ.05) … is that mapping in another document ? Or perhaps built into one of the tools ?

Anyway, sounds like 133 is what I need in my pps.dts fragment, I’ll give that a try, thanks !

OK, so following up, I can finally see my pps working with ppstest.

It turned out that I couldn’t get the overlay combined with the original dtb, /opt/nvidia/jetson-io/ gave RuntimeError: Platform not supported, no headers found! so I decompiled the current dtb, modified it with the pps fragment and then recompiled, then used custom FDT in /boot/extlinux/extlinux.conf.

This feels very hackish but no idea why the jetson-io script wouldn’t work. Also couldn’t use the &tegra_main_gpio for the PPS gpios definition despite it clearly existing in the symbols section of the decompiled .dts. Ended up finding the phandle for /gpio@2200000 and using it explicitly. Probably would have been easier if I could have found the original .dts source somewhere but I suspect it was synthesized and doesn’t exist as tegra194-xavier-nx-cti-NGX004-RPI-IMX219-2CAM.dts despite what dmesg says.

I’m sure there is a better way so wouldn’t recommend this approach, though it did eventually work. Thanks for your help !

Heh, who’s datasheet? :)

Here are two references… NX/Jetson_Xavier_NX_Pin_and_Function_Names_Guide_v1.0.pdf

Unfortunately Quark’s limited documentation doesn’t really give any details about what they mapped to what. Their BSPs contain a ton of dtbs but no sources so you’d have to dump them back to dts. Or ask them for the specifics.

Oh, If you do want to dump all the dtbs, here’s a quick one-liner…

$ for x in *.dtb ; do dtc -I dtb -O dts -o ${x//.dtb/.dts} $x ; done
1 Like

That was, page 37 … to get to the logical name I needed the pinmux configuration spreadsheet, thanks.

The function and names guide gives useful background though your link is a little broken (

Thanks for confirming the .dts aren’t in BSP, I can stop looking now … ;)

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