Spidev crashes when SPI_IOC_MESSAGE(N), N > 1

We have custom board with an ADIS165000 attached to SPI2 or spi@3230000 CS:0

Eventually, I would like to take advantage of a burst feature of this chip wherein I can copy all the IMU data from the chip with a single long read transaction but I’m having trouble capturing more than a single transaction at a time. To reduce this problem down in this post, I’m focusing on two consecutive transactions.

This topic is similar to Jetpack 5.0.2 crashes when it tries to transfer SPI message with SPI_IOC_MESSAGE(N), N > 1

For reference:

$ cat /etc/nv_tegra_release
# R35 (release), REVISION: 1.0, GCID: 31346300, BOARD: t186ref, EABI: aarch64, DATE: Thu Aug 25 18:41:45 UTC 2022

Here is my SPI DTSI snippet:

#include <dt-bindings/gpio/tegra-gpio.h>

/ {
  spi@3230000{ /* SPI3 in 40 pin conn */
    status = "okay";
    spi@0 { /* chip select 0 */
      compatible = "tegra-spidev";
      reg = <0x0>;
      //spi-max-frequency = <50000000>;
      spi-max-frequency = <25000000>; /* 25MHz */
      controller-data {
        nvidia,enable-hw-based-cs;
        nvidia,rx-clk-tap-delay = <0x10>;
        nvidia,tx-clk-tap-delay = <0x0>;
      };
    };

    spi@1 { /* chips select 1 */
      compatible = "tegra-spidev";
      reg = <0x1>;
      spi-max-frequency = <50000000>;
      controller-data {
        nvidia,enable-hw-based-cs;
        nvidia,rx-clk-tap-delay = <0x10>;
        nvidia,tx-clk-tap-delay = <0x0>;
      };
    };
  };
};

I’ve verified that I can read and write to the device a single 16-bit word at a time:

Here is a snippet of the ‘read_register’ function where the read schema is the following

  1. Transfer one 16-bit transaction where the TX buffer has the requested address in the high byte and 0x00 in the low byte, ignore the read.
  2. Transfer one 16-bit transaction where the TX buffer doesn’t matter but the read buffer will have the 16-bit register value

VERSION 1

  // Send one 16-bit value to the IMU through the 'tx_buf'
  // Read one 16-bit value from the IMU through the 'rx_buf'
  // Between the two transactions de-assert 'cs'

  // Configure the SPI Transfer
  uint16_t spi_addr = (addr << 8) & 0xFF00;
  uint16_t tx_buf_msg0[8] = {spi_addr};
  uint16_t rx_buf_msg0[8] = {0x0000};

  uint16_t tx_buf_msg1[8] = {spi_addr};
  uint16_t rx_buf_msg1[8] = {0x0000};

  tx_buf_msg0[0] = spi_addr;
  tx_buf_msg0[1] = spi_addr;

  printf("TX Buffer: 0x%04X\n", tx_buf_msg0[0]);

  m_spi_transfer[0].speed_hz = SPI_FREQ; // 1MHz
  m_spi_transfer[0].cs_change = 1;       // Change at the end of the transaction
  m_spi_transfer[0].bits_per_word = 16;  // 16-bit word
  m_spi_transfer[0].len = 2;             // 1 16-bit word
  m_spi_transfer[0].tx_buf = (unsigned long)tx_buf_msg0; // Attach TX Buffer
  m_spi_transfer[0].rx_buf = (unsigned long)rx_buf_msg0; // Attach RX Buffer

  rv = ioctl(spidev_fd, SPI_IOC_MESSAGE(1),
             &m_spi_transfer[0]); // Send 1 messeges
  if (rv < 0)
    printf("Error 0 from IOCTL When Reading Register: %02X: RV: %d\n", addr,
           rv);

  m_spi_transfer[1].speed_hz = SPI_FREQ; // 1MHz
  m_spi_transfer[1].cs_change = 1;       // Change at the end of the transaction
  m_spi_transfer[1].bits_per_word = 16;  // 16-bit word
  m_spi_transfer[1].len = 2;             // 1 16-bit word
  m_spi_transfer[1].tx_buf = (unsigned long)tx_buf_msg1; // Attach TX Buffer
  m_spi_transfer[1].rx_buf = (unsigned long)rx_buf_msg1; // Attach RX Buffer

  rv = ioctl(spidev_fd, SPI_IOC_MESSAGE(1),
             &m_spi_transfer[1]); // Send 1 messeges
  if (rv < 0)
    printf("Error 1 from IOCTL When Reading Register: %02X: RV: %d\n", addr,
           rv);

  printf("Recevied Data 0: 0x%04X\n", rx_buf_msg0[0]);
  printf("Recevied Data 1: 0x%04X\n", rx_buf_msg1[0]);

  value = rx_buf_msg1[0];
  return rv;

This works with the expected result

TX Buffer: 0x7200
Recevied Data 0: 0x0000
Recevied Data 1: 0x4074

Now when I change it so that there is two words within a transaction:

