Low throughput on SPI-to-CAN (TCAN4550) under JetPack 6.1 (Linux Kernel 5.15)

Hi everyone,

We are currently facing a performance bottleneck with an SPI-to-CAN FD controller (TCAN4550) on our Jetson platform. The achieved CAN throughput is capped at around 1500 frames per second (fps), which is significantly lower than expected.

After narrowing down the root cause, we discovered that this issue appears to be related to the SPI-to-CAN driver implementation/subsystem in the Linux 5.x kernels. On our other non-Jetson boards, we successfully resolved this exact throughput issue simply by upgrading the kernel to Linux 6.x.

However, for our Jetson deployment, we are running JetPack 6.2 (which is based on Ubuntu 22.04 and Linux Kernel 5.15). Since we cannot easily upgrade the entire Jetson kernel to mainline 6.x due to JetPack dependencies, we are looking for a way to fix or backport the solution to our current environment.

Has anyone encountered this SPI-to-CAN limitation on Jetson, or does anyone have experience backporting the relevant tcan4x5x / SPI framework patches from Kernel 6.x to Kernel 5.15?

Any guidance, patches, or workarounds would be greatly appreciated!

Thanks in advance!

Hi yihang.li,

Have you tried using internal mttcan instead?

Do you mean the issue is caused from the SPI-to-CAN driver or SPI-master driver?

You can also wait for the upcoming Jetpack 7.2, which is built with K6.8 and it supports for Orin series.

Thanks for the insights.

Exactly, we had no issues at all when using the native mttcan , but unfortunately, the number of available mttcan interfaces on our hardware simply doesn’t meet our requirements. That’s the only reason we had to add the external TCAN4550 via SPI.

Right now, we highly suspect the bottleneck lies within the spi_master. From what we’ve observed:

  • In Linux 5: It seems an interrupt is triggered every single time a single CAN message is sent.
  • In Linux 6: It appears that multiple CAN messages can be batched and transmitted within a single interrupt window.

This behavior in Linux 5 is almost certainly the culprit behind our CAN throughput failing to meet the target specification.

Moving to Jetpack 7.2 (which will likely bring further kernel-level optimizations) is definitely on our roadmap for the future, but we desperately need a solution that works on Jetpack 6.2 right now. Our next product relies heavily on the TCAN4550, and its launch window is just around the corner. Waiting for Jetpack 7.2 is simply not an option for our timeline.

That’s why we are desperately looking for a way to resolve this or backport the fix within our current Linux 5 environment. Any advice on how to achieve this on Linux 5 would be a lifesaver.

Could you check if the patch from the following thread helps for your issue?
Jetson orin nano SPI Speed not changing - #9 by KevinFFF

can you share your DTS overlay for the TCAN4550 we have been having troubles getting the can device to come up.

Thank You in advance
– George

The previous patch I shared is for the CS issue in SPI driver of JP6.x.

We don’t have custom TCAN4550 module and device tree configuration to share.
Please also request your vendor for related resource.

Hi,KevinFFF
Apologies for the delay in getting back to you—I’ve been away on a long-term leave.

I’ve tried the suggestions provided earlier, but unfortunately, they didn’t yield the expected results. However, I did manage to find another optimization point: by
SPI TX Time Variability - #8 by KevinFFF, I was able to increase the TCAN throughput from 1,500 fps to 2,000 fps.

While this is an improvement, it is still far from our target of 3,500 fps.

Any further insights would be greatly appreciated

Have you also tried to increase the SPI frequency?
What’s the SPI frequency in your case currently?

Regarding the SPI settings, we are currently using the 18MHz frequency as specified in the TCAN4550 datasheet. We have attempted to increase this frequency, but it prevents the CAN interface from initializing successfully

here is our current device tree setup for the TCAN4550 interface:

		spi@3210000{
			compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
			reg = <0x0 0x03210000 0x0 0x1000>;
			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
			#address-cells = <1>;
			#size-cells = <0>;
			clocks = <&bpmp TEGRA234_CLK_SPI1>;
			assigned-clocks = <&bpmp TEGRA234_CLK_SPI1>;
			assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
			clock-names = "spi";
			iommus = <&smmu_niso0 TEGRA234_SID_GPCDMA>;
			resets = <&bpmp TEGRA234_RESET_SPI1>;
			reset-names = "spi";
			dmas = <&gpcdma 15>, <&gpcdma 15>;
			dma-names = "rx", "tx";
			dma-coherent;
			status = "okay";
			prod-settings {
				#prod-cells = <4>;
				prod {
					prod = <
						0 0x00000194 0x80000000 0x00000000>;            //spi_misc_0
				};
			};
			spi@0 {
				compatible = "ti,tcan4x5x";
				reg = <0x0>;
				#address-cells = <1>;
				#size-cells = <1>;
				spi-max-frequency = <18000000>;
				bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>;
				interrupt-parent = <&gpio>;
				clocks = <&can_clock>;
				interrupts = <TEGRA234_MAIN_GPIO(Q, 6) IRQ_TYPE_LEVEL_LOW>;
				//device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
				//device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
				reset-gpios = <&gpio TEGRA234_MAIN_GPIO(A, 7) GPIO_ACTIVE_HIGH>;
				nvidia,enable-hw-based-cs;
				controller-data {
					nvidia,enable-hw-based-cs;
					nvidia,rx-clk-tap-delay = <0x10>;
					nvidia,tx-clk-tap-delay = <0x0>;
				};
		};

The issue likely stems from the custom SPI-to-CAN driver.
Could you try porting it from K6.x to K5.15?

Orin NX/Nano should be supported with the latest Jetpack 7.2(r39.2) which includes Linux K6.8.
You can also verify if it could meet your requirement.

Thanks for all the help so far. I have some good news: after configuring the TCAN4550 FIFO, I’ve managed to push the throughput up to 3,200 fps, which is just enough to meet our minimum requirements. I plan to verify this on Jetpack 7.2 later, which would be the ideal long-term solution. However, since the performance is now acceptable for our immediate needs, I’ll be shifting my focus to other adaptation tasks for the time being, so this verification will be lower priority for me at the moment. I’ll definitely circle back to this once I have more bandwidth or if I encounter further bottlenecks. Thanks again for your support!

Thanks for your update and good to hear that you have managed it by configuring TCAN4550 FIFO.