TX1 SPI Hardware CS incorrect behavior using regmap

Hello,

I’m working with an SPI to UART chip connected to my Jetson TX1 devboard.

My chip working using chipselect-gpio, but I see a lot of wasted time. 5us between CS activating and SCLK starting, 12us between SCLK stopping and CS deactivating, and about 12us between data bytes when sending multiple bytes. I have all controller-data values set to 0x00. Because of this inefficiency I want to try switching to enable-hw-based-cs to reduce some of the waiting. I set it up in the device tree, and I do see the CS toggling with less latency, though still about 5us sometimes, other times 0us. I tested spidev and using the hardware chip select, it has almost zero wasted time between CS active, no latency between data bytes, and no delay between between data and CS inactive.

My problem is: when I perform a read from my driver immediately followed by a write the system does not disable the CS between the two packets so my uart chip does not process the write packet. In some cases it seems as though the CS never is disabled after a read.

The driver for my SPI-uart chip uses regmap to read/write to the SPI and I have not been able to trace the exact call stack through the regmap.c to the spi-tegra114.c to diagnose why the CS line is not deactivating between read and write. This behavior does not exist with SW based CS, even when cs-inactive-cycles is 0.

Questions: Could this be a regmap issue? I could convert my driver to use direct SPI calls. Is this CS behavior something that can be controlled via the tegra spi registers? Why does spidev behave differently?

Any input you can provide is very welcome.

Thanks!
Andy

It’s better to use the SPI message to link all the access together to avoid the issue.

Hi Shane, thanks for the reply.

I’ve rewritten my driver to use the SPI API directly, however the issue is still present.

Here is my test:
Perform call to spi_write of 2 bytes (successful)
Perform call to spi_write_then_read with 1 byte write and 1 byte read (write and read successful)
Perform call to spi_write with 2 bytes (fails)

Upon investigation with the scope and SPI analyzer it appears that spi_write_then_read leaves the CS signal low after it completes and returns to my code, so the final spi_write fails because there is no CS toggle between the read and write.

I must keep CS low during the write-then-read for the slave chip’s protocol, so I can not split the two operations, and the performance of this bus must remain very high so software CS is not feasible.

SPI driver would toggle cs to inactive state after every transfer unless specified otherwise using cs_change field in transfer structure. Also if both read and write are combined into a single transfer, we will not see cs toggling. Could you try to use spi message directly so that can control the behavior.

I finally found the root cause of the issue.

In my device tree I have spi@7000d400 set to have two chip selects, and under that bus CS 0 is configured for my IC, CS 1 was configured for SPIDEV. When I completely removed the SPIDEV from the device tree for this SPI bus the hardware CS signal started working as expected.

I didn’t have time to diagnose why, but I wanted to post this here in the event that it could save someone else a lot of time.