VERSION 2

  // 2 x 16-bit transactions

  // Configure the SPI Transfer
  uint16_t spi_addr = (addr << 8) & 0xFF00;
  uint16_t tx_buf_msg[8] = {spi_addr};
  uint16_t rx_buf_msg[8] = {0x0000};

  memset(tx_buf_msg, 0, sizeof(tx_buf_msg));
  tx_buf_msg[0] = spi_addr;
  tx_buf_msg[1] = spi_addr;

  printf("First 2 Words of TX Buffer: 0x%04X 0x%04X\n", tx_buf_msg[0],
         tx_buf_msg[1]);

  m_spi_transfer[0].speed_hz = SPI_FREQ; // 1MHz
  m_spi_transfer[0].cs_change = 1;       // De-assert CS between the two words
  m_spi_transfer[0].bits_per_word = 16;  // 16-bit word
  m_spi_transfer[0].len = 4;             // 1 16-bit word
  m_spi_transfer[0].tx_buf = (unsigned long)tx_buf_msg; // Attach TX Buffer
  m_spi_transfer[0].rx_buf = (unsigned long)rx_buf_msg; // Attach RX Buffer

  rv = ioctl(spidev_fd, SPI_IOC_MESSAGE(2), &m_spi_transfer[0]);
  if (rv < 0)
    printf("Error 1 from IOCTL When Reading Register: %02X: RV: %d\n", addr,
           rv);

  printf("Recevied Data: 0x%04X, 0x%04X\n", rx_buf_msg[0], rx_buf_msg[1]);

  value = rx_buf_msg[1];
  return rv;

The result is not correct:

First 2 Words of TX Buffer: 0x7200 0x7200
Recevied Data: 0x0000, 0x0000

Stuff I’ve tried

I’ve enabled tracing on the spi subsystem using the following commands:

echo 1 > /sys/kernel/debug/tracing/tracing_on
echo 30720 > /sys/kernel/debug/tracing/buffer_size_kb
echo 1 > /sys/kernel/debug/tracing/events/spi/enable
echo > /sys/kernel/debug/tracing/trace
cat /sys/kernel/debug/tracing/trace_pipe

For VERSION 1

 adis-imu-contro-5443    [000] d..1  3795.675809: spi_message_submit: spi2.0 00000000e6ed7e8a
 adis-imu-contro-5443    [001] ....  3795.680923: spi_controller_busy: spi2
 adis-imu-contro-5443    [001] ....  3795.680972: spi_message_start: spi2.0 00000000e6ed7e8a
            spi2-361     [001] ....  3795.681341: spi_controller_idle: spi2
 adis-imu-contro-5443    [001] ....  3795.681426: spi_message_done: spi2.0 00000000e6ed7e8a len=2/2
 adis-imu-contro-5443    [001] d..1  3795.681521: spi_message_submit: spi2.0 00000000e6ed7e8a
 adis-imu-contro-5443    [001] ....  3795.682144: spi_controller_busy: spi2
 adis-imu-contro-5443    [001] ....  3795.682149: spi_message_start: spi2.0 00000000e6ed7e8a
            spi2-361     [001] ....  3795.682346: spi_controller_idle: spi2
 adis-imu-contro-5443    [001] ....  3795.682376: spi_message_done: spi2.0 00000000e6ed7e8a len=2/2

For VERSION 2

 adis-imu-contro-5299    [001] d..1  3492.761065: spi_message_submit: spi2.0 00000000652afe5f
 adis-imu-contro-5299    [001] ....  3492.761444: spi_controller_busy: spi2
 adis-imu-contro-5299    [001] ....  3492.762044: spi_message_start: spi2.0 00000000652afe5f
            spi2-361     [001] ....  3492.762345: spi_controller_idle: spi2
 adis-imu-contro-5299    [001] ....  3492.762524: spi_message_done: spi2.0 00000000652afe5f len=4/4

I do notice that when I switch between VERSION 2 to VERSION 1 I need to run that application a few times before the application usually behaves, it seems there is some data in a buffer that hasn’t been cleared out.

Applying Patch to spi-tegra114.c

In the other post I see that there was a request to apply a patch to the driver. I did this and was able to get some data but when I added more print messages to identify where the register dumps were occurring, The kernel became unstable and panicked.

