GPIO doesn't work?

This should be such a simple task, but I can’t get GPIO to work on my TX2. I’ve noticed that the mappings seem to have been moved to start at 256 instead of 0 (as it was on X1), but even adding 256 to the GPIO number, I can’t seem to toggle GPIO.

I’ve tried PZ0 (200+256), PK2 (82+256), PK3 (83+256), PBB3 (219+256), and others, and none of them toggle when commanded. I’m using a typical sysfs workflow, but the pins simply don’t change.

root@tegra-ubuntu:/sys/class/gpio# echo 475 > export
root@tegra-ubuntu:/sys/class/gpio# cd gpio475
root@tegra-ubuntu:/sys/class/gpio/gpio475# cat direction
in
root@tegra-ubuntu:/sys/class/gpio/gpio475# echo out > direction
root@tegra-ubuntu:/sys/class/gpio/gpio475# cat direction
out
root@tegra-ubuntu:/sys/class/gpio/gpio475# cat value
0
root@tegra-ubuntu:/sys/class/gpio/gpio475# echo 1 > value
root@tegra-ubuntu:/sys/class/gpio/gpio475# cat value
1

Everything works as expected there, but the levels don’t change on the pins.

Am I missing something?

Hi
T186 gpio pin maps is kind different with t210, there’re to group like below and you can reference to the …/kernel/kernel-4.4/include/dt-bindings/gpio/tegra186-gpio.h to figure out the gpio number.

GPIOs 256-319, platform/c2f0000.gpio, tegra-gpio-aon:
GPIOs 320-511, platform/2200000.gpio, tegra-gpio:

/* GPIOs implemented by main GPIO controller */
#define TEGRA_MAIN_GPIO_PORT_A 0
#define TEGRA_MAIN_GPIO_PORT_B 1
#define TEGRA_MAIN_GPIO_PORT_C 2
#define TEGRA_MAIN_GPIO_PORT_D 3
#define TEGRA_MAIN_GPIO_PORT_E 4
#define TEGRA_MAIN_GPIO_PORT_F 5
#define TEGRA_MAIN_GPIO_PORT_G 6
#define TEGRA_MAIN_GPIO_PORT_H 7
#define TEGRA_MAIN_GPIO_PORT_I 8
#define TEGRA_MAIN_GPIO_PORT_J 9
#define TEGRA_MAIN_GPIO_PORT_K 10
#define TEGRA_MAIN_GPIO_PORT_L 11
#define TEGRA_MAIN_GPIO_PORT_M 12
#define TEGRA_MAIN_GPIO_PORT_N 13
#define TEGRA_MAIN_GPIO_PORT_O 14
#define TEGRA_MAIN_GPIO_PORT_P 15
#define TEGRA_MAIN_GPIO_PORT_Q 16
#define TEGRA_MAIN_GPIO_PORT_R 17
#define TEGRA_MAIN_GPIO_PORT_T 18
#define TEGRA_MAIN_GPIO_PORT_X 19
#define TEGRA_MAIN_GPIO_PORT_Y 20
#define TEGRA_MAIN_GPIO_PORT_BB 21
#define TEGRA_MAIN_GPIO_PORT_CC 22
#define TEGRA_MAIN_GPIO_PORT_DD 23

