Xavier NX spi cs problems and timing

I’ve made some edits to the device tree, but most importantly the kernel module. More investigation is needed, but similar issues were found in How to set SPI CS(chip select) timing?, Bug in spi-tegra114.c and other spi related things, https://forums.developer.nvidia.com/t/spi-slave-can-only-receive-the-second-packet-from-nano-dev-kit-spi-master/110132and for some reason, not all of the proposed patches/fixes made it into the current kernel. I’ve done a quick hack to get something working, but this is not at all robust and may not solve all issues. Basically I commented out a check for gpio chip select, changed tegra-spidev to linux,spidev, and disabled prod-settings in the device tree.

Below I included some quite verbose notes on how I did this for anyone and/or myself in the future.


Getting Kernel Sources

Get the sources:

RELEASE=35
VERSION=1.0
KERNEL=5.10
RELEASE_VERSION=r${RELEASE}_release_v${VERSION}
ARCHIVE_NAME=public_sources_${RELEASE_VERSION}
SOURCES_NAME=Linux_for_Tegra_${RELEASE_VERSION}
mkdir -p ${HOME}/src/nvidia/l4t_sources/xavier_nx && cd ${HOME}/src/nvidia/l4t_sources/xavier_nx
wget https://developer.nvidia.com/embedded/l4t/${RELEASE_VERSION}/sources/public_sources.tbz2
mv public_sources.tbz2 ${ARCHIVE_NAME}.tbz2
tar -xvf ${ARCHIVE_NAME}.tbz2 && mv Linux_for_Tegra ${SOURCES_NAME}
cd ${SOURCES_NAME}/source/public
JETSON_XAVIER_NX_KERNEL_SOURCES=$(pwd)
tar -xvf kernel_src.tbz2


Kernel Module Modifications

Copy the driver

# Make a copy of the spi driver
SPI_DIR=kernel/kernel-${KERNEL}/drivers/spi
SPI_DRIVER_DIR=${JETSON_XAVIER_NX_KERNEL_SOURCES}/${SPI_DIR}
mkdir -p ${HOME}/src/spi && cd ${HOME}/src/spi
cp ${SPI_DRIVER_DIR}/spi-tegra114.c ./

Create a Makefile containing the following with nano Makefile:

obj-m += spi-tegra114.o
	
all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
install:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install

Edit the spi kernel driver. We modified it by commenting out checks on gpio chip selects and inactive cycles as follows: nano spi-tegra114.c

// line 1302
	if (cdata && cdata->clk_delay_between_packets) {
		// if (cdata->cs_inactive_cycles || !cstate->cs_gpio_valid) {
		// if (cdata->cs_inactive_cycles) {
		// 	dev_err(&spi->dev,
		// 		"Invalid cs packet delay config\n");
		// 	tegra_spi_cleanup(spi);
		// 	return -EINVAL;
		// }
		cdata->cs_inactive_cycles = cdata->clk_delay_between_packets;
	}

It was rebuilt as spi-tegra114.ko and placed in /lib/modules/$(uname -r)/kernel/drivers/spi/:

make
mv /lib/modules/$(uname -r)/kernel/drivers/spi/spi-tegra114.ko /lib/modules/$(uname -r)/kernel/drivers/spi/spi-tegra114.ko.bak
cp ${HOME}/src/spi/spi-tegra114.ko /lib/modules/$(uname -r)/kernel/drivers/spi/


Device Tree Preparation

The device tree was prepared as:

# Prepare tree and image
echo DEVICE=tegra194-p3668-0001-p3509-0000 >> ${HOME}/.bashrc && . ${HOME}/.bashrc
echo BOOT_LOCATION=/boot >> ${HOME}/.bashrc && . ${HOME}/.bashrc
sudo cp ${BOOT_LOCATION}/dtb/kernel_${DEVICE}.dtb /boot/dtb/kernel_${DEVICE}.dtb.bak
sudo cp ${BOOT_LOCATION}/Image ${BOOT_LOCATION}/Image.bak

# Get the original device tree
mkdir -p ${HOME}/src/device_trees
dtc -I dtb -O dts -o ~/src/device_trees/original_tree.dts ${BOOT_LOCATION}/dtb/kernel_${DEVICE}.dtb.bak

# Prepare the spi overlay
sudo /opt/nvidia/jetson-io/config-by-function.py spi1 -o dtbo
sudo mv ${BOOT_LOCATION}/kernel_${DEVICE}-hdr40-user-custom.dtbo ~/src/device_trees/kernel_${DEVICE}-hdr40-user-custom.dtbo && dtc -I dtb -O dts -o ~/src/device_trees/spi_overlay.dts ~/src/device_trees/kernel_${DEVICE}-hdr40-user-custom.dtbo

Edit the new overlay: nano ${HOME}/src/device_trees/spi_overlay.dts to add in the following fragment:

fragment@1 {
    target-path = "/spi@3210000";
    __overlay__ {

        prod-settings {
            status= "disabled";
        };

        spi@0 {
            compatible = "linux,spidev";
            
            controller-data {
                nvidia,clk-delay-between-packets = <2>;
            };
        };
    };
};

Apply the new overlay:

dtc -I dts -O dtb -@ -o ${HOME}/src/device_trees/original_tree.dtb ${HOME}/src/device_trees/original_tree.dts && dtc -I dts -O dtb -@ -o ${HOME}/src/device_trees/spi_overlay.dtbo ${HOME}/src/device_trees/spi_overlay.dts && sudo fdtoverlay -i ${HOME}/src/device_trees/original_tree.dtb -o ${BOOT_LOCATION}/dtb/kernel_${DEVICE}.dtb ${HOME}/src/device_trees/spi_overlay.dtbo


Testing

Basic tests were carried out with https://github.com/rm-hull/spidev-test

mkdir -p ${HOME}/src/ && cd ${HOME}/src/
git clone https://github.com/rm-hull/spidev-test
cd spidev-test
gcc spidev_test.c -o spidev_test

The test was run ${HOME}/src/spidev-test/spidev_test and produced:

Which is a good start. Next, exact timing controls will be investigated.


1 Like