SPI0 doesn't work on Jetson Nano with eMMC, but does work on Jetson Nano with SD Card

I have verified this on 4 Jetson Nano modules (2 with SD Card and 2 with eMMC). The rootfs and Image are identical on all 4 modules. The device tree has a small modification for the SD Card vs eMMC (see attached file).

devicetree_diff.txt (473 Bytes)

The u-boot finds a spi flash “mx25u3235f” on the Jetson Nano with SD Card. And u-boot fails to find the spi flash on the Jetson Nano with eMMC. The scope shows no activity on the spi0 pins on the Jetson Nano with eMMC. Attached are the u-boot log, sysfs pinmux settings, and gpio settings for both. The ksz8795-switch uses the spi driver to read/write registers, and when it fails the chip IDs are all zero.

spi0-pass-sdcard.txt (9.2 KB)

spi0-fails-emmc.txt (8.6 KB)

Command used to flash the SD Card module:
sudo ./flash.sh jetson-nano-devkit mmcblk0p1

Command used to flash the eMMC module:
sudo ./flash.sh jetson-nano-emmc mmcblk0p1

Could you check with loopback test to confirm the pinmux setting is correct for both devices.

After connecting the loopback wire on the 40 pin connector, I ran the loopback test and found the same results.

Jetson Nano with SD Card (PASS):

$ cat /sys/kernel/debug/tegra_gpio
0:0 60 40 40 20 00 00 000000
0:1 00 00 00 00 00 00 000000
0:2 00 00 00 00 00 00 000000

$ sudo ./spidev_test -D /dev/spidev0.0 -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 kHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D |…@…|
RX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D |…@…|

Jetson Nano with eMMC (FAIL):

$ cat /sys/kernel/debug/tegra_gpio
0:0 60 40 40 20 00 00 000000
0:1 f0 00 00 00 00 00 000000
0:2 1f 00 00 10 00 00 000000

$ sudo ./spidev_test -D /dev/spidev0.0 -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 kHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D |…@…|
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…|

From the Jetson Nano pinmux spread sheet it looks like the SPI pins are set to GPIOs by default. I tried to change the pins to sfio with the following device tree changes, but that didn’t work either.

gpio: gpio@6000d000 {
	gpio-init-names = "default";
	gpio-init-0 = <&gpio_default>;
	gpio_default: default {
		// gpio-to-sfio = <16 17 18 19 20>;
		gpio-hog;
		function;
		gpios = <
			TEGRA_GPIO(C, 0) 0 
			TEGRA_GPIO(C, 1) 0 
			TEGRA_GPIO(C, 2) 0 
			TEGRA_GPIO(C, 3) 0
			TEGRA_GPIO(C, 4) 0
			>;

$ cat /sys/kernel/debug/tegra_gpio
0:0 60 40 40 20 00 00 000000
0:1 f0 00 00 00 00 00 000000
0:2 1f 00 00 10 00 00 000000

What’s the version? J4.4/J4.5 default should clean the GPIO configure.

$ cat /etc/nv_tegra_release
R32 (release), REVISION: 5.0, GCID: 25531747, BOARD: t210ref, EABI: aarch64, DATE: Fri Jan 15 22:55:35 UTC 2021

Same result with newer version.

$ cat /etc/nv_tegra_release
R32 (release), REVISION: 5.1, GCID: 26202423, BOARD: t210ref, EABI: aarch64, DATE: Fri Feb 19 16:45:52 UTC 2021

$ cat /sys/kernel/debug/tegra_gpio
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
A: 0:0 64 40 40 04 00 00 000000
B: 0:1 f0 00 00 00 00 00 000000
C: 0:2 1f 00 00 18 00 00 000000
D: 0:3 00 00 00 00 00 00 000000
E: 1:0 40 00 00 00 00 00 000000
F: 1:1 00 00 00 00 00 00 000000
G: 1:2 0c 00 00 00 00 00 000000
H: 1:3 fd 99 00 60 00 00 000000
I: 2:0 07 07 03 00 00 00 000000
J: 2:1 f0 00 00 00 00 00 000000
K: 2:2 00 00 00 00 00 00 000000
L: 2:3 00 00 00 00 00 00 000000
M: 3:0 00 00 00 00 00 00 000000
N: 3:1 00 00 00 00 00 00 000000
O: 3:2 00 00 00 00 00 00 000000
P: 3:3 00 00 00 00 00 00 000000
Q: 4:0 00 00 00 00 00 00 000000
R: 4:1 00 00 00 00 00 00 000000
S: 4:2 a0 80 00 00 00 00 000000
T: 4:3 01 01 00 00 00 00 000000
U: 5:0 00 00 00 00 00 00 000000
V: 5:1 03 00 00 02 00 00 000000
W: 5:2 00 00 00 00 00 00 000000
X: 5:3 78 08 08 70 00 60 606000
Y: 6:0 06 00 00 02 00 00 000000
Z: 6:1 0f 08 00 04 00 04 000400
AA: 6:2 00 00 00 00 00 00 000000
BB: 6:3 01 00 00 00 00 00 000000
CC: 7:0 92 80 80 02 00 12 121200
DD: 7:1 01 00 00 00 00 00 000000
EE: 7:2 00 00 00 00 00 00 000000
FF: 7:3 00 00 00 00 00 00 000000

$ ./spidev_test -D /dev/spidev0.0 -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D | …@…
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | …
root@nanoemmc:~#

Have a try below patch and below to dts to check the tegra_gpio status.

default {
	gpio-hog;
	function;
 	gpios = <0x10 0x0 0x11 0x0 0x12 0x0 0x13 00 0x14 0x0>;
};

ShaneCCC thanks for your help! Finally got spi0 working on Jetson Nano with eMMC for both linux 4.9 and linux 5.10. And it still works on Jetson Nano with SD Card.

For linux 4.9 I used the following three fixes: device tree fix (above), patch to drivers/gpio/gpio-tegra.c (link above), and the following commands to fix the spi0 pinmuxes.

devmem2 0x70003050 h 0xe044
devmem2 0x70003054 h 0xe044
devmem2 0x70003058 h 0xe044
devmem2 0x7000305c h 0xe048
devmem2 0x70003060 h 0xe048

These fixes didn’t work on the upstream linux 5.10. The gpios and pinmuxes in the device tree are not recognized, and report the error of “no hogging state specified, bailing out”. To get Jetson Nano eMMC spi0 working on the upstream linux required one fix shown below at the end of tegra_gpio_probe() in drivers/gpio/gpio-tegra.c.

// free spi0 pins
for (gpio = 16; gpio <= 20; gpio++) {
	tegra_gpio_free(&tgi->gc, gpio);
}
1 Like

Great to hear that.

Thanks

This is a better solution for linux 5.10 as it clears all gpios, not just the SPI0 gpios. It can be placed in tegra_gpio_probe() after the call to devm_platform_ioremap_resource() in drivers/gpio/gpio-tegra.c.

for (gpio = 0; gpio < tgi->gc.ngpio; gpio++) {
	tegra_gpio_disable(tgi, gpio);
}