TPM on SPI2 in Uboot

Hi everyone,

We are trying to implement a more secure solution by measuring our boot and expanding the PCRs in our TPM. To do this we are going to be editing the only binary that we can build from source that is protected by secure boot, Das U-Boot.

I have successfully gotten the tpm2 configurations built into u-boot and we are signing boot.img and flashing it to our Nano SoM.

We have our Infineon TPM on SPI2, and we have successfully been using tpm tools from the OS to use our TPM. The Pinmux and the DT for the kernel work great. However, I am having trouble being able to call “tpm2 init” from the bootloader.

This is the change we are adding (which is almost the same as our DT change for the kernel):

spi@7000d600 {
		status = "okay";
		cs-gpios = <&gpio TEGRA_GPIO(B, 7) GPIO_ACTIVE_LOW>;

		slb9670: spi@0{
			compatible = "infineon,slb9670", "tis,tpm2-spi", "tcg,tpm_tis-spi"; //Our Kernel DT only has infineon,slb9670
			reg = <0>;
			spi-max-frequency = <32000000>;
			status = "okay";
			reset-gpios = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_LOW>;

			controller-data {
				nvidia,variable-length-transfer;
				nvidia,rx-clk-tap-delay = <31>;
			};
		};
	};

When I run TPM2 init I get the following:

Tegra210 (P3450-0000) # tpm2 init
tpm_tis_spi_probe() tpm_tis_spi_probe: missing reset GPIO
tpm_tis_spi_xfer() tpm_tis_spi_xfer: timeout on wait state
tpm_tis_spi_probe() tpm_tis_spi_probe: no device found
Couldn't set TPM 0 (rc = 1)

I get similar errors when running sf probe, so I thought maybe it was using SPI0 instead of SPI2:

Tegra210 (P3450-0000) # sf probe
tpm_tis_spi_probe() tpm_tis_spi_probe: missing reset GPIO
tpm_tis_spi_xfer() tpm_tis_spi_xfer: timeout on wait state
tpm_tis_spi_probe() tpm_tis_spi_probe: no device found
Failed to initialize SPI flash at 0:0 (error -5)

But if I try and run sf on SPI2 directly I get the following errors:

Tegra210 (P3450-0000) # sf probe 2:0
Invalid bus 2 (err=-19)
Failed to initialize SPI flash at 2:0 (error -19)

This makes me think, we are not enabling SPI2 correctly. We know the HW works because this has been working for months from the OS. Has anyone configured a TPM like this from u-boot? Do we need to edit the pinmux differently for u-boot?

After some work it seems that there isn’t a tegra210 driver for SPI in u-boot only a tegra114 driver for it. It also seems that the cs-gpio is not being used by the tegra114 driver so this might be my issue. Has anyone else successfully gotten this working with the default drivers? I was looking at the Rpi4 guide and it uses a SW based bit bang driver instead. Is this the way to go?

I tried using the SW based bit bang driver and I still am unable to contact my TPM. This is what I am using for the device tree, following the Rpi4 guide:

	spi@7000d600 {
		status = "okay";
		compatible = "spi-gpio";
		gpio-sck = <&gpio TEGRA_GPIO(B, 6) GPIO_ACTIVE_HIGH>;
		gpio-mosi = <&gpio TEGRA_GPIO(B, 4) GPIO_ACTIVE_HIGH>;
		gpio-miso = <&gpio TEGRA_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
		cs-gpios = <&gpio TEGRA_GPIO(B, 7) GPIO_ACTIVE_LOW>;
		spi-delay-us = <0>;
		#address-cells = <1>;
		#size-cells = <0>;
		status = "okay";

		/* for kernel driver */
		sck-gpios = <&gpio TEGRA_GPIO(B, 6) GPIO_ACTIVE_HIGH>;
		mosi-gpios = <&gpio TEGRA_GPIO(B, 4) GPIO_ACTIVE_HIGH>;
		miso-gpios = <&gpio TEGRA_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
		num-chipselects = <1>;

		slb9670: slb9670@0 {
			compatible = "infineon,slb9670", "tis,tpm2-spi", "tcg,tpm_tis-spi";
			reg = <0>;
			gpio-reset = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_LOW>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			/* for kernel driver */
			spi-max-frequency = <1000000>;
		};
	};