Here is the patch I applied to spi-tegra114.c:

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index d50705047a02..150cdd62f0ae 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -267,6 +267,7 @@ struct tegra_spi_data {
 static int tegra_spi_runtime_suspend(struct device *dev);
 static int tegra_spi_runtime_resume(struct device *dev);
 static int tegra_spi_status_poll(struct tegra_spi_data *tspi);
+static void tegra_spi_dump_regs(struct tegra_spi_data *tspi);
 
 static inline u32 tegra_spi_readl(struct tegra_spi_data *tspi,
 		unsigned long reg)
@@ -725,6 +726,8 @@ static int tegra_spi_start_dma_based_transfer(
 	tspi->dma_control_reg = val;
 
 	val |= SPI_DMA_EN;
+	dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
+	tegra_spi_dump_regs(tspi);
 	tegra_spi_writel(tspi, val, SPI_DMA_CTL);
 	return ret;
 }
@@ -763,6 +766,8 @@ static int tegra_spi_start_cpu_based_transfer(
 
 	val = tspi->command1_reg;
 	val |= SPI_PIO;
+	dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
+	tegra_spi_dump_regs(tspi);
 	tegra_spi_writel(tspi, val, SPI_COMMAND1);
 	return 0;
 }
@@ -1354,14 +1359,14 @@ static int tegra_spi_setup(struct spi_device *spi)
 
 static void tegra_spi_dump_regs(struct tegra_spi_data *tspi)
 {
-	dev_dbg(tspi->dev, "============ SPI REGISTER DUMP ============\n");
-	dev_dbg(tspi->dev, "Command1:    0x%08x | Command2:    0x%08x\n",
+	dev_err(tspi->dev, "============ SPI REGISTER DUMP ============\n");
+	dev_err(tspi->dev, "Command1:    0x%08x | Command2:    0x%08x\n",
 		tegra_spi_readl(tspi, SPI_COMMAND1),
 		tegra_spi_readl(tspi, SPI_COMMAND2));
-	dev_dbg(tspi->dev, "DMA_CTL:     0x%08x | DMA_BLK:     0x%08x\n",
+	dev_err(tspi->dev, "DMA_CTL:     0x%08x | DMA_BLK:     0x%08x\n",
 		tegra_spi_readl(tspi, SPI_DMA_CTL),
 		tegra_spi_readl(tspi, SPI_DMA_BLK));
-	dev_dbg(tspi->dev, "TRANS_STAT:  0x%08x | FIFO_STATUS: 0x%08x\n",
+	dev_err(tspi->dev, "TRANS_STAT:  0x%08x | FIFO_STATUS: 0x%08x\n",
 		tegra_spi_readl(tspi, SPI_TRANS_STATUS),
 		tegra_spi_readl(tspi, SPI_FIFO_STATUS));
 }
@@ -1467,6 +1472,7 @@ static int tegra_spi_transfer_one_message(struct spi_controller *ctrl,
 			    (tspi->cur_direction & DATA_DIR_RX))
 				dmaengine_terminate_all(tspi->rx_dma_chan);
 			ret = -EIO;
+			dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
 			tegra_spi_dump_regs(tspi);
 			/* Abort transfer by resetting pio/dma bit */
 			if (!tspi->is_curr_dma_xfer) {
@@ -1490,6 +1496,7 @@ static int tegra_spi_transfer_one_message(struct spi_controller *ctrl,
 		if (tspi->tx_status ||  tspi->rx_status) {
 			dev_err(tspi->dev, "Error in Transfer\n");
 			ret = -EIO;
+			dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
 			tegra_spi_dump_regs(tspi);
 			goto complete_xfer;
 		}
@@ -1563,6 +1570,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi)
 			tspi->status_reg);
 		dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n",
 			tspi->command1_reg, tspi->dma_control_reg);
+		dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
 		tegra_spi_dump_regs(tspi);
 		complete(&tspi->xfer_completion);
 		spin_unlock_irqrestore(&tspi->lock, flags);
@@ -1584,6 +1592,8 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi)
 
 	if (tspi->cur_pos == t->len) {
 		complete(&tspi->xfer_completion);
+		dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
+		tegra_spi_dump_regs(tspi);
 		goto exit;
 	}
 
@@ -1639,6 +1649,7 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi)
 			tspi->status_reg);
 		dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n",
 			tspi->command1_reg, tspi->dma_control_reg);
+		dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
 		tegra_spi_dump_regs(tspi);
 		complete(&tspi->xfer_completion);
 		spin_unlock_irqrestore(&tspi->lock, flags);
@@ -1660,6 +1671,8 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi)
 
 	if (tspi->cur_pos == t->len) {
 		complete(&tspi->xfer_completion);
+		dev_err(tspi->dev, "%s: %d\n", __func__, __LINE__);
+		tegra_spi_dump_regs(tspi);
 		goto exit;
 	}

Here is a capture of the kernel panic

