MCP2518FD not working with JetPack 6.0 GA

Dear Nvidia Team

We flashed on our Orin NX custom carrier board JetPack 6.0 GA. Now we face an issue with the SPI-CAN Controller MCP2518FD. With older JetPack Versions, everything was working.
The controller is connected to the SPI0 interface of the Orin NX. We changed the device tree according to the new Documentation:

cat kernel/kernel-jammy-src_5.15/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/can/microchip,mcp251xfd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title:
  Microchip MCP2517FD and MCP2518FD stand-alone CAN controller device tree
  bindings

maintainers:
  - Marc Kleine-Budde <mkl@pengutronix.de>

properties:
  compatible:
    oneOf:
      - const: microchip,mcp2517fd
        description: for MCP2517FD
      - const: microchip,mcp2518fd
        description: for MCP2518FD
      - const: microchip,mcp251xfd
        description: to autodetect chip variant

  reg:
    maxItems: 1

  interrupts:
    maxItems: 1

  clocks:
    maxItems: 1

  vdd-supply:
    description: Regulator that powers the CAN controller.

  xceiver-supply:
    description: Regulator that powers the CAN transceiver.

  microchip,rx-int-gpios:
    description:
      GPIO phandle of GPIO connected to to INT1 pin of the MCP251XFD, which
      signals a pending RX interrupt.
    maxItems: 1

  spi-max-frequency:
    description:
      Must be half or less of "clocks" frequency.
    maximum: 20000000

required:
  - compatible
  - reg
  - interrupts
  - clocks

additionalProperties: false

examples:
  - |
    #include <dt-bindings/gpio/gpio.h>
    #include <dt-bindings/interrupt-controller/irq.h>

    spi0 {
        #address-cells = <1>;
        #size-cells = <0>;

        can@0 {
            compatible = "microchip,mcp251xfd";
            reg = <0>;
            clocks = <&can0_osc>;
            pinctrl-names = "default";
            pinctrl-0 = <&can0_pins>;
            spi-max-frequency = <20000000>;
            interrupts-extended = <&gpio 13 IRQ_TYPE_LEVEL_LOW>;
            microchip,rx-int-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
            vdd-supply = <&reg5v0>;
            xceiver-supply = <&reg5v0>;
        };
    };

We see in the log files, that the controller is successfully initialized:

[ 10.690021] mcp251xfd spi0.0 can1: MCP2518FD rev0.0 (-RX_INT -MAB_NO_WARN +CRC_REG +CRC_RX +CRC_TX +ECC -HD c:40.00MHz m:20.00MHz r:17.00MHz e:0.00MHz) successfully initialized.

After we activate the interface with:

ip link set can1 type can bitrate 1000000 restart-ms 1000

Receiving data with the interface works, however we are not able to send any messages. We tested it with cansend.
Any idea what could go wrong?
Let us know if you need further information.
Thank you.

Hi sevm89,

Please share the full dmesg for further check.

Do you mean that you can receive the CAN data but you can’t send CAN data?

Please also share the result of sudo ip -d -s link show can1 on your board.

Hi KevinFFF

Here is the full dmesg:
dmesg.txt (63.7 KB)

Yes we can receive the CAN data on this interface, but we are not able to send any CAN data.

ip -d -s link show can1
9: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 1000
bitrate 1000000 sample-point 0.750
tq 25 prop-seg 14 phase-seg1 15 phase-seg2 10 sjw 1
mcp251xfd: tseg1 2…256 tseg2 1…128 sjw 1…128 brp 1…256 brp-inc 1
mcp251xfd: dtseg1 1…32 dtseg2 1…16 dsjw 1…16 dbrp 1…256 dbrp-inc 1
clock 40000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 parentbus spi parentdev spi0.0
RX: bytes packets errors dropped missed mcast
8000 1000 0 0 0 0
TX: bytes packets errors dropped carrier collsns
0 0 0 0 0 0

Thank you.

I can’t find the errors in your dmesg and also the result of can interface.

Is there any errors when you run cangen can1?
You can also measure the waveform when you send CAN packet.

Hi KevinFFF

We get the following error:

$ cangen can1
write: No buffer space available

Probably because nothing can be sent.

When we send packages, we do not see any waveform on the CAN bus. When we send data from another CAN device, we see the CAN signals on the CAN bus.

Can you share the steps how you reproduce this issue?

Do you mean the issue only happen on JP6.0GA? not with JP5.1.3?
If so, have you checked if there’s difference in the MCP2518FD driver?

In addition, what’s your CAN device connected?

We have a custom AGX Orin system connected to the CAN bus. Receiving on the Orin NX works:

ORIN NX:    # candump can1
AGX ORIN:   # cangen can0

We see packages arriving.

Sending from the ORIN NX does not work:

AGX ORIN:   # candump can0
ORIN NX:    # cangen can0

No packages arrive.

When we use the MTTCAN from the ORIN NX system, we can receive and send data from the AGX ORIN system.

With JetPack 5.1.2, we had everything working with the MCP2518FD device.
We will have a look at the changes in the driver.

Thank you.

May I also know the block diagram of your connection?
Do you use CAN transceiver in your setup?

For AGX Orin, maybe you can refer to the following link for the verification.
Loopback test for 2 CAN interfaces