I also bumped the log level to 7 in u-boot. my console ran out of space for the logging so I am only going to attach the end of the call to show that the GPIOs are getting changed and read:

set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
soft_spi_xfer() spi_xfer: slave spi@7000d600:slb9670@0 dout E59FF3F8 din 00000000 bitlen 8
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 0
set_level() set_level: port = 1, bit 4 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN
tpm_tis_spi_xfer() tpm_tis_spi_xfer: timeout on wait state
soft_spi_xfer() spi_xfer: slave spi@7000d600:slb9670@0 dout E59FF3F8 din E59FF3F8 bitlen 0
tegra_gpio_set_value() gpio_set_value: pin = 15 (port 1:bit 7), value = 1
set_level() set_level: port = 1, bit 7 == 1
tpm_tis_spi_probe() tpm_tis_spi_probe: no device found
Couldn't set TPM 0 (rc = 1)
cmd_call() Command failed, result=1

Based on this and our pinmux the right GPIOs are being changed. But there is still no devices being found and I cannot contact the TPM.

@jjsalzano,

I’m Tom Warren, the NVIDIA U-Boot PIC. Although I’ve never used the tpm commands on Nano, I did see a couple of problems in your posts above.

  • You are getting a “tpm_tis_spi_probe() tpm_tis_spi_probe: missing reset GPIO” response from your first set of DTB changes because you have ‘reset-gpios’ instead of 'gpio-reset` in your slb9670 node. If you look at the code in drivers/tpm/tpm2_tis_spi.c, you’ll see it’s looking for a property named ‘gpio-reset’. ‘reset-gpios’ appears nowhere in the TPM code, at least not in our downstream (L4T) version of U-Boot.
  • Your bit bang changes to the DTB correct this, using ‘gpio-reset’ correctly. You can probe the SPI lines using an inexpensive analyzer like the Salaea Logic to see what’s really happening on the SPI bus. Compare what happens when the kernel talks to your TPM and what happens under U-Boot.
  • I haven’t checked, but you may want to look at upstream (Denx) U-Boot to see if any other board has made changes to the TPM ‘driver’, or posted questions to the list & gotten help w/TPM on SPI. They are a great resource for help with things that L4T U-Boot doesn’t support/hasn’t tested.
  • Finally, I’d add a bunch more debug spew to both the U-Boot TPM driver code and the kernel code, so you can see exactly what’s happening during probe/read/etc. in both cases and perhaps find out what’s missing on the U-Boot side.

HTH,
Tom

@TWarren
Hi Tom,
Thank you for the response. It took me until thismorning to get into the office with the equipment to look at the SPI bus. So I was waiting to respond.

On your first point when I was looking at the code somewhere I am certain I saw it use reset-gpios and then gpio-reset as legacy support. But of course now that I look I cannot find it anywhere.

We hooked up the probe and saw an interesting result. When we let the Jetson boot to the OS we ran some TPM2 commands and saw the correct response both from the TPM and on the analyzer. When we rebooted into u-boot and ran “tpm2 init” we saw the chip select line get pulled down for about 15ms, however clock, miso, and mosi don’t change at all. No activity is detected on any SPI lines except for CS. As you can see in the log the SOFT SPI driver believes that the lines are changing. I am going to try and use the tegra114 spi driver next time and see if we also see no activity.

I did a diff on the old and new driver code. The upstream has some changes but not a lot. I’ll try and port in the upstream but I don’t have high confidence that it will change anything.

I am curious about something however. Where does the pinmux get loaded from for cboot? We had changed the kernel to load the DTB from the filesystem to support our remote update solution. However, from what I am seeing cboot seems to be taking it from the DTB partition instead and setting up the pins. Is this what is happening? When we flash the Jetson initially the DTB in the partition and the one loaded from the FS are the same, but Is there a possibility that the PinMux could be causing an issue?

