Time sensitive networking [TSN] on NX

the documentation on the page 25 refers to a feature ‘Precision Time Protocol (PTP)’ for System;
Could you explain what sort of feature, is it?
Will NX have any support of protocols:
IEEE 802.1 Time Sensitive Networking (TSN)?
IEEE1588v2 one-step Precision Time Protocol (PTP)?

Hi Andrey1984,

NX should support PTP as Xavier. We are still checking the detailed steps to let you try this feature.

Generally, it would be demonstrated by linuxptp tools with 2 NX connected with ethernet cable.

1 Like

Thank you for following up!
According to the document below, ethernet controller supports PTP IEEE 1588-2008, also known as PTP version 2 ( PTPv2 ) Welcome — Jetson Linux<br/>Developer Guide 34.1 documentation

Ethernet Controller Features (EQOS)

IEEE 1588-2008 (PTP)

References:

https://docs.fedoraproject.org/en-US/fedora/rawhide/system-administrators-guide/servers/Configuring_PTP_Using_ptp4l/

1 Like
     ethtool -T eth0
Time stamping parameters for eth0:
Capabilities:
	hardware-transmit     (SOF_TIMESTAMPING_TX_HARDWARE)
	software-transmit     (SOF_TIMESTAMPING_TX_SOFTWARE)
	hardware-receive      (SOF_TIMESTAMPING_RX_HARDWARE)
	software-receive      (SOF_TIMESTAMPING_RX_SOFTWARE)
	software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
	hardware-raw-clock    (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
	off                   (HWTSTAMP_TX_OFF)
	on                    (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
	none                  (HWTSTAMP_FILTER_NONE)
	ptpv1-l4-sync         (HWTSTAMP_FILTER_PTP_V1_L4_SYNC)
	ptpv1-l4-delay-req    (HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ)
	ptpv2-l4-sync         (HWTSTAMP_FILTER_PTP_V2_L4_SYNC)
	ptpv2-l4-delay-req    (HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ)
	ptpv2-l2-sync         (HWTSTAMP_FILTER_PTP_V2_L2_SYNC)
	ptpv2-l2-delay-req    (HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ)
	ptpv2-event           (HWTSTAMP_FILTER_PTP_V2_EVENT)

installing

 git clone git://git.code.sf.net/p/linuxptp/code linuxptp
   cd linuxptp/
   make -j6
  sudo make install

running

    sudo ptp4l -i eth0 -m -S
ptp4l[69457.930]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[69457.931]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[69464.849]: port 1: LISTENING to MASTER on ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES
ptp4l[69464.850]: selected local clock 48b02d.fffe.05a79e as best master
ptp4l[69464.850]: port 1: assuming the grand master role
1 Like

Hi Andrey1984,

Sorry for late reply.

List PTP test steps for you reference:

Host side
ifconfig eth0 down
ifconfig eth0 up
ifconfig eth0 0.0.0.0
ip addr add 10.0.0.1/24 dev eth0
ip link set dev eth0 up
timedatectl set-ntp false
date 010100002018
phc_ctl /dev/ptp0 set
phc_ctl /dev/ptp0 get
ptp4l -f gPTP.cfg -i eth0 -p /dev/ptp0 -m

DUT side
ifconfig eth0 down
ifconfig eth0 up
ifconfig eth0 0.0.0.0
ip addr add 10.0.0.2/24 dev eth0
ip link set dev eth0 up
timedatectl set-ntp false
phc_ctl /dev/ptp0 get
ptp4l -f gPTP.cfg -i eth0 -p /dev/ptp0 -s -m

@carolyuu, thank you for your response.
Could you share the content of the file gPTP.cfg , please?

NX PPS support seems to require rebuilding the kernel in order to add PPS device outputs to the ptp implementation.
The default stock kernel seems having PPS.GPIO =Y , but it has pps-ktimer=NO

nx2:~/linuxptp$ zcat /proc/config.gz | grep -i pps
# PPS support
CONFIG_PPS=y
CONFIG_PPS_DEBUG=y
# PPS clients support
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
CONFIG_PPS_CLIENT_GPIO=y
# PPS generators support
# CONFIG_NVPPS is not set

Is it likely that after rebuilding the kernel with adding PPS-KTIMER module It will be possible to use e.g. simpleRT2K device [ or ublox F9t] PPS to increase the precision of PTP implementation?

does NX support PPS input for PTP?

I think all you need to do is create a device tree binding to set the gpio associated to the pps-gpio driver.

Something like this example from the kernel docs…

	pps {
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_pps>;

		gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
		assert-falling-edge;

		echo-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
		echo-active-ms = <100>;

		compatible = "pps-gpio";
	};

/dev/ptp0 already exists but doesn’t have a pps source associated to it (because there are no pps devices). Once the above binding is done, a /dev/pps0 device should automatically show up and be used by ptp0. I can try it later.

The PPS output from the external device would then be connected to the GPIO you chose when you created the binding, using whatever voltage conversion may be necessary.

Hi,

You could download the gPTP.cfg here:

hello Andrey1984,

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 refer to the approach in post #16 from similar discussion thread, Topic 124003 .
thanks

@JerryChang
Thank you for your response.
The idea is to setup two NX devices as in the example by @carolyuu.
However, with an extra precision layer provided by PPS from GPS unit. The GPS timepulse will be connected to one of the NX devices.
In order to be able to implement it I have to sort out:

    • To which pins to connect the timepulse outputs of the GPS device [ SimpleRT2K by ardusimple]
  • I understand that there is no hardcoded pin for PPS at NX devices. Which pins of the NX GPIO to use for wiring with gps timepulse outputs?
    • Despite the fact that pps-gpio kernel module is enabled by default, there is no /dev/pps device.

Will building the kernel from sources be required to add pps.ktimer module? NVPPS module? Both? Neither of the two?
Can it be done with just editing dtsi file? which exactly dtsi file? with flashing dtb? without flashing dtb?

to which file the following goes?

pps {
gpios = <&tegra_aon_gpio TEGRA194_AON_GPIO(AA, 0) GPIO_ACTIVE_LOW>;
compatible = “pps-gpio”;
assert-falling-edge;
status = “okay”;
};

What pin will be assigned if using the excerpt above?
Will it also require editing the kernel modules config section?

What is the NVPPS?

    • after the device /dev/pps is somehow created - how to use it as input for ethernet nic linux ptp operations?

Attempt #1
mkdir development
cd development
pwd
/mnt/development
wget https://developer.nvidia.com/embedded/L4T/r32_Release_v4.2/Sources/T186/public_sources.tbz2
tar -xjf public_sources.tbz2
cd Linux_for_Tegra/
cd source/
cd public/
tar -xjf kernel_src.tbz2
mkdir /mnt/outdir
TEGRA_KERNEL_OUT=/mnt/outdir
cd kernel/
cd kernel-4.9/
make ARCH=arm64 O=$TEGRA_KERNEL_OUT tegra_defconfig

  • revising .config file in the outdir folder. Do i need to make any changes to there? enable pps.ktimer? nvpps? CONFIG_TEGRA_HTS_GTE=y
    @gtj what dtsi file should I edit?

You choose the pin. Use the pinmux spreadsheet to pick one. If you’re using the NX devkit, pick a gpio that appears on the 40 pin header. For instance, if you wan to use GPIO01 (pin 29) on the header, look in the spreadsheet and you’ll see it’s GPIO3_PQ.05. The important parts being Q 5.

Without a valid gpio setting, the driver won’t load.

Ha! I didn’t even know there was a NVPPS module but yes, you’ll have to compile the kernel from source to use it as it’s not enabled by default. I’m not sure what it does that the pps-gpio driver doesn’t though and there’s no device tree example for it that I can find. I think it’d be a simple…

nvpps {
    compatible = “nvidia,tegra194-nvpps”;
    gpio = <&gpio TEGRA_GPIO(Q, 5) GPIO_ACTIVE_LOW>;
    status = “okay”;
};

That will fail as tegra_aon_gpio and TEGRA194_AON_GPIO aren’t valid on this platform.

Using the GPIO01 example from above, you’d want something like this…

pps {
    gpio = <&gpio TEGRA_GPIO(Q, 5) GPIO_ACTIVE_LOW>;
    compatible = “pps-gpio”;
    assert-falling-edge;
    status = “okay”;
};

I guess it’s a Tegra specific version of pps-gpio so you’d use one or the other but not both. Someone from nvidia would have to confirm.

That should happen automatically.

More info coming…

which of the files below should I edit?

/mnt/developoment/Linux_for_Tegra/source/public/hardware/nvidia/platform/t19x/jakku/kernel-dts$ ls
common
Makefile
tegra194-p3668-all-p3509-0000-adafruit-sph0645lm4h.dts
tegra194-p3668-all-p3509-0000.dts
tegra194-p3668-all-p3509-0000-fe-pi-audio-z-v2.dts
tegra194-p3668-all-p3509-0000-hdr40.dts
/mnt/developoment/Linux_for_Tegra/source/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/common$ ls
tegra194-audio-p3668.dtsi
tegra194-camera-jakku-rbpcv2-imx219.dtsi
tegra194-camera-rbpcv2-imx219.dtsi
tegra194-fixed-regulator-p3509-0000-a00.dtsi
tegra194-fixed-regulator-p3668.dtsi
tegra194-p3509-0000-a00.dtsi
tegra194-p3509-disp.dtsi
tegra194-p3668-common.dtsi
tegra194-p3668-pcie-plugin-manager.dtsi
tegra194-plugin-manager-p3668.dtsi
tegra194-powermon-p3668.dtsi
tegra194-power-tree-p3668.dtsi
tegra194-spmic-p3668.dtsi
tegra194-super-module-e2614.dtsi
tegra194-super-module-e2614-p3509.dtsi
tegra194-thermal-p3668.dtsi

I think you just need to enable “Tegra NVPPS Support” under Device Drivers if you want to try that. pps-gpio is already enabled by default.

The best file to modify is probably hardware/nvidia/platform/t19x/jakku/kernel-dts/tegra194-p3668-all-p3509-0000.dts. There are other ways to enable the gpio in the device tree including creating your own overlay but that’s a bit more complicated.

In tegra194-p3668-all-p3509-0000.dts you could just add the appropriate sample from above…

/ {
	nvidia,dtsfilename = __FILE__;
	nvidia,dtbbuildtime = __DATE__, __TIME__;

	compatible = "nvidia,p3449-0000+p3668-0000", "nvidia,p3449-0000+p3668-0001", "nvidia,p3509-0000+p3668-0000", "nvidia,p3509-0000+p3668-0001", "nvidia,tegra194";

	nvpps {
		compatible = “nvidia,tegra194-nvpps”;
		gpio = <&gpio TEGRA_GPIO(Q, 5) GPIO_ACTIVE_LOW>;
		status = “okay”;
	};
};

it seems that I can edit the device-tree at runtime with the method proposed below

which of the files above do I add the section above to?

nx2:~$ locate tegra194-p3668-all-p3509-0000
/boot/tegra194-p3668-all-p3509-0000-adafruit-sph0645lm4h.dtbo
/boot/tegra194-p3668-all-p3509-0000-fe-pi-audio-z-v2.dtbo
/boot/tegra194-p3668-all-p3509-0000-hdr40.dtbo
/boot/tegra194-p3668-all-p3509-0000.dtb
/boot/dtb/tegra194-p3668-all-p3509-0000.dtb
/boot/dtb/tegra194-p3668-all-p3509-0000.dtb.sig

which of the two below?

/boot/tegra194-p3668-all-p3509-0000.dtb
/boot/dtb/tegra194-p3668-all-p3509-0000.dtb

how do I trans code and pass the change to dtb on-the-fly?

sudo fdtput -t i  /boot/tegra194-p3668-all-p3509-0000.dtb nvpps compatible nvidia,tegra194-nvpps gpio &gpio TEGRA_GPIO(Q, 5) GPIO_ACTIVE_LOW status okay

The issue with creating a dtb overlay is that you’ll have to convert the TEGRA_GPIO macro yourself because it’s normally parsed by the kernel build dtb generation process. To convert it, look at kernel-4.9/include/dt-bindings/gpio/tegra-gpio.h. Find the number associated to the GPIO letter, 16 for Q in this case, multiply it by 8, then add the GPIO number, 5 for a result of 133. Now you need to replace GPIO_ACTIVE_LOW by “1”.

So the line becomes…

gpio = <&gpio 133 1>;

So now an overlay source file should look like this…

/dts-v1/;
/plugin/;
 
/ {
    overlay-name = "PPS Overlay";
    compatible = "nvidia,p3509-0000+p3668-0000";
 
    fragment@pps {
        target-path = "/";
        __overlay__ {
            pps {
                gpio = <&gpio 133 1>;
                compatible = “pps-gpio”;
                assert-falling-edge;
                status = “okay”;
            };
        };
    };
};

Once you have that file, follow the instructions in the L4T documentation to enable it…
https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fhw_setup_jetson_io.html%23wwpID0E0EB0HA

I haven’t tried these exact steps yet but I will later today.

 cat /mnt/developoment/Linux_for_Tegra/source/public/kernel/kernel-4.9/include/dt-bindings/gpio/tegra-gpio.h
/*
 * This header provides constants for binding nvidia,tegra*-gpio.
 *
 * The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below
 * provide names for this.
 *
 * The second cell contains standard flag values specified in gpio.h.
 */

#ifndef _DT_BINDINGS_GPIO_TEGRA_GPIO_H
#define _DT_BINDINGS_GPIO_TEGRA_GPIO_H

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

#define TEGRA_GPIO_PORT_A 0
#define TEGRA_GPIO_PORT_B 1
#define TEGRA_GPIO_PORT_C 2
#define TEGRA_GPIO_PORT_D 3
#define TEGRA_GPIO_PORT_E 4
#define TEGRA_GPIO_PORT_F 5
#define TEGRA_GPIO_PORT_G 6
#define TEGRA_GPIO_PORT_H 7
#define TEGRA_GPIO_PORT_I 8
#define TEGRA_GPIO_PORT_J 9
#define TEGRA_GPIO_PORT_K 10
#define TEGRA_GPIO_PORT_L 11
#define TEGRA_GPIO_PORT_M 12
#define TEGRA_GPIO_PORT_N 13
#define TEGRA_GPIO_PORT_O 14
#define TEGRA_GPIO_PORT_P 15
#define TEGRA_GPIO_PORT_Q 16
#define TEGRA_GPIO_PORT_R 17
#define TEGRA_GPIO_PORT_S 18
#define TEGRA_GPIO_PORT_T 19
#define TEGRA_GPIO_PORT_U 20
#define TEGRA_GPIO_PORT_V 21
#define TEGRA_GPIO_PORT_W 22
#define TEGRA_GPIO_PORT_X 23
#define TEGRA_GPIO_PORT_Y 24
#define TEGRA_GPIO_PORT_Z 25
#define TEGRA_GPIO_PORT_AA 26

16 =Q
will it be physical GPIO pin 5 that will be equal to Q equal to 16?