Yes we use CAN transceivers in our setup.
Here is the block diagramm:

For AGX Orin, we have everything working also with JP6.0 GA.
We tried the loopback test on the Orin NX and it does also not work.

There are many changes between the JP5.1.2 driver and the one in JP6.0. How can we further debug this? Should we contact the MCP2518FD manufacturer?
Thank you.

From your result, it seems the issue is specific to MCP2518FD driver in JP6.0GA (can1).
(since mttcan(can0) could work as expected)
Please contact your vendor to check if there’s any patch missed for JP6.0GA(K5.15).

According to the manufacturer, there should not be changes between 5.10 and 5.15 causing this behavior.
Could it be an issue with patches for the SPI Bus that were applied to the kernel 5.10 but not 5.15, like mentioned in the following topic?

We don’t have this module to verify it locally with JP6.0GA.
If you have the concern about SPI driver, you can also port the driver from K5.10 to your current K5.15 to verify.

Hi KevinFFF

We ported the spi-tegra114 driver from K5.10 to K5.15 and now everything works as expected. Did you already check internally why there are patches missing for the K5.15 as stated in your last response here:

Thank you.

2 Likes

It sounds good.

We are still checking if there’s missing patch in spi-tegra114 driver for JP6.0GA.

Dear KevinFFF

We are also trying to use a newer Kernel (6.6.29) for the same Orin NX platform and face again the same issue with the SPI-to-CAN Controller. Sending from the CAN Interface does not work while receiving data works. As porting the SPI driver from Kernel 5.10 to Kernel 6.6.29 is a big effort, we hope you can come up with an easier solution.
Thank you.

Hi KevinFFF

Do you have any update on this matter?
Thank you.

Hi sevm89,

Sorry that we are busy on another task currently so that it may take more time to get check this issue in details.
I’ve roughly compared the driver in K5.10 and K5.10. It indeed has several differences.

Have you tried to just use spi-tegra114 driver from K5.10 to your current kernel?
Or please help to provide your current driver for further check.

Just using the spi-tegra114 driver from K5.10 for K6.6.29 does not work, we get compilation errors:

drivers/spi/spi-tegra114.c: In function ‘tegra_spi_setup_transfer_one’:
drivers/spi/spi-tegra114.c:1126:45: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1126 |                         gpio_set_value(spi->cs_gpio, gval);
      |                                             ^~~~~~~
      |                                             cs_gpiod
drivers/spi/spi-tegra114.c: In function ‘tegra_spi_cleanup’:
drivers/spi/spi-tegra114.c:1246:32: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1246 |                 gpio_free(spi->cs_gpio);
      |                                ^~~~~~~
      |                                cs_gpiod
drivers/spi/spi-tegra114.c: In function ‘tegra_spi_setup’:
drivers/spi/spi-tegra114.c:1279:26: error: ‘struct spi_controller’ has no member named ‘cs_gpios’; did you mean ‘cs_gpiods’?
 1279 |         if (spi->master->cs_gpios && gpio_is_valid(spi->cs_gpio)) {
      |                          ^~~~~~~~
      |                          cs_gpiods
drivers/spi/spi-tegra114.c:1279:57: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1279 |         if (spi->master->cs_gpios && gpio_is_valid(spi->cs_gpio)) {
      |                                                         ^~~~~~~
      |                                                         cs_gpiod
drivers/spi/spi-tegra114.c:1286:53: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1286 |                         ret = gpio_request_one(spi->cs_gpio, gpio_flag,
      |                                                     ^~~~~~~
      |                                                     cs_gpiod
drivers/spi/spi-tegra114.c:1298:45: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1298 |                         gpio_set_value(spi->cs_gpio, val);
      |                                             ^~~~~~~
      |                                             cs_gpiod
drivers/spi/spi-tegra114.c: In function ‘tegra_spi_transfer_one_message’:
drivers/spi/spi-tegra114.c:1505:53: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1505 |                                 gpio_set_value(spi->cs_gpio, gval);
      |                                                     ^~~~~~~
      |                                                     cs_gpiod
drivers/spi/spi-tegra114.c:1515:61: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1515 |                                         gpio_set_value(spi->cs_gpio, gval);
      |                                                             ^~~~~~~
      |                                                             cs_gpiod
drivers/spi/spi-tegra114.c:1524:53: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1524 |                                 gpio_set_value(spi->cs_gpio, gval);
      |                                                     ^~~~~~~
      |                                                     cs_gpiod
drivers/spi/spi-tegra114.c:1535:53: error: ‘struct spi_device’ has no member named ‘cs_gpio’; did you mean ‘cs_gpiod’?
 1535 |                                 gpio_set_value(spi->cs_gpio, !gval);
      |                                                     ^~~~~~~
      |                                                     cs_gpiod

Here is the current driver from K6.6.29:
spi-tegra114.txt (41.5 KB)

Hi KevinFFF

We were now able to adapt the driver and so far it seems to work, even tough we just commented out the parts that gave the compilation errors. Here the current working driver file:
spi-tegra114.txt (57.5 KB)

As this seams a bit messy, we still would like to receive a working driver by NVidia with the necessary patches. Please keep us updated.
Thank you.

3 Likes

okay, we are still checking the SPI driver issue in JP6.0GA with internal.