Joseph

Joseph,

Nice work. Yes, if only CS is moving but not MISO/MOSI/SCK, then it’s likely a pinmux issue. CBoot on Nano takes the DTB from the flash partition (passed up by nvtboot/MB2) and uses that to set the GPIO & pinmux states. So you’ll need to look at the SPI2 pinmux/GPIO settings and change them in the DTB you flash to RP1/DTB partition(s) - since SPI2 isn’t used by the devkit as shipped, they are likely not configured correctly. To start, you can change the SPI2 pinmux settings from within U-Boot using mem read/write commands (md/mw/mm) and the TRM to set them to SPI2 for the PM bits 1:0, correct PU/PD/IO, etc. just like the kernel settings. You can dump the pinmux regs from the kernel using something like devmem to get a good starting point. Once the TPM commands are working from U-Boot w/the correct pinmux settings, you can change the DTB source & recompile the kernel to generate a new DTB (or use DTC if you know how to dump/edit/compile the original DTB) and reflash it to both RP1 and DTB partitions. If you have problems getting the DTB right, you can always slam the pinmux regs from within U-Boot as a WAR. Hopefully that’s where the problem lies.

Tom

Hi Tom,

I should clarify, at the initial boot (Which is where we are trying to test this TPM2 functionality) the DTB in the RP1 and DTB partitions is the same as the one in the FS. I am more trying to determine if during our update process we will have to flash RP1 and DTB with our .dtb contents in addition to just laying down the file in the fs if we want the changes in u-boot.