[  249.643076] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.643274] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.643451] spi-tegra114 3230000.spi: Command1:    0x70e0980f | Command2:    0x00000015
[  249.643741] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.643935] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0000 | FIFO_STATUS: 0x00400005
[  249.644228] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  249.644352] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.644508] spi-tegra114 3230000.spi: Command1:    0x40c08000 | Command2:    0x00000015
[  249.644715] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.644899] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.652095] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.652379] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.652784] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.653164] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.659675] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.667692] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  249.673452] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.681239] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.689288] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.697337] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.715965] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.716193] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.719983] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.728308] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.736076] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.744414] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  249.750119] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.757630] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.765680] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.773743] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.782944] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.789270] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.796802] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.804633] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.813546] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.820978] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  249.826754] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.834283] spi-tegra114 3230000.spi: Command1:    0x40c08000 | Command2:    0x00000015
[  249.842332] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.850639] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.859684] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.865738] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.873454] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.881257] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.889306] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.897594] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  249.898557] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.903400] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.903409] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.903415] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.903421] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.942321] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.951044] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  249.957943] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.966051] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  249.974952] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  249.979966] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  249.987496] spi-tegra114 3230000.spi: Command1:    0x40c08000 | Command2:    0x00000015
[  249.991288] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  249.995801] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  249.995809] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  250.018940] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  250.026502] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  250.034797] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  250.042590] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  250.050928] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  250.050973] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  250.056958] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  250.056967] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  250.056974] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  250.056980] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  250.095593] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  250.103427] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  250.111462] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  250.119268] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  250.127573] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  250.133525] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  250.305282] spi-tegra114 3230000.spi: Command1:    0xdead2003 | Command2:    0xdead2003
[  250.469948] spi-tegra114 3230000.spi: DMA_CTL:     0xdead2003 | DMA_BLK:     0xdead2003
[  250.634638] spi-tegra114 3230000.spi: TRANS_STAT:  0xdead2003 | FIFO_STATUS: 0xdead2003
[  250.635012] CPU:0, Error:cbb-noc@0x2300000,irq=15
[  250.635105] **************************************
[  250.635200] CPU:0, Error:cbb-noc
[  250.635266]  Error Logger            : 0
[  250.635348]  ErrLog0                 : 0x80030000
[  250.635421]    Transaction Type      : RD  - Read, Incrementing
[  250.635525]    Error Code            : SLV
[  250.635591]    Error Source          : Target
[  250.635661]    Error Description     : Target error detected by CBB slave
[  250.635803]    AXI2APB_4 bridge error: SFIFONE - Status FIFO Not Empty interrupt
[  250.635948]    AXI2APB_4 bridge error: TIM - Timer(Timeout) interrupt
[  250.636073]    AXI2APB_5 bridge error: RDFIFOF - Read Response FIFO Full interrupt
[  250.636220]    Packet header Lock    : 0
[  250.636291]    Packet header Len1    : 3
[  250.636380]    NOC protocol version  : version >= 2.7
[  250.636476]  ErrLog1                 : 0x320028
[  250.636687]  ErrLog2                 : 0x0
[  250.636878]    RouteId               : 0x320028
[  250.637129]    InitFlow              : ccroc_p2ps/I/ccroc_p2ps
[  250.638047]    Targflow              : axis_satellite_grout/T/axis_satellite_grout
[  250.644610]    TargSubRange          : 0
[  250.647847]    SeqId                 : 0
[  250.650477]  ErrLog3                 : 0x3230000
[  250.654146]  ErrLog4                 : 0x0
[  250.656947]    Address accessed      : 0x3230000
[  250.661163]  ErrLog5                 : 0xa09f851
[  250.664384]    Non-Modify            : 0x1
[  250.667796]    AXI ID                : 0x14
[  250.670859]    Master ID             : CCPLEX
[  250.674271]    Security Group(GRPSEC): 0x7e
[  250.678214]    Cache                 : 0x1 -- Bufferable
[  250.682686]    Protection            : 0x2 -- Unprivileged, Non-Secure, Data Access
[  250.689496]    FALCONSEC             : 0x0
[  250.692389]    Virtual Queuing Channel(VQC): 0x0
[  250.697285]  **************************************
[  250.702332] kernel BUG at drivers/soc/tegra/cbb/tegra194-cbb.c:1896!
[  250.708662] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[  250.714000] Modules linked in: fuse aes_ce_ccm rtl8xxxu rtl8192cu rtl_usb rtl8192c_common rtlwifi mac80211 snd_soc_tegra186_asrc snd_soc_tegra210_ope cfg80211 snd_soc_tegra186_dspk snd_soc_tegra186_arad snd_soc_tegra210_mvc snd_soc_tegra210_afc snd_soc_tegra210_iqc snd_soc_tegra210_dmic xt_conntrack ofpart cmdlinepart snd_soc_tegra210_admaif qspi_mtd xt_MASQUERADE snd_soc_tegra210_amx snd_soc_tegra210_adx nf_conntrack_netlink nfnetlink snd_soc_tegra210_mixer snd_soc_tegra_pcm snd_soc_tegra210_i2s mtd xt_addrtype snd_soc_tegra210_sfc iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c br_netfilter lzo_rle lzo_compress zram overlay aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce sha2_ce sha256_arm64 sha1_ce realtek loop snd_soc_spdif_tx snd_soc_tegra210_adsp leds_gpio snd_hda_codec_hdmi snd_soc_tegra_machine_driver snd_soc_tegra_utils snd_hda_tegra snd_soc_simple_card_utils snd_hda_codec spidev ina3221 pwm_fan max77620_thermal nvadsp tegra_bpmp_thermal
[  250.714277]  tegra210_adma snd_soc_tegra210_ahub snd_hda_core userspace_alert nvgpu imx265 spi_tegra210_qspi imx265_fpga spi_tegra114 binfmt_misc nvmap ramoops reed_solomon ip_tables x_tables
[  250.818656] CPU: 0 PID: 346 Comm: irq/36-3230000. Tainted: G           OE     5.10.104-tegra #3
[  250.827833] Hardware name: Unknown NVIDIA Jetson Xavier NX Developer Kit/NVIDIA Jetson Xavier NX Developer Kit, BIOS 1.0-d7fb19b 08/10/2022
[  250.840181] pstate: 60400089 (nZCv daIf +PAN -UAO -TCO BTYPE=--)
[  250.846480] pc : tegra194_cbb_err_isr+0x190/0x1b0
[  250.851198] lr : tegra194_cbb_err_isr+0x114/0x1b0
[  250.855664] sp : ffff800010003b30
[  250.859334] x29: ffff800010003b30 x28: 0000000000000001
[  250.864847] x27: 0000000000000005 x26: ffffb4b8ed6e5d48
[  250.869927] x25: ffffb4b8ee135e18 x24: 0000000000000001
[  250.875439] x23: ffffb4b8eda07000 x22: ffffb4b8edf0eaa0
[  250.881208] x21: 000000000000000f x20: ffff23b7c0eecc80
[  250.886290] x19: ffffb4b8edf0eaa0 x18: 0000000000000010
[  250.891802] x17: 0000000000000000 x16: ffffb4b8ed177ea0
[  250.897397] x15: ffff23b7f1122270 x14: ffffffffffffffff
[  250.902910] x13: ffff800090003727 x12: ffff80001000372f
[  250.908422] x11: 0000000000000038 x10: 0101010101010101
[  250.913937] x9 : ffff800010003a40 x8 : 2a2a2a2a2a2a2a2a
[  250.919446] x7 : 2a2a2a2a2a2a2a09 x6 : c0000000ffffefff
[  250.924959] x5 : ffff23bb3fd9b958 x4 : ffffb4b8edd97968
[  250.930384] x3 : 0000000000000001 x2 : ffffb4b8ec0ff1d0
[  250.935465] x1 : ffff23b7f1121d00 x0 : 0000000100010101
[  250.940801] Call trace:
[  250.943256]  tegra194_cbb_err_isr+0x190/0x1b0
[  250.947562]  __handle_irq_event_percpu+0x68/0x2a0
[  250.952350]  handle_irq_event_percpu+0x40/0xa0
[  250.956812]  handle_irq_event+0x50/0xf0
[  250.960576]  handle_fasteoi_irq+0xc0/0x170
[  250.964356]  generic_handle_irq+0x40/0x60
[  250.968625]  __handle_domain_irq+0x70/0xd0
[  250.972838]  efi_header_end+0xb0/0xf0
[  250.976323]  el1_irq+0xd0/0x180
[  250.979056]  __do_softirq+0xb4/0x3e8
[  250.982977]  irq_exit+0xc0/0xe0
[  250.985950]  __handle_domain_irq+0x74/0xd0
[  250.989973]  efi_header_end+0xb0/0xf0
[  250.993648]  el1_irq+0xd0/0x180
[  250.996628]  _raw_spin_unlock_irqrestore+0x38/0x70
[  251.001183]  handle_cpu_based_xfer+0x88/0x2b0 [spi_tegra114]
[  251.007038]  tegra_spi_isr_thread+0x40/0x50 [spi_tegra114]
[  251.012117]  irq_thread_fn+0x34/0xa0
[  251.015704]  irq_thread+0x158/0x250
[  251.019379]  kthread+0x148/0x170
[  251.023049]  ret_from_fork+0x10/0x24
[  251.026386] Code: a9425bf5 a9446bf9 a8c77bfd d65f03c0 (d4210000)
[  251.032855] ---[ end trace 379708d6d2a7ce84 ]---
[  251.037139] Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt
[  251.044667] SMP: stopping secondary CPUs
[  251.048783] Kernel Offset: 0x34b8dbf40000 from 0xffff800010000000
[  251.055071] PHYS_OFFSET: 0xffffdc4940000000
[  251.058928] CPU features: 0x8240002,03802a30
[  251.063388] Memory Limit: none
[  251.066547] ---[ end Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt ]---

