GPIO and DeviceTree

Hello,

I am working with JetPack 4.4 on a Jetson Nano Devkit. I am trying to use GPIOE.6 on the pin header as input port. I modified the device tree as follows:

File tegra210-porg-pinmux-p3448-0000-a02.dtsi:

{
pinmux: pinmux@700008d4 {
status = “okay”;
pinctrl-names = “default”, “drive”, “unused”;
pinctrl-0 = <&pinmux_default>;
pinctrl-1 = <&drive_default>;
pinctrl-2 = <&pinmux_unused_lowpower>;

	pinmux_default: common {

             pe6 {
			nvidia,pins = "pe6";
			nvidia,function = "rsvd0";
			nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
			nvidia,tristate = <TEGRA_PIN_DISABLE>;
			nvidia,enable-input = <TEGRA_PIN_ENABLE>;
		};

.
.
.
.

File tegra210-porg-gpio-p3448-0000-a02.dtsi:

{
gpio: gpio@6000d000 {
gpio-init-names = “default”;
gpio-init-0 = <&gpio_default>;

	gpio_default: default {
		gpio-input = <
			TEGRA_GPIO(E, 6)

.
.
.
.

When I put a low or high signal on the input port and read back the value, I always get the value 0.

echo 38 > /sys/class/gpio/export

Set port high and read value:
cat /sys/class/gpio/gpio38/value
0

Set port low and read value:
cat /sys/class/gpio/gpio38/value
0

When I initialize the port as input, I can read back the correct values:

echo in > /sys/class/gpio/gpio38/direction

Set port high and read value:
cat /sys/class/gpio/gpio38/value
1

Set port low and read value:
cat /sys/class/gpio/gpio38/value
0

I thought initializing the port pad, mux and gpio registers via the device tree should be sufficient for the port to work?! Why do I have to set the port direction to input explicitly?

Thanks in advance

Marc

hello MarcS,

you may use default configurations, according to the Pinmux spreadsheets, GPIO3_PE.06 is by default define as GPIO pin with input direction.

may I know how you’re putting a low/high signal to the pin-33?
since there’s GPIO pull down resistor, it might be related to pd strength not enough to change the pin state.

Hello,

thanks for your answer. I put high/low signal to the input by directly connecting a cable to 3,3V/GND. So pull down strength shouldn’t be an issue.

Directly after system startup:

echo 38 > /sys/class/gpio/export

sudo cat /sys/kernel/debug/gpio

State is always shown as low independent of actual pin state.

gpiochip0: GPIOs 0-255, parent: platform/6000d000.gpio, tegra-gpio:
gpio-0 ( )
gpio-1 ( )
gpio-2 ( |pcie_wake ) in hi
gpio-3 ( )
gpio-4 ( )
gpio-5 ( )
gpio-6 ( |system-suspend-gpio ) out hi
gpio-7 ( )
gpio-8 ( )
gpio-9 ( )
gpio-10 ( )
gpio-11 ( )
gpio-12 (SPI1_MOSI )
gpio-13 (SPI1_MISO )
gpio-14 (SPI1_SCK )
gpio-15 (SPI1_CS0 )
gpio-16 (SPI0_MOSI )
gpio-17 (SPI0_MISO )
gpio-18 (SPI0_SCK )
gpio-19 (SPI0_CS0 )
gpio-20 (SPI0_CS1 )
gpio-21 ( )
gpio-22 ( )
gpio-23 ( )
gpio-24 ( )
gpio-25 ( )
gpio-26 ( )
gpio-27 ( )
gpio-28 ( )
gpio-29 ( )
gpio-30 ( )
gpio-31 ( )
gpio-32 ( )
gpio-33 ( )
gpio-34 ( )
gpio-35 ( )
gpio-36 ( )
gpio-37 ( )
gpio-38 (GPIO13 |sysfs ) in lo

After setting the direction to input again:

echo in > /sys/class/gpio/gpio38/direction

Input is put to low state:

sudo cat /sys/kernel/debug/gpio

gpiochip0: GPIOs 0-255, parent: platform/6000d000.gpio, tegra-gpio:
gpio-0 ( )
gpio-1 ( )
gpio-2 ( |pcie_wake ) in hi
gpio-3 ( )
gpio-4 ( )
gpio-5 ( )
gpio-6 ( |system-suspend-gpio ) out hi
gpio-7 ( )
gpio-8 ( )
gpio-9 ( )
gpio-10 ( )
gpio-11 ( )
gpio-12 (SPI1_MOSI )
gpio-13 (SPI1_MISO )
gpio-14 (SPI1_SCK )
gpio-15 (SPI1_CS0 )
gpio-16 (SPI0_MOSI )
gpio-17 (SPI0_MISO )
gpio-18 (SPI0_SCK )
gpio-19 (SPI0_CS0 )
gpio-20 (SPI0_CS1 )
gpio-21 ( )
gpio-22 ( )
gpio-23 ( )
gpio-24 ( )
gpio-25 ( )
gpio-26 ( )
gpio-27 ( )
gpio-28 ( )
gpio-29 ( )
gpio-30 ( )
gpio-31 ( )
gpio-32 ( )
gpio-33 ( )
gpio-34 ( )
gpio-35 ( )
gpio-36 ( )
gpio-37 ( )
gpio-38 (GPIO13 |sysfs ) in lo

Input is put to high state:

sudo cat /sys/kernel/debug/gpio

gpiochip0: GPIOs 0-255, parent: platform/6000d000.gpio, tegra-gpio:
gpio-0 ( )
gpio-1 ( )
gpio-2 ( |pcie_wake ) in hi
gpio-3 ( )
gpio-4 ( )
gpio-5 ( )
gpio-6 ( |system-suspend-gpio ) out hi
gpio-7 ( )
gpio-8 ( )
gpio-9 ( )
gpio-10 ( )
gpio-11 ( )
gpio-12 (SPI1_MOSI )
gpio-13 (SPI1_MISO )
gpio-14 (SPI1_SCK )
gpio-15 (SPI1_CS0 )
gpio-16 (SPI0_MOSI )
gpio-17 (SPI0_MISO )
gpio-18 (SPI0_SCK )
gpio-19 (SPI0_CS0 )
gpio-20 (SPI0_CS1 )
gpio-21 ( )
gpio-22 ( )
gpio-23 ( )
gpio-24 ( )
gpio-25 ( )
gpio-26 ( )
gpio-27 ( )
gpio-28 ( )
gpio-29 ( )
gpio-30 ( )
gpio-31 ( )
gpio-32 ( )
gpio-33 ( )
gpio-34 ( )
gpio-35 ( )
gpio-36 ( )
gpio-37 ( )
gpio-38 (GPIO13 |sysfs ) in hi

I also don’t get any registerred interrupts from that pin until I set the direction to input again. I tried it with another pin and it has the same behaviour. I also used the default dtsi files generated by pinmux excel sheet, but there was no change. It seems as if the state of the pin is disconnected from the internal logic until I set it as input per command.

I did some changes in other device tree files. But I cannot imagine that it has something to do with those changes.

In file …/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi:

Commented out the following lines:

//#include "porg-platforms/tegra210-porg-camera-rbpcv2-imx219.dtsi"
//#include "porg-platforms/tegra210-porg-camera-rbpcv2-dual-imx219.dtsi"
//#include "porg-plugin-manager/tegra210-porg-plugin-manager.dtsi"

In file …/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-p3448-0000-p3449-0000-a02.dts:

Added the following line:

#include “tegra210-porg-p3448-common.dtsi”
#include "tegra210-tc358743.dtsi"
#include “porg-platforms/tegra210-porg-pinmux-p3448-0000-a02.dtsi”
#include “porg-platforms/tegra210-porg-gpio-p3448-0000-a02.dtsi”

hello MarcS,

please disassembler your dtb file into text file to examine your GPIO pin definitions,
for example,
$ dtc -I dtb -O dts -o output.txt tegra210.dtb

Hello,

in the attachement you can find the disassembled file from the HOST.

I copied the dtb file to …/kernel/dtb directory and flashed it with sudo ./flash.sh -r -k DTB jetson-nano-qspi-sd mmcblk0p1. Where can I find the dtb file on the Nano?

dtc -I dtb -O dts -o output.txt tegra210-p3448-0000-p3449-0000-a02.dtb

output.txt (252.1 KB)

I don’t know about the dtb file on the Nano for your case, but this will always be a 100% representation of what the Nano currently runs with:
dtc -I fs -O dts -o extracted.dts /proc/device-tree
(the “/proc/device-tree” can also be browsed as files)

Hello,

here are the disassembled device tree settings directly from the jetson nano.

dtc -I fs -O dts -o extracted.txt /proc/device-tree

extracted.txt (254.8 KB)

hello MarcS,

so, below were default GPIO settings I was talking about.

	gpio@6000d000 {
        ...
		default {
			gpio-output-high = <0x6 0xbb 0xe7>;
			gpio-input = <0xd8 0xc 0xd 0xe 0xf 0xe8 0x26 0x95 0x5 0xbc 0xbd 0xbe 0xc1 0xc2 0xa8 0xa9 0xc8 0xca 0x4d 0x4e 0x4c 0x4f 0x32 0x33 0x10 0x11 0x12 0x13 0x14 0x3a 0x3d 0x3e 0x41 0xe4>;
			gpio-output-low = <0x97 0x98 0xcb 0x38 0x3b 0x3c 0x3f 0x40 0x42>;
			phandle = <0x3c>;
			linux,phandle = <0x3c>;
		};

it looks GPIO3_PE.06 has correct default settings as gpio-input = 0x26

Hi Marcs,

Can you give me the output of following register just after you export pin 38.

  1. $ busybox devmem 0x6000d100
  2. $ busybox devmem 0x6000d110
  3. $ busybox devmem 0x6000d120
  4. $ busybox devmem 0x6000d130

This will check if pin is set to input state at HW level. Ideally, keeping pin in gpio-input should set the pin to input state from the bootloader. It should not be an issue. But let’s check in your case. Let me know the output of above registers.

Thanks,
Shubhi

Hello,

please see my answers below.

After Startup:

marc@marc-desktop:~$ echo 38 > /sys/class/gpio/export

marc@marc-desktop:~$ sudo busybox devmem 0x6000d100

0x00000000

marc@marc-desktop:~$ sudo busybox devmem 0x6000d110

0x00000000

marc@marc-desktop:~$ sudo busybox devmem 0x6000d120

0x00000000

marc@marc-desktop:~$ sudo busybox devmem 0x6000d130

0x00000000

I think all zeros in the registers can’t be correct?!

sudo echo in > /sys/class/gpio/gpio38/direction

marc@marc-desktop:~$ sudo busybox devmem 0x6000d100

0x00000040

marc@marc-desktop:~$ sudo busybox devmem 0x6000d110

0x00000000

marc@marc-desktop:~$ sudo busybox devmem 0x6000d120

0x00000000

marc@marc-desktop:~$ sudo busybox devmem 0x6000d130

0x00000000

Hi Marcs,
Yes, the results are not correct. When you added GPIO PE6 in gpio-input, without export also , in the registers it should show GPIO.
I have verified the settings by adding GPIO PE6 in device tree.
So, the expected results are:
0x6000d100 0x00000040
0x6000d110 0x00000000
0x6000d120 0x00000000
0x6000d130 0x00000000

Hi Marcs,
Can you please give me the output of below command:
$ xxd /proc/device-tree/gpio@6000d000/default/gpio-input

This will confirm if GPIO PE6 is present in gpio default input section.

Thanks,
Shubhi

Hi Marcs,

Is this still an issue to support? Any result can be shared?

Hi,

sorry for the late response.

marc@marc-desktop:~$ xxd /proc/device-tree/gpio@6000d000/default/gpio-input
00000000: 0000 00d8 0000 000c 0000 000d 0000 000e …
00000010: 0000 000f 0000 00e8 0000 0026 0000 0095 …&…
00000020: 0000 0005 0000 00bc 0000 00bd 0000 00be …
00000030: 0000 00c1 0000 00c2 0000 00a8 0000 00a9 …
00000040: 0000 00c8 0000 00ca 0000 004d 0000 004e …M…N
00000050: 0000 004c 0000 004f 0000 0032 0000 0033 …L…O…2…3
00000060: 0000 0010 0000 0011 0000 0012 0000 0013 …
00000070: 0000 0014 0000 003a 0000 003d 0000 003e …:…=…>
00000080: 0000 0041 0000 00e4 …A…

As a workaround, I created a batch file which explicitly sets the port as input.