GTE on linux: duplicated event on GPIO rising edge

Hello,

I made some tests with the GTE on linux side to stamp the rising edge of a GPIO.
I’m facing an unclear situation: I’m getting 2 timestamps out of the GTE for each rising edge, while a single one would be expected. I’m most likely overlooking something.

Setup:

  • Jetson Orin Nano 4GB module
  • Custom carrier board
  • Jetpack 5.1.1 / L4T 35.3.1

Goal:

  • timestamp the rising edge of a GPIO with the GTE on the linux side.
  • since I’m already using the AON GTE on the SPE, I need to rely on the LIC GTE.
  • I’m aware that using the LIC GTE means that interrupts of a given GPIO controller are aggregated.

Current status:

  • I based my test on the tegra194_gte_test kernel module as provided by nvidia
  • my input GPIO is Z.04 (given as parameter to the kernel module as gpio_in=482), managed by the GPIO controller 1
  • my output GPIO is Z.05 (given as parameter to the kernel module as gpio_out=483)
  • the gpio line is driven as expected (I checked with the scope)
  • On the rising edge, the interrupt triggers - I can see the print
  • In the “store_gpio_en_dis” function registering the event to the GTE:
    • I updated the GTE engine to be used from the AON to the LIC one
    • I updated the argument to “tegra_gte_register_event” to use the IRQ TEGRA234_IRQ_GPIO1_0 (value 296)
  • I do get the expected prints on the rising edge: “GPIO HW Timestamp: raw 698048997994, ns 22337567935808”

However, the interval between the timestamps are not the expected ones. When the GPIO toggles every 5s (so one timestamp is expected every10s), I got the following intervals (scaled in seconds for readability):

  • 10.2397288
  • 0.000206816
  • 10.239388064
  • 0.000199392
  • 10.23957536
  • 0.0002784
  • 10.239497344
  • 0.000182944

By checking a bit more, I realized that from the ISR I can always get 2 successful calls to “tegra_gte_retrieve_event”.

I first suspected that I was getting the interrupt from another pin in the same GPIO controller. But I could not find any based on the report from /proc/interrupts. Among all listed gpios, only GPIO 134 (so PZ.04) is reports interrupts.

To be 100% sure that the events are only linked to the GPIO Z04, I moved the “tegra_gte_retrieve_event” in the timer callback, and edited the register GPIO_Z_ENABLE_CONFIG_04_0 to toggle the bit 6 (INTERRUPT_FUNCTION) while the kernel module was loaded:

  • devmem2 0x02211480 b 0x19 # Interrupt bit disabled, no more HW timestamp are available
  • devmem2 0x02211480 b 0x59 # Interrupt bit enabled, HW timestamp are available (but 2 of them coming at once)

When the setup is running with HW timestamps, I found 2 entries in /proc/interrupts matching the expected pace:

  • GICv3 165 Level c150000.tegra-hsp
  • gpio 134 Edge tegra_gte_test_isr
    The second one is the one I expect. I’m not sure how the HSP part comes into the picture and why this would generate an extra event matching my GTE event descriptor.

Any suggestion about how to investigate this further would be appreciated. Thank you.

Hi maxe777,

Have you tried to verify on the devkit?
Or is there the detailed steps to reproduce the same behavior?

Dear @KevinFFF,

Thanks for your fast follow up. I unfortunately do not have access to an eval kit but I can provide the reproduction steps.

  • The kernel module source to use for the test is located at sources/kernel/nvidia/drivers/staging/platform/tegra/gte_test/tegra194_gte_test.c
  • Apply the following patch tegra194_gte_test.patch (5.0 KB), or replace the original file with
    tegra194_gte_test.c (6.4 KB) - whatever is the most convenient for you.
  • Build the kernel module and copy it on the platform
  • Chose the input and output pins you would like to use for the test on your hardware. You can then find the mapping to the gpio identifiers with sudo cat /sys/kernel/debug/gpio.
  • Check under which GPIO controller the input GPIO is. This info can be found in the TRM in the table 1.1 GPIO Controllers and Port Mapping in the section GPIO Controllers / Overview / Features.
  • Under sources /hardware/nvidia/soc/t23x/kernel-include/dt-bindings/interrupt/tegra234-irq.h lookup the identifier for TEGRA234_IRQ_GPIO<X>_0, <X> being the GPIO controller ID.
  • Load the kernel module with: sudo insmod tegra194_gte_test.ko gpio_in=<gpio_in_id> gpio_out=<gpio_out_id> lic_irq=<lic_irq_id>
  • Enable the GTE timestamping with: sudo su -c "echo 1 > /sys/kernel/tegra_gte_test/gpio_en_dis"

At this stage:

  • The output GPIO should toggle every 5s
  • Before you connect the input and output pins together, the kernel log should report No timestamp available
  • Once you connect both pins together, messages like: GPIO HW Timestamp: raw 54791076543, ns 1753314449376 should appear.

Here is an example out I get:

[659.614352] GPIO HW Timestamp: raw 21125127462,  ns 676004078784
[659.614362] GPIO HW Timestamp: raw 21125133396,  ns 676004268672
[669.854125] GPIO HW Timestamp: raw 21445117941,  ns 686243774112
[669.854134] GPIO HW Timestamp: raw 21445126020,  ns 686244032640
[680.093824] GPIO HW Timestamp: raw 21765108679,  ns 696483477728
[680.093831] GPIO HW Timestamp: raw 21765116689,  ns 696483734048
[690.333467] GPIO HW Timestamp: raw 22085099729,  ns 706723191328
[690.333475] GPIO HW Timestamp: raw 22085105778,  ns 706723384896
[700.573441] GPIO HW Timestamp: raw 22405098950,  ns 716963166400
[700.573449] GPIO HW Timestamp: raw 22405104979,  ns 716963359328

Which gives the following intervals:

  • 0.189888
  • 10239.50544
  • 0.258528
  • 10239.445088
  • 0.25632
  • 10239.45728
  • 0.193568
  • 10239.781504
  • 0.192928

Before loading the module and writing to the sysfs to enable the GTE, I checked that no other events are registered: cat /sys/bus/platform/drivers/tegra_gte/3aa0000.gte/events_registered returns 0.

Afterwards the same command returns 1, and only the entry event296 (GPIO controller 1 in my test case) is listed under /sys/bus/platform/drivers/tegra_gte/3aa0000.gte/event296

Please let me know if the steps are unclear or if you spot anything suspicious. I’m also open to provide more logs if this can help.

Thank you.

Hi @KevinFFF,

Would it be possible to have an update since last week? Please let me know if my last post is unclear on any aspect, of if I can do anything to support better.

Regards

Sorry for the late response, have you managed to get issue resolved or still need the support? Thanks

Hi @kayccc ,
The issue is still open from our end. Thanks for checking.

What’s the lic_irq you are using when you PZ.04 as input and PZ.05 as output?

Hi @KevinFFF,

Thanks a lot for following up on this thread.

I’m using the value from the macro TEGRA234_IRQ_GPIO1_0 defined in soc/t23x/kernel-include/dt-bindings/interrupt/tegra234-irq.h, so 296.

Regards.

Could you help to provide the full dmesg after you run the test?

Hi @KevinFFF,

Sure, find the dump attached. I annotated it with the commands I ran around the relevant sections.
dmesg.txt (59.6 KB)

I also tried adding debounce time on the input GPIO (as suggested in this other ticket I submitted: SPE: GTE provided TSC sometimes goes backwards - #13 by maxe777), but I get the same behavior.

Looking forward to the outcome of your tests.

Hi @KevinFFF,

What is the status on your side? Could you reproduce the issue?

Regards

Hi @KevinFFF,

friendly reminder, this ticket is still pending an answer. Thank you.

Sorry for the late reply, I’ve referred your steps and could reproduce the same behavior as yours.

It seems this patch removing 2 nodes(lic_irq_en_dis, lic_irq_ts) under /sys/kernel/tegra_gte_test/ and use gte-lic instead of gte-aon.

When you did this, could you still see any interrupt?

How do you know this is coming from your setup?
Have you tried to disable tegra-hsp@c150000 in device tree?

Hi @KevinFFF

I’ve referred your steps and could reproduce the same behavior as yours

Thank you so much, this is great news.

It seems this patch removing 2 nodes(lic_irq_en_dis, lic_irq_ts) under /sys/kernel/tegra_gte_test/ and use gte-lic instead of gte-aon.

Correct. As stated in the initial post, since gte-aon is already used by the SPE in my setup, using gte-lic is the goal to get GTE support on the CCPLEX side.

When you did this (devmem2 0x02211480 b 0x19), could you still see any interrupt?

I checked carefully again the output of /proc/interrupts:

  • when the IN out OUT gpios are connected together, “gpio 134 Edge tegra_gte_test_isr” fires at the expected rate, and increments exactly by 1 when I see the rising egde on the scope; But the ISR from the driver reports 2 timestamps in a short interval (the GTE stamps are spaced by about 11us), for a GPIO rising edge every 10s.
  • when the IN out OUT gpios are connected together, and the devmem command to disable the interrupt function was run, the same entry under /proc/interrupts no longer increments on the rising edge (and the driver ISR no longer fires). Setting the register value back to 0x59 restores the initial behavior.
  • when IN and OUT gpios are not connected together, the gpio 134 entry under /proc/interrupt stays stable and the driver gets no ISR (same behavior as when the interrupt gets disabled with devmem).

How do you know this is coming from your setup?

This actually seems to be unrelated. I could actually only catch activity on 3c00000.tegra-hsp this time, and I cannot relate this interrupt activity to the GPIO activity.

I also attached the diff of /proc/interrupts from dumps before and after I can see a rising edge on the scope to give you the overview:
int_diff.txt (1.8 KB)

Could you please advise what else can be checked to figure out what is reason behind this extra entry under the GTE?

Thank you

Hi @KevinFFF,

Would you have an update on this ticket? Thanks.