In my naive opinion it does seem like a critical function may be called twice:

[  250.050928] spi-tegra114 3230000.spi: handle_cpu_based_xfer: 1595
[  250.050973] spi-tegra114 3230000.spi: tegra_spi_start_cpu_based_transfer: 769
[  250.056958] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  250.056967] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  250.056974] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  250.056980] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005
[  250.095593] spi-tegra114 3230000.spi: ============ SPI REGISTER DUMP ============
[  250.103427] spi-tegra114 3230000.spi: Command1:    0x70c0980f | Command2:    0x00000015
[  250.111462] spi-tegra114 3230000.spi: DMA_CTL:     0x00000000 | DMA_BLK:     0x00000000
[  250.119268] spi-tegra114 3230000.spi: TRANS_STAT:  0x00ff0001 | FIFO_STATUS: 0x00400005

Thanks for any help,

Dave

Hi,
Could you try spidev_test and see if it works in loopback test?

Hi, I am also working on SPI between Jetson Xavier NX and ADIS16480.
I recommend you to use the hardware delay. Please have a look at low level document and find this part:

I still have a problem and asked it here:

Thanks to both of you for the help! I bit the bullet and soldered on some wires to the SPI pins and attached them to my logic analyzer.

re: @DaneLLL

I’ve built the ‘spi_test’ on my board and can see the following:

This is for a single transaction, which works as expected.

I’ve modified spi_test.c so that I can specify the number of SPI transfers and I got interesting results:

First I did not specify the ‘cs_change’ to 1 and saw that the chip select didn’t go low:

when I did specify that chip select should go low between transactions the ‘cs_change’ flag set to ‘1’ I did see the 'CS line de-assert, it was very short though but here is a capture:

Both of the transactions should have been the same but it looks like the controller only sent out 8-bits and then there was a kernel panic:


[ 1643.024569] spi-tegra114 3230000.spi: CpuXfer ERROR bit set 0x400005
[ 1643.024753] spi-tegra114 3230000.spi: CpuXfer 0x70e0980f:0x00000000
[ 1643.024919] spi-tegra114 3230000.spi: Error in Transfer
[ 1643.025079] spi_master spi2: failed to transfer one message from queue
[ 1703.855822] spi-tegra114 3230000.spi: CpuXfer ERROR bit set 0x400005
[ 1703.856013] spi-tegra114 3230000.spi: CpuXfer 0x70e0980f:0x00000000
[ 1703.856177] spi-tegra114 3230000.spi: Error in Transfer
[ 1703.913357] CPU:0, Error:bpmp-noc@0xd600000,irq=18
[ 1703.913495] **************************************
[ 1703.913632] CPU:0, Error:bpmp-noc
[ 1703.913716]  Error Logger            : 1
[ 1703.913800]  ErrLog0                 : 0x80030608
[ 1703.913904]    Transaction Type      : WR  - Write, Incrementing
[ 1703.914022]    Error Code            : TMO
[ 1703.914088]    Error Source          : Target NIU
[ 1703.914169]    Error Description     : Target time-out error
[ 1703.914271]    Packet header Lock    : 0
[ 1703.914344]    Packet header Len1    : 3
[ 1703.914414]    NOC protocol version  : version >= 2.7
[ 1703.914527]  ErrLog1                 : 0xba801
[ 1703.914594]  ErrLog2                 : 0x0
[ 1703.914650]    RouteId               : 0xba801
[ 1703.914716]    InitFlow              : cpu_p_i/I/0
[ 1703.914790]    Targflow              : cbb_t/T/0
[ 1703.914859]    TargSubRange          : 4
[ 1703.914924]    SeqId                 : 0
[ 1703.914987]  ErrLog3                 : 0x110008
[ 1703.915052]  ErrLog4                 : 0x0
[ 1703.915167]    Address accessed      : 0x20110008
[ 1703.915463]  ErrLog5                 : 0xcfa30
[ 1703.915698]    Master ID             : BPMP
[ 1703.915941]    Security Group(GRPSEC): 0x7d
[ 1703.917216]    Cache                 : 0x0 -- Device Non-Bufferable
[ 1703.922291]    Protection            : 0x0 -- Unprivileged, Secure, Data Access
[ 1703.928419]    FALCONSEC             : 0x0
[ 1703.931569]    Virtual Queuing Channel(VQC): 0x0
[ 1703.936552]  **************************************
[ 1703.938659] spi_master spi2: failed to transfer one message from queue
[ 1703.941606] CPU:0, Error:cbb-noc@0x2300000,irq=15
[ 1703.952134] **************************************
[ 1703.957038] CPU:0, Error:cbb-noc
[ 1703.960530]  Error Logger            : 0
[ 1703.963512]  ErrLog0                 : 0x80030008
[ 1703.967090]    Transaction Type      : WR  - Write, Incrementing
[ 1703.972691]    Error Code            : SLV
[ 1703.975672]    Error Source          : Target
[ 1703.979430]    Error Description     : Target error detected by CBB slave
[ 1703.985744]    AXI2APB_4 bridge error: SFIFONE - Status FIFO Not Empty interrupt
[ 1703.993436]    AXI2APB_4 bridge error: TIM - Timer(Timeout) interrupt
[ 1703.999911]    AXI2APB_5 bridge error: RDFIFOF - Read Response FIFO Full interrupt
[ 1704.007349]    Packet header Lock    : 0
[ 1704.010760]    Packet header Len1    : 3
[ 1704.014438]    NOC protocol version  : version >= 2.7
[ 1704.019682]  ErrLog1                 : 0x320013
[ 1704.022916]  ErrLog2                 : 0x0
[ 1704.025547]    RouteId               : 0x320013
[ 1704.028954]    InitFlow              : ccroc_p2ps/I/ccroc_p2ps
[ 1704.033767]    Targflow              : axis_satellite_grout/T/axis_satellite_grout
[ 1704.040155]    TargSubRange          : 0
[ 1704.043134]    SeqId                 : 0
[ 1704.046023]  ErrLog3                 : 0x3230000
[ 1704.049692]  ErrLog4                 : 0x0
[ 1704.052235]    Address accessed      : 0x3230000
[ 1704.056435]  ErrLog5                 : 0x489f851
[ 1704.059673]    Non-Modify            : 0x1
[ 1704.063341]    AXI ID                : 0x9
[ 1704.065884]    Master ID             : CCPLEX
[ 1704.069554]    Security Group(GRPSEC): 0x7e
[ 1704.073497]    Cache                 : 0x1 -- Bufferable
[ 1704.077697]    Protection            : 0x2 -- Unprivileged, Non-Secure, Data Access
[ 1704.084522]    FALCONSEC             : 0x0
[ 1704.087672]    Virtual Queuing Channel(VQC): 0x0
[ 1704.092312]  **************************************
[ 1704.097337] kernel BUG at drivers/soc/tegra/cbb/tegra194-cbb.c:1896!
[ 1704.103690] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[ 1704.109199] Modules linked in: fuse aes_ce_ccm rtl8xxxu rtl8192cu rtl_usb rtl8192c_common rtlwifi mac80211 cfg80211 snd_soc_tegra210_ope snd_soc_tegra186_asrc snd_soc_tegra186_dspk snd_soc_tegra210_iqc snd_soc_tegra186_arad snd_soc_tegra210_mvc snd_soc_tegra210_afc snd_soc_tegra210_dmic ofpart snd_soc_tegra210_amx snd_soc_tegra210_adx cmdlinepart snd_soc_tegra210_mixer qspi_mtd snd_soc_tegra210_i2s snd_soc_tegra210_admaif mtd snd_soc_tegra_pcm snd_soc_tegra210_sfc xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c br_netfilter aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce sha2_ce sha256_arm64 sha1_ce lzo_rle lzo_compress zram overlay snd_soc_spdif_tx realtek snd_soc_tegra210_adsp loop snd_soc_tegra_machine_driver leds_gpio snd_soc_tegra_utils spidev snd_soc_simple_card_utils max77620_thermal pwm_fan ina3221 tegra210_adma nvadsp snd_hda_codec_hdmi nvgpu snd_hda_tegra
[ 1704.109465]  snd_soc_tegra210_ahub snd_hda_codec tegra_bpmp_thermal userspace_alert snd_hda_core imx265 imx265_fpga spi_tegra210_qspi spi_tegra114 binfmt_misc nvmap ramoops reed_solomon ip_tables x_tables
[ 1704.213864] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G           OE     5.10.104-tegra #3
[ 1704.221987] Hardware name: Unknown NVIDIA Jetson Xavier NX Developer Kit/NVIDIA Jetson Xavier NX Developer Kit, BIOS 1.0-d7fb19b 08/10/2022
[ 1704.234589] pstate: 60400089 (nZCv daIf +PAN -UAO -TCO BTYPE=--)
[ 1704.240888] pc : tegra194_cbb_err_isr+0x190/0x1b0
[ 1704.245350] lr : tegra194_cbb_err_isr+0x114/0x1b0
[ 1704.250328] sp : ffff800010003b30
[ 1704.253484] x29: ffff800010003b30 x28: 0000000000000001
[ 1704.258997] x27: 0000000000000005 x26: ffffa5e81dac5d48
[ 1704.264509] x25: ffffa5e81e515e18 x24: 0000000000000001
[ 1704.270284] x23: ffffa5e81dde7000 x22: ffffa5e81e2eeaa0
[ 1704.275535] x21: 000000000000000f x20: ffff3cd000eece80
[ 1704.280959] x19: ffffa5e81e2eeaa0 x18: 0000000000000010
[ 1704.286732] x17: 0000000000000000 x16: 0000000000000000
[ 1704.291898] x15: ffffa5e81e162bf0 x14: ffffffffffffffff
[ 1704.297412] x13: ffff800090003727 x12: ffff800010003730
[ 1704.302924] x11: 0000000000000038 x10: 0101010101010101
[ 1704.308693] x9 : ffff800010003a40 x8 : 2a2a2a2a2a2a2a2a
[ 1704.314203] x7 : 2a2a2a2a2a2a2a09 x6 : c0000000ffffefff
[ 1704.319461] x5 : ffff3cd37fd9a958 x4 : ffffa5e81e177968
[ 1704.325142] x3 : 0000000000000001 x2 : ffffa5e81c4df1d0
[ 1704.330480] x1 : ffffa5e81e162680 x0 : 0000000000010101
[ 1704.335560] Call trace:
[ 1704.338276]  tegra194_cbb_err_isr+0x190/0x1b0
[ 1704.342562]  __handle_irq_event_percpu+0x68/0x2a0
[ 1704.347033]  handle_irq_event_percpu+0x40/0xa0
[ 1704.351570]  handle_irq_event+0x50/0xf0
[ 1704.355076]  handle_fasteoi_irq+0xc0/0x170
[ 1704.359101]  generic_handle_irq+0x40/0x60
[ 1704.363127]  __handle_domain_irq+0x70/0xd0
[ 1704.367583]  efi_header_end+0xb0/0xf0
[ 1704.370825]  el1_irq+0xd0/0x180
[ 1704.373830]  __do_softirq+0xb4/0x3e8
[ 1704.377735]  irq_exit+0xc0/0xe0
[ 1704.380708]  __handle_domain_irq+0x74/0xd0
[ 1704.384733]  efi_header_end+0xb0/0xf0
[ 1704.388150]  el1_irq+0xd0/0x180
[ 1704.391129]  cpuidle_enter_state+0xb8/0x410
[ 1704.395149]  cpuidle_enter+0x40/0x60
[ 1704.399081]  call_cpuidle+0x44/0x80
[ 1704.402588]  do_idle+0x208/0x270
[ 1704.405569]  cpu_startup_entry+0x2c/0x70
[ 1704.409682]  rest_init+0xdc/0xe8
[ 1704.412835]  arch_call_rest_init+0x18/0x20
[ 1704.417292]  start_kernel+0x514/0x54c
[ 1704.420890] Code: a9425bf5 a9446bf9 a8c77bfd d65f03c0 (d4210000)
[ 1704.426843] ---[ end trace 685b595989f3ff3d ]---
[ 1704.431382] Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt
[ 1704.438905] SMP: stopping secondary CPUs
[ 1704.442856] Kernel Offset: 0x25e80c320000 from 0xffff800010000000
[ 1704.449049] PHYS_OFFSET: 0xffffc33100000000
[ 1704.453184] CPU features: 0x8240002,03802a30
[ 1704.457878] Memory Limit: none
[ 1704.461037] ---[ end Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt ]---

