I have been looking at the performance of the SPI to FPGA transactions on an oscilloscope and noticing that while I can transfer bytes at 25 MHz, the spidev driver puts very large gaps between bytes (2us and 6us repetitively compared to the 320ns required to transfer a single byte) when provided with an spi_ioc_message structure that transfers a large number of bytes in a single call. Given that the SPI devices on the Atom processor appear to support DMA, I am puzzled by this large overhead. The overhead is proving to be a limitation in our application, as transfers of, say 256 bytes, are taking about 1ms when they should take less than 100us.
I would like to investigate the reasons for this behaviour in the SPI controller kernel driver code in Yocto and possibly experiment with improving the situation. However, digging through the Yocto tree is a bit of a maze. I have found where the SPI devices are registered for the FPGA and IMU (meta-intel-aero-base/recipes-modules/intel-aero/files/*), but the source for the SPI master is not there. Does anyone know where the source code is for the SPI controller/master for the Intel Aero in the Yocto tree? (i.e. the code that actually interacts with the Serial IO (SIO) or Platform Controller Unit (PCU) of the Atom processor) Are there tried-and-true techniques for tracking these things down? (for instance, the SPI master appears to be the pci0000:00/8086228E:00/spi_master device under /sys/devices, but how might that be used to track down the source code in Yocto?).
Thank you for your interest in the Intel Aero drone.
Your request has been received and is currently being investigated.
We will get back to you as soon as possible.
The SPI is not using DMA for some reason by default. I applied the Linux kernel patches: "b6ced294fb61 spi: pxa2xx: Switch to SPI core DMA mapping functionality", and "c64e1265ae85 spi: pxa2xx: use DMA by default if supported" (on advice of Intel), and managed to get DMA working, but the SPI slave select line was still slow in deasserting for some reason, so the time to complete an SPI IOCtl call did not really change. Applying later SPI Linux kernel patches may be required (of which there are many it seems). If you try anything, please post your results.
I am interested in improving SPI performance as well. The SPI driver is mcp251x . You can find the master sources here: https://github.com/intel-aero/packages/find/master
I also found this on kernel.org for the pxa2xx (SPI driver) https://www.kernel.org/doc/Documentation/spi/pxa2xx
It seems that DMA is not the default path for SPI transfers?
DMA and PIO I/O Support
The pxa2xx_spi driver supports both DMA and interrupt driven PIO message
transfers. The driver defaults to PIO mode and DMA transfers must be enabled
by setting the "enable_dma" flag in the "pxa2xx_spi_master" structure. The DMA
mode supports both coherent and stream based DMA mappings.
There are alot of performance gains to be had with a better SPI driver. Our Application is gated by SPI - CANBUS performance . MicroChip's mcp251x CANBUS driver could pick up SPI performance gains, as would people working with the FPGA .
I have been trying to figure out where the Data Overrun CANBUS issues I have run into, are coming from. Maybe the SPI driver is the culprit?
Maybe Intel can help shed the light on this. I wasn't planning to build custom kernels or merging kernel patches just yet.
This documentation for the Intel® AtomTM Z8000 also covers the Aero x7-Z8750 . The section on SPI might be relevant for any performance tweaks.
Section 220.127.116.11 is a good starting point to understanding the Z8750's SPI support.
I recently encounter the SPI transfer problem with big gaps between every 8 bits with MRAA driver (PIO). In fact, it calls the ioctl() function to transfer data.
So I want to use DMA with pxa2xx driver too. But I don't know how to write (or use) the SPI Master driver.
Here is my understanding:
1. I need to register an platform_device with enable_dma=1.
2. Should I "insmod" this .ko file? And how to use this device under program?
3. I need to transfer data use according functions, and I am confused in this step. Is the function name like "pxa2xx_spi_dma_transfer"?
Could you give me some example or reference link? That would help me a lot.