#define TEGRA_MAIN_GPIO(port, offset) \
	((TEGRA_MAIN_GPIO_PORT_##port * 8) + offset)

/* GPIOs implemented by AON GPIO controller */
#define TEGRA_AON_GPIO_PORT_S 0
#define TEGRA_AON_GPIO_PORT_U 1
#define TEGRA_AON_GPIO_PORT_V 2
#define TEGRA_AON_GPIO_PORT_W 3
#define TEGRA_AON_GPIO_PORT_Z 4
#define TEGRA_AON_GPIO_PORT_AA 5
#define TEGRA_AON_GPIO_PORT_EE 6
#define TEGRA_AON_GPIO_PORT_FF 7

#define TEGRA_AON_GPIO(port, offset) \
	((TEGRA_AON_GPIO_PORT_##port * 8) + offset)

So how can I figure out a correct physical PIN?

For example, based on this http://www.jetsonhacks.com/nvidia-jetson-tx1-j21-header-pinout/, I could not call pin 37

echo 137 > /sys/class/gpio/export
-bash: echo: write error: Invalid argument

ON Jetson TX1, I could look into driver/pinctrl/pinctrl-tegra210.c, but I could not find pinctrl-tegra186.c

If I want to export PIN 37 to user space, what am I missing?
Thanks!

Am I missing something? How am I supposed to know what “T210” and “T186” are, and how they map to GPIO, and which of them I’m supposed to use? Where is this documented?

One thing we’re missing is a labeled image of the default carrier board, where each pin of each connector is labeled with the pin name, and separately, a table that shows the part names and pin numbers for the TX2.

I don’t know of a good way to map pins to number, but so far as naming goes, each Tegra SoC has a series designation, and then specific implementations. For example, the older Tegra 3 is actually the t3x series, and one specific case is the t30 (example, Apalis T30 from Toradex.com). Anything that would be a tegra 12x is a Tegra K1, the Jetson TK1 is specifically the tegra 124. Anything TX1 is a tegra 21x, the Jetson TX1 is specifically the tegra 210 implementation (I haven’t looked, but perhaps the shield TV is a t21x, but not a t210). Anything TX2 would be the tegra 18x series, the Jetson is specifically the tegra 186 implementation. Most kernel build default configs name only the series, not a specific chip, thus a starting TX2 kernel config of “make tegra18_defconfig” matches the Jetson or any other TX2 (if there are eventually different variants of the TX2 SoC, such as a different core count, they’ll still be backwards compatible with “make tegra18_defconfig”).

Okay, so, that’s a bunch of information, but it doesn’t help solve the actual problem, which is that there is a big gaping hole in the documentation set for this system.
To be fair, the hardware has at least a reasonable level of documentation. There are even timing diagrams for the more sensitive busses, which is more than can be said for certain data sheets I’ve worked with.
However, the software seems … like an afterthought. Or a black box. About as bad, documentation-wise, as Intel. (Intel is great at hardware, and sucks at software support. Some other hardware vendors are actually very good at also supporting software development. Seems like NVIDIA isn’t (yet?) in that bucket.)

Thanks linuxdev for your reply, but I am still confused about what to do.

NVIDIA recently uploaded “Jetson TX2 Module Pinmux” and “Jetson TX2 Module Data Sheet” on Jetson Download Center | NVIDIA Developer .

Although the J21 GPIO Addresses on TX2 are very similar to TX1, I could not export the PIN using the map provided by JetsonHacks. [ I am new to this ].

So, what is the correct approach to find out which pin to use? Coming from Arduino/Teensy development, I wish NVIDIA could provide a simple way to use J21 GPIO by specifying the PIN Numbers.

It’s starting to feel like they had to get the TX2 out, perhaps to get feedback, and perhaps because of internal reasons, and what’s out now, is not actually a fully functional kit.
For example, the CAN drivers aren’t even exposed yet, and, as we’re finding, the GPIO doesn’t yet work right.
I have high hopes for whatever the next release will be!

Separately, I really think someone at NVIDIA who knows about the GPIOs should write up the pipeline from kernel to hardware to board to headers, and document each step. Assuming that knowledge is in the head of one person, and that person knows what an end developer like us would need to know, that shouldn’t take a lot of time. Meanwhile, if those bits are owned by different teams, and the teams are not experienced end developers, and perhaps one or two people no longer work in that department (or at that company) then we’re probably in for a rougher ride …

You can download the TX2 pinmux file to find the pin name and reference to tegra186-gpio.h to find the pin number.
For example the pin 37 “GPIO8/ALS_PROX_INT” for TX2 is GPIO PQ4 then the pin number is 320 + (8x16 +4) = 452

320 is from cat /sys/kernel/debug/pinctrl/700008d4.pinmux/gpio-ranges

GPIOs 256-319, platform/c2f0000.gpio, tegra-gpio-aon:
GPIOs 320-511, platform/2200000.gpio, tegra-gpio:

And there’s pinctrl-tegra186.c located kernel/t18x/drivers/pinctrl/

Thank you.

I guess this means that the good news is that it is technically possible to trace a pin to its GPIO number.

Now, put yourself in the developer’s shoes – is this how you find that the documentation for most products people actually want to use is structured?

Separately, I opened up that Excel sheet (which has a lot of un-explained columns) and the first thing I saw was this:

UART3_TX	H10	UART4_TX
UART3_RX	H9	UART4_RX

Literally, you rename a UART from “4” to “3” halfway through the signal path.

This is … something I’ve never, ever, ever, seen actually lead to happiness in the long run. I’ve seen it done a few times, and I even thought it was a good idea once, but it always ends in tears.

If marketing, or some engineering manager, or someone else EVER, for ANY REASON, decides that it might be a good idea to introduce another numbering than what is already physically present, you can immediately tell that it means they haven’t yet been on enough of a train wreck to know what a bad idea that is.

Anyway, thanks for the answer, and what documentation currently exists to make forward progress at least technically possible.

2 Likes

Sounds easy. I’ll summarize.

You just reference the group “GPIOs 320-511, platform/2200000.gpio, tegra-gpio” and then multiply by 8 and add an offset. Which group depends on whether you are using the MAIN or AON GPIOs. The ports are labeled A through Z through FF. The TX2 is the tegra18x and tegra 186. You download the TX2 pinmux file and look at tegra186-gpio.h. For example pin 37 “GPIO8/ALS_PROX_INT” GPIO PQ4 so the pin number is 320 + (8x16 +4) = 452, where 320 is the offset and 16 is something else and we multiply it by 8 and add 4 which might be the number of the gpio.h file. Be careful if the GPIO is renamed to some other GPIO number.

lol

1 Like

Sweet! Thank you guys. It finally makes sense now…That 320 was tricky for me. Anyway, it works.

That sounds like it’s technically correct. Which is the best kind of correct!

All the GPIOs on J21:

GPIO8_ALS_PROX_INT = 388
GPIO9_MOTION_INT = 298
GPIO11_AP_WAKE_BT = 389
GPIO16_MDM_WAKE_AP = 481
GPIO19_AUD_RST = 398

Procedure:

  • Look up GPIO name (e.g. “GPIO8_ALS_PROX_INT”) in TX2 pinmux spreadsheet.
  • Note pin name (e.g. “GPIO_PI4”). Port is “I”, pin number is 4.
  • Look up the port and its group in tegra186-gpio.h (e.g. “I” => 8 in main group).
    If the group is “main”, offset is 320.
    If the group is “aon”, offset is 256.
  • GPIO export value is group + (port * 8 + pin) (e.g. 320 + (8 * 8 + 4) = 388)
3 Likes

There seems to be a conflict in the answers given by @ShaneCCC and @readonly.
ShaneCC suggests that the IC Ball Name should be used for determining the offset. Readonly suggests that the Pin Muxing/Customer Usage should be used.
Which is correct?

Hi All
It’s my mistake should be the pin muxing.

I was able to follow @readonly’s instructions and figured out that GPIO20/AUD_INT is 397. How do I change in the kernel or where ever, so that when TX2 starts up, GPIO20’s default direction input and low (0v)?

Hi Tom
You can add below sample piece code to your device tree. And you can set the direction when it’s input pin.

gpio@2200000 {
                gpio-control-input {
                        gpio-hog;
                        input;
                        gpios = <CAM0_RST_L 0 CAM0_PWDN 0>;
                        label = "cam0-rst", "cam0-pwdn";
                };

Hi all,

I am trying to read the GPIO pins GPIO18_MDM_COLDBOOT and GPIO17_MDM2AP_READY, I am able to read these GPIOs using a TX1 board but I am not able to read correctly the value from one of these GPIOs using TX2 board.

This is the GPIO information
Pin name             GPIO Name      GPIO#           
GPIO18_MDM_COLDBOOT  GPIO3_PI.06    390
GPIO17_MDM2AP_READY  GPIO3_PI.07    391

When I have read the GPIO 391 the value is always the same (0), since I am able to read this GPIO using TX1 board, I think is not a hardware problem.

Reading the file ‘/sys/kernel/debug/gpio’ the configuration of the GPIO is the expected:

gpio-391 (                    |sysfs               ) in  lo

How I can know if this GPIO is already working as a GPIO? I am wondering if by default it has been configured with its second function.

Thanks.

Hi,

I have seen that GPIO function is defined in this file tegra210-jetson-cv-pinmux-p2597-2180-a00.dtsi for TX1, the GPIOs are under the structure pinmux: pinmux@700008d4. For example, this is the definition for MDM2AP_READY (PK.04) and MDM_COLDBOOT (PK.06).
The GPIO function is defined by “nvidia,function”

pk4 {
            nvidia,pins = "pk4";
            nvidia,function = "rsvd1";
            nvidia,pull = <TEGRA_PIN_PULL_UP>;
            nvidia,tristate = <TEGRA_PIN_DISABLE>;
            nvidia,enable-input = <TEGRA_PIN_ENABLE>;
    };
 
    pk6 {
            nvidia,pins = "pk6";
            nvidia,function = "rsvd1";
            nvidia,pull = <TEGRA_PIN_PULL_UP>;
            nvidia,tristate = <TEGRA_PIN_DISABLE>;
            nvidia,enable-input = <TEGRA_PIN_ENABLE>;
    };

I have searched for equivalent definitions for TX2 but apparently there is not definition for these GPIOs in the device tree files.

Do you know why they are not defined?
If the GPIO is not defined is applied some default configuration?

Thanks.