Why only send 8 bits? If you want to repeat this I’ve attached my simple project to do this.

SPI Test Project (134.4 KB)

The binary is located at `spi\cmake_spi_test\build\spi_test

You can test it with:

Transfer a single 16-bit value

./spi_test --device /dev/spidev2.0 -s 1000000 --bpw 16 --verbose --cpha 1 --cpol 1 -I 1

Transfer two16-bit values in a back-to-back transaction

./spi_test --device /dev/spidev2.0 -s 1000000 --bpw 16 --verbose --cpha 1 --cpol 1 -I 2

The notable changes in the ‘spi_test’ project are here:

static void transfer_n(int fd, uint8_t const *tx, uint8_t const *rx, size_t len,
                       int n) {
  int ret;
  int out_fd;

  struct spi_ioc_transfer *tr =
      (struct spi_ioc_transfer *)malloc(n * sizeof(struct spi_ioc_transfer));

  for (int i = 0; i < n; i++) {
    memset(&tr[i], 0, sizeof(struct spi_ioc_transfer));
    tr[i].tx_buf = (unsigned long)tx;
    tr[i].rx_buf = (unsigned long)rx;
    tr[i].len = len;
    tr[i].cs_change = 1;
    tr[i].delay_usecs = delay;
    tr[i].speed_hz = speed;
    tr[i].bits_per_word = bits;
  }

  // struct spi_ioc_transfer tr = {
  //    .tx_buf = (unsigned long)tx,
  //    .rx_buf = (unsigned long)rx,
  //    .len = len,
  //    .delay_usecs = delay,
  //    .speed_hz = speed,
  //    .bits_per_word = bits,
  //};

  // if (!(mode & SPI_LOOP)) {
  //  if (mode & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL))
  //    tr.rx_buf = 0;
  //  else if (mode & (SPI_RX_OCTAL | SPI_RX_QUAD | SPI_RX_DUAL))
  //    tr.tx_buf = 0;
  //}

  printf("TX Buffer (Length: %ld):", len);
  for (int i = 0; i < len; i++) {
    printf(" 0x%02X", tx[i]);
  }
  printf("\n");

  ret = ioctl(fd, SPI_IOC_MESSAGE(n), tr);
  if (ret < 1)
    pabort("can't send spi message");

  if (verbose)
    hex_dump(tx, len, 32, "TX");

  if (output_file) {
    out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (out_fd < 0)
      pabort("could not open output file");

    ret = write(out_fd, rx, len);
    if (ret != len)
      pabort("not all bytes written to output file");

    close(out_fd);
  }

  if (verbose)
    hex_dump(rx, len, 32, "RX");
  free(tr);
}

RE: @y.kim: Thanks a lot for taking the time to respond, I see that the time between CS changes is rather small, I’ll check into that too by adding the ‘delay’ within the DTS file.

Edit: I wanted to upload a picture of a capture with two back-to-back transfers when cs_change was set to 0 and I once again got a kernel panic. The first time I captured it I didn’t see a panic the second time it did.

Thanks for your continued help.

Dave

Hi,
On Xavier NX, we can enable SPI1 or SPI3. Seems like you use SPI3 but please help confirm it.

And please check if you can run loopback test like:
Enabling SPI Nodes on Xavier-Nx - #3 by ShaneCCC

Yes, we are using SPI3, here is my dtsi file enabling it and I can confirm that I have successfully communicated with the IMU.

#include <dt-bindings/gpio/tegra-gpio.h>

/ {
  spi@3230000{
    status = "okay";
    //nvidia,polling-mode = <0>;
    spi@0 { /* chip select 0 */
      compatible = "tegra-spidev";
      reg = <0x0>;
      //spi-max-frequency = <50000000>;
      spi-max-frequency = <25000000>; /* 25MHz */
      controller-data {
        nvidia,enable-hw-based-cs;
        nvidia,rx-clk-tap-delay = <0x10>;
        nvidia,tx-clk-tap-delay = <0x0>;
        nvidia,cs-inactive-cycles = <0x08>;
      };
    };

    spi@1 { /* chips select 1 */
      compatible = "tegra-spidev";
      reg = <0x1>;
      spi-max-frequency = <50000000>;
      controller-data {
        nvidia,enable-hw-based-cs;
        nvidia,rx-clk-tap-delay = <0x10>;
        nvidia,tx-clk-tap-delay = <0x0>;
      };
    };
  };
};

The SPI device works as expected whenever SPI_IOC_MESSAGE(1) is used. I’ve used it to transfer larger captures (34 bytes) and can confirm that I could read a transfer of 34 bytes. I would prefer, but do not need to use a SPI_IOC_MESSAGE(2).

Is there a way I can configure the internal loopback settings within the ‘sysfs’ directory? Or dtsi file?

Here is my pinmux configuration within a dtsi file:

#include <dt-bindings/pinctrl/pinctrl-tegra.h>

/ {
  pinmux@2430000 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinmux_default>;

    pinmux_default: common {
      /* SFIO Pin Configuration */
...


      imu_spi_sck {
        nvidia,pins = "spi3_sck_py0";
        nvidia,function = "spi3";
        nvidia,pin-label = "imu_spi_sck";
        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
        nvidia,tristate = <TEGRA_PIN_DISABLE>;
        nvidia,enable-input = <TEGRA_PIN_ENABLE>;
        nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
        nvidia,lpdr = <TEGRA_PIN_DISABLE>;
        nvidia,pull-up-strength   = <31>;
        nvidia,pull-down-strength = <31>;
      };

      imu_spi_miso {
        nvidia,pins = "spi3_miso_py1";
        nvidia,function = "spi3";
        nvidia,pin-label = "imu_spi_poci";
        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
        nvidia,tristate = <TEGRA_PIN_DISABLE>;
        nvidia,enable-input = <TEGRA_PIN_ENABLE>;
        nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
        nvidia,pull-up-strength = <31>;
        nvidia,pull-down-strength = <31>;
        nvidia,lpdr = <TEGRA_PIN_DISABLE>;
      };

      imu_spi_mosi {
        nvidia,pins = "spi3_mosi_py2";
        nvidia,function = "spi3";
        nvidia,pin-label = "imu_spi_pico";
        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
        nvidia,tristate = <TEGRA_PIN_DISABLE>;
        nvidia,enable-input = <TEGRA_PIN_ENABLE>;
        nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
        nvidia,pull-up-strength   = <31>;
        nvidia,pull-down-strength = <31>;
        nvidia,lpdr = <TEGRA_PIN_DISABLE>;
      };

      imu_spi_cs_n {
        nvidia,pins = "spi3_cs0_py3";
        nvidia,function = "spi3";
        nvidia,pin-label = "imu_spi_cs_n";
        nvidia,pull = <TEGRA_PIN_PULL_UP>;
        nvidia,tristate = <TEGRA_PIN_DISABLE>;
        nvidia,enable-input = <TEGRA_PIN_ENABLE>;
        nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
        nvidia,pull-up-strength   = <31>;
        nvidia,pull-down-strength = <31>;
        nvidia,lpdr = <TEGRA_PIN_DISABLE>;

      };
...
};

Let me know if there is something you would like me to try something.

Hi,
Since you have figured out a solution:
Extra clock transition when using SPIDEV with longer transactions - #6 by dmc

This should not be an issue for now? Please help confirm it. Thanks.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.