This being said, our initial PinMux (in DTB, RP1, and the /boot dir) has the SPI2 functionality enabled:

			spi2_mosi_pb4 {
				nvidia,pins = "spi2_mosi_pb4";
				nvidia,function = "spi2";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

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

			spi2_sck_pb6 {
				nvidia,pins = "spi2_sck_pb6";
				nvidia,function = "spi2";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

			spi2_cs0_pb7 {
				nvidia,pins = "spi2_cs0_pb7";
				nvidia,function = "spi2";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

I know that spi2_cs0_pb7 is working because out chip select line does in fact change. Is there somewhere else I can be looking to debug further? It seems weird that the gpio_tegra driver is reporting the lines changing without error, but the probes are not picking anything up. Is there a deeper layer I can be looking at for answers?

If the pinmux looks right (I’d still dump those registers in U-Boot and check them against the TRM just to be sure), then the next thing I’d check is the SPI2 CAR (Clock and Reset) registers - make sure it’s out of reset, that it has a reasonable clock, etc. Again, if needed you can dump those reggies from the kernel and see what they are set to and mimic them in U-Boot to see if you can get your signals wiggling.

Tom

Hi @TWarren

I am still really trying to get this working, and I haven’t had luck yet. I was stuck getting our decrypted LUKs partition mounted with fstab and just got back to this last night.

So I tried to merge in just changes to the drivers in question from the upstream but it propagated the requirements. So what I did was take the latest OE4T uboot as a whole and used that instead (with the same type of configuration and the same DTs). Interestingly that is where I was seeing that reset-gpios is used.

Anyway. Using the OE4T uboot didn’t magically fix our issue. So I switched back to the NVidia u-boot for now to continue debugging. I hope I am dumping and looking at the right registers, and I am looking at the TRM. Please let me know if I am royally screwing this up. From the OS this is what I am seeing with cat /sys/kernel/debug/tegra_pinctrl_reg for SPI:

Bank: 1 Reg: 0x70003064 Val: 0x00006004 -> spi2_mosi_pb4
Bank: 1 Reg: 0x70003068 Val: 0x00006044 -> spi2_miso_pb5
Bank: 1 Reg: 0x7000306c Val: 0x00006004 -> spi2_sck_pb6
Bank: 1 Reg: 0x70003070 Val: 0x00006004 -> spi2_cs0_pb7
Bank: 1 Reg: 0x70003074 Val: 0x00006001 -> spi2_cs1_pdd0

I then look at the same registers in u-boot and I see this:

Tegra210 (P3450-0000) # md.l 0x70003064 5
70003064: 00006024 00006064 00006024 00006024    $`..d`..$`..$`..
70003074: 00006021                               !`..

So they don’t match. I used mw to make them match:

Tegra210 (P3450-0000) # md.l 0x70003064 5
70003064: 00006004 00006044 00006004 00006004    .`..D`...`...`..
70003074: 00006001                               .`..

I then run tpm2 init again but I don’t see any difference. Note that in the OS we are using the tegra210 SPI driver but we are using SOFT_SPI in uboot.

I am not sure where I should be finding the CAR registers. It seems that the offset according to the TRM might be 0x8 I looked at 0x70000008:

Tegra210 (P3450-0000) # md.l 0x70000008 1
70000008: 00000c00                               ....

This seems to indicate that SWR_SPI2_RST (bit 12) is low which means that the reset is not enabled.

the gpios seem to be being used correctly:

Tegra210 (P3450-0000) # gpio status
Bank B:
B4: output: 0 [x] spi@7000d600.gpio-mosi
B5: input: 0 [x] spi@7000d600.gpio-miso
B6: output: 1 [x] spi@7000d600.gpio-sck
B7: output: 1 [x] spi@7000d600.cs-gpios

Bank Z:
Z1: input: 0 [x] sdhci@700b0000.cd-gpios
Z3: output: 1 [x] sdhci@700b0000.power-gpios

Bank DD:
DD0: output: 1 [x] slb9670@0.gpio-reset

I did capture the start of the debug spew and am attaching it here.

Tegra210 (P3450-0000) # log level 7
Tegra210 (P3450-0000) # tpm2 init
uclass_find_device_by_seq() 0 -1
uclass_find_device_by_seq() 0 0
uclass_find_device_by_seq()    - -1 -1 'slb9670@0'
uclass_find_device_by_seq()    - not found
clk_set_defaults() clk_set_defaults(slb9670@0)
clk_set_default_parents() clk_set_default_parents: could not read assigned-clock-parents for 00000000fc808b40
ofnode_read_prop() ofnode_read_prop: assigned-clock-rates: ofnode_read_prop() <not found>
of_read_u32() of_read_u32: #gpio-cells: of_read_u32() 0x2 (2)
uclass_get_device_by_ofnode() Looking for gpio@6000d000
uclass_find_device_by_ofnode() Looking for gpio@6000d000
uclass_find_device_by_ofnode()    - result for gpio@6000d000: gpio@6000d000 (ret=0)
uclass_get_device_by_ofnode()    - result for gpio@6000d000: gpio@6000d000 (ret=0)
gpio_request_tail() gpio_request_tail: dm_gpio_requestf failed
gpio_request_tail() gpio_request_tail: Node 'slb9670@0', property 'gpio-reset', failed to request GPIO index 0: -16
tpm_tis_spi_probe() tpm_tis_spi_probe: missing reset GPIO
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
soft_spi_xfer() spi_xfer: slave spi@7000d600:slb9670@0 dout 0000D480 din 00001388 bitlen 32
tegra_gpio_set_value() gpio_set_value: pin = 15 (port 1:bit 7), value = 1
set_level() set_level: port = 1, bit 7 == 1
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 15 (port 1:bit 7), value = 0
set_level() set_level: port = 1, bit 7 == 0
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 0
set_level() set_level: port = 1, bit 6 == 0
tegra_gpio_set_value() gpio_set_value: pin = 12 (port 1:bit 4), value = 1
set_level() set_level: port = 1, bit 4 == 1
tegra_gpio_set_value() gpio_set_value: pin = 14 (port 1:bit 6), value = 1
set_level() set_level: port = 1, bit 6 == 1
tegra_gpio_get_value() tegra_gpio_get_value: pin = 13 (port 1:bit 5)
get_direction() get_direction: port = 1, bit = 5, IN

@jjsalzano,

Your forced pinmux regs under U-Boot look correct. We’ll have to find out why they aren’t correct by default later (assuming you’ve corrected them in the DTB).

The CAR registers are based at 6000:6000 - see the TRM, Chapter 2, Address Map. The CLK_SOURCE_SPI2 register is at offset 0x118, so 0x60006118. The SPI2 clock reset reg is at offset 0x308 (RST_DEV_H_SET), bit 12 s/b 0 to take the SPI2 HW out of reset. SPI2 clock enable is at offset 0x328 (CLK_ENB_H_SET), again bit 12, set to 1 to enable. There are also pad control registers for SPI2 at 0x70000AE8-0AF8 (see table 26: Pad Control Groups Register Addresses in the TRM). I don’t remember if these need to be manipulated or not - probably best to check them from the kernel side and them make sure they are the same for U-Boot.

I would use the tegra114 SPI driver in U-Boot (ignore the 114 designator - it should work fine for T210 as well, it was just developed for T114 and never had its name changed). I think your GPIO bit-bang driver is trying to wiggle SPI2 GPIOs, and those won’t work right if the PM (function bits) are set for SPI, IIRC (I’ll check the TRM). And using the SPI driver ensures that all of the pad/clock set is done correctly.

I haven’t done any SPI work in U-Boot in years, and I don’t have a SPI chip I can wire to my Nano here at this time, so I can’t walk thru the code to help you. Please check the forum messages - IIRC others have gotten SPI1/SPI2 working with U-Boot.

Tom

@TWarren

Hey Tom,

Thank you so much for your continued help in this matter. It is essential for our disk encryption and the security of an upcoming release.

Thank you for pointing me at the correct areas. From what I see CLK_SOURCE_SPI2 shows 0xc0000098. Which should mean:

  • clk_m
  • clock diviser is either 152 or 77, depending on how I am reading the math in the TRM.

RST_DEV_H_SET is all 0s so bit 12 is also 0, meaning we are out of reset. CLK_ENB_H_SET has bit 12 as 1, so that is good. Everything in the registers 0x70000ae8-af8 are 0 which I am not sure what that means yet.

As you said I will check what is going on in the kernel. I believe I need to add devmem2 to our rootfs to check, so I will be doing that this evening.

Thank you for confirming that the tegra114 driver will work for this. I was kind of hoping it would. I changed out DT back to what we had at the beginning, except for changing to gpio-reset:

/ {
	spi@7000d600 {
		status = "okay";
		cs-gpios = <&gpio TEGRA_GPIO(B, 7) GPIO_ACTIVE_LOW>;

		slb9670: spi@0{
			compatible = "infineon,slb9670", "tis,tpm2-spi", "tcg,tpm_tis-spi";
			reg = <0>;
			spi-max-frequency = <32000000>;
			status = "okay";
			gpio-reset = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_LOW>;

			controller-data {
				nvidia,variable-length-transfer;
				nvidia,rx-clk-tap-delay = <31>;
			};
		};
	};
};

This is the full debug log I have at the moment and I will be trying to add some more logging:

Tegra210 (P3450-0000) # log level 7
Tegra210 (P3450-0000) # tpm2 init
uclass_find_device_by_seq() 0 -1
uclass_find_device_by_seq() 0 0
uclass_find_device_by_seq()    - -1 -1 'spi@0'
uclass_find_device_by_seq()    - not found
clk_set_defaults() clk_set_defaults(spi@0)
clk_set_default_parents() clk_set_default_parents: could not read assigned-clock-parents for 00000000fc808a90
ofnode_read_prop() ofnode_read_prop: assigned-clock-rates: ofnode_read_prop() <not found>
of_read_u32() of_read_u32: #gpio-cells: of_read_u32() 0x2 (2)
uclass_get_device_by_ofnode() Looking for gpio@6000d000
uclass_find_device_by_ofnode() Looking for gpio@6000d000
uclass_find_device_by_ofnode()    - result for gpio@6000d000: gpio@6000d000 (ret=0)
uclass_get_device_by_ofnode()    - result for gpio@6000d000: gpio@6000d000 (ret=0)
gpio_request_tail() gpio_request_tail: dm_gpio_requestf failed
gpio_request_tail() gpio_request_tail: Node 'spi@0', property 'gpio-reset', failed to request GPIO index 0: -16
tpm_tis_spi_probe() tpm_tis_spi_probe: missing reset GPIO
tegra114_spi_set_speed() tegra114_spi_set_speed: regs=000000007000d600, speed=500000
tegra114_spi_set_mode() tegra114_spi_set_mode: regs=000000007000d600, mode=0
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 00000000fc3f9d60 din 00000000fc3f9da0 bitlen 32
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 00000000fc3f9da0 bitlen 8
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tpm_tis_spi_xfer() tpm_tis_spi_xfer: timeout on wait state
tegra114_spi_xfer() tegra114_spi_xfer: slave 2:0 dout 0000000000000000 din 0000000000000000 bitlen 0
spi_cs_deactivate() Deactivate CS, bus 'spi@7000d600'
tegra114_spi_xfer() tegra114_spi_xfer: transfer ended. Value=00000000, fifo_status = 00400005
tpm_tis_spi_probe() tpm_tis_spi_probe: no device found
Couldn't set TPM 0 (rc = 1)
cmd_call() Command failed, result=1

The team EE and I are meeting tomorrow morning to prove the SPI lines again to see if we can get any further.

I completely understand that there is only so much you are able to debug. But so far your help has been extremely helpful, thank you.

I am hoping others might also be able to help if they have gotten this done.

as another datapoint. I removed FDT from our extlinux.conf. So at this point both u-boot and the kernel should be getting the device tree from the DTB partition right? Because I still see the same pinmux registers in the kernel I was seeing with our FDT, and uboot is still different.

Today we were in the lab to do more testing. We were not successful sadly. But we did come up with more datapoints. At this point I have turned of FDT in extlinux.conf so that both uboot and the OS are pulling from the partition.

If we use devmem2 to look at 0x60006118 in the OS the value is 0x1F not 0xc0000098. The other registers had the same bit12 setting.

So today we set the GPIO registers to match the kernel and the clk source register to be 0x1F. We scoped the 4 SPI lanes, this time using the tegra 114 driver as showed with the debug log yesterday.
We again had only the CS line change, all other lines stayed low. We then changed all the GPIO registers to 0x6001, which made them pure output GPIOS and tried to toggle them manually. The only GPIO that changed was the chip select, all other lines stayed low, even though the output in u-boot showed them changing.

  1. FDT line in extlinux.conf - this is only there to allow a kernel & DTB to be matched, i.e. you’ve done something to create a new kernel Image that requires some new HW description in the DTB. Ideally, the HW description in the flashed DTB (RP1 and/or DTB partitions) should be the DTB that’s sent to the kernel on boot by the CPU-BL (CBoot or U-Boot), with any additions like kernel args, etc. added. So whatever modifications you need to make to the DTB to support SPI2 and your TPM device need to be compiled into the ‘kernel’ DTB (usually during kernel build, i.e. ‘tmp kernel’) and copied over to the BSP to be flashed to RP1/DTB. That way your changes will be present for both the bootloader(s) and the kernel.
  1. Your CLK_SOURCE_SPI2 looks to be using the Osc [19.2 MHz, unless the clock doubler is set, then it’s 38.4 MHz], with a divisor of 77 [(N/2)+1]. That’s either 250 or 500KHz, don’t know if that’s a decent SPI clock for your TPM. It may be moot, though, if you are still bit banging - that, IIRC, doesn’t rely on the SPI SCK, but clocks out the bits via GPIO manipulation, so the SCK speed isn’t important.
    One other thought - if you are still bit-banging, you need to make sure the GPIO_CNF registers in the GPIO block are set to GPIO mode, not SFIO mode. In SPI2 mode, those pads need to be set to SFIO (Special Function IO) so the SPI controller can wiggle them, and that’s the default for GPIO_CNF registers (see 9.13.1 in the TRM). So if you are still trying to get the signals moving via GPIO bit-banging, you need to ensure that each GPIO’s _CNF register is set correctly to GPIO mode (1) instead of SFIO mode (0). If you use the ‘gpio’ commands, I believe they will configure those bits correctly, but you should check.

I’d recommend getting the tegra114 SPI driver working with SPI2 as that should set everything up correctly for you - clocks, pads, etc., but probably not pinmux or GPIO_CNF → SFIO, so check those. And you’ll need a complete SPI2 instance in your U-Boot’s tegra210.dtsi, i.e. spi@7000d600 with status=“okay”, compatible = “nvidia,tegra114-spi”, clock & reset entries, etc. Most of it should already be there, but check.

Tom

@TWarren

Hi Tom

We are not using bit banging anymore we have been trying with the tegra114 driver the last few days. So all 3 responses that I had since your previous one were using the Tegre114 driver. I will check the GPIO_CNF register next.

spi@7000d600 is setup correctly as far as I can tell and it shows up with “dm tree” using the tegra114 driver.

@jjsalzano

Excellent news - the SPI driver is the way to go, IMO. Have you tried using the ‘sspi’ and/or ‘sf’ functions and watched the SPI signals @ your TPM to see if you are getting (a) a decent SPI clock and (b) some kind of IO on DI/DO/CS?

Can you post your complete tegra210.dtsi changes (in arch/arm/dts), or email them to me @ twarren@nvidia.com?

Tom

@TWarren

We hooked up the probes again just now and tried both the sspi and sf probe commands and we still did not get any wiggles on MISO,MOSI, or CLK (We have confirmed that we see data when running tpm2_selftest successfully in the OS). What we did was change the following registers to match the OS before hand:
0x60006118: 0xc0000098 → 0x1f
0x6000d004 (GPIO_CNF_0 port B): 0x0 → 0x80 (Doesn’t change any of the pins we are using here)
0x70003064: 0x6024 → 0x6004
0x70003068: 0x6064 → 0x6044
0x7000306c: 0x6024 → 0x6004
0x70003070: 0x6024 → 0x6004
0x70003074: 0x6021 → 0x6001

Note that sf probe seem to work on 0:0 with the tegra210 qspi driver.

What we then did was change all 0x70003064-0x70003074 to 0x6001 and changed 0x6000d004 to 0xFF (All pins in port B are now GPIO output).

We then toggled them individually. We say with “gpio status -a” that they were set to specific values but the probe didn’t see them change.

I will send you our DT files in an email.

Joseph

@TWarren
Hi Tom,
Any insights from the dts/dtsi files? Maybe why we are seeing different register values in uboot vs the kernel (We are not longer using FDT in the kernel, atleast in the feature branch).
I am going to try and use OE4T again and force the registers (the 7 that we know about) and see if anything different happens.

Joseph

@jjsalzano
Sorry, Joseph, no, I have nothing new for you. Note that U-Boot doesn’t touch the pinmux regs, but instead relies on CBoot to process the RP1/DTB DTB pinmux & GPIO settings. So what you see in U-Boot should match what’s in those DTBs from the partition(s). As for the kernel, I’m not a kernel dev, so I can’t say for sure, but perhaps the kernel SPI driver is updating the muxes and that’s why they differ.

What does OE4T stand for? We usually refer to upstream U-Boot as Denx U-Boot, and downstream as L4T. So I don’t know what version you are referring to when you say OE4T.

I’ve found my Winbond SPI test board, so I may try to connect it to my Nano and see if I can access it with L4T U-Boot if I get some time next week.

Tom

@TWarren

That is what I was assuming about cboot setting them up. You might be right about the kernel making those changes itself.

OE4T is the Open Embedded For Tegra project. We were able to take a few of their patches for the 5.10 Terga Kernel to get our HID device working with USB3. We were hoping that maybe some of the other changes that were made would help us. As far as I can tell it seems that they are on par with the upstream Denx U-Boot. I can try both.