SPI transfer API time cost issue

Hi everyone,
I use spi_sync to read data from an ADC device. The code as follow:

void test(void)
{
    int i, ret, miss_count=1;
    spi_message_init(&m);
    spi_message_add_tail(&tr, &m);
    for (i = 0; i < 40000; i++)
    {

        mutex_lock(&ads1299.buf_lock);

        calltime = ktime_get();
        ret = spi_sync(ads1299.spi, &m);
        rettime = ktime_get();

        /*calculate time cost*/
        delta = ktime_sub(rettime, calltime);
        duration = (unsigned long long )ktime_to_ns(delta) >> 10;
        
        if (duration > 200)
        {
            printk("%d miss, time is %lld us\r\n", miss_count,duration);
            miss_count++;
        }
        
        
        mutex_unlock(&ads1299.buf_lock);
    }
    printk("done\r\n");
}

The output is:


You can see sometimes the time up to 2000us. Then I try spi_async and found it’s performance is worse.

Cause I can read data from ADC when the ADC give a ready signal to me, and that signal will trigger a interrupt.I need finish spi data transfer between the 2 interrupts interval, for example, if I use 4kHz sample rate, I should finish the data read less than 250us, otherwise I will lose data.

I check the hardware time cost(CS low to high), it cost less than 50us, so I think the time cost may realted to the SPI controller driver.

I think about the DMA, and find this tipic How SPI can use DMA on Xavier! , ShaneCCC said when use these system api, use the DMA default.

So the question is :

  1. Can I reduce the time cost when I just use the system api (spi_sync, spi_async).
  2. How the SPI work with DMA? Can DMA control the SPI transfer directly?That is to say, the interrupt trigger the DMA, DMA read data use SPI, and when the data is enough, DMA trigger a callback to let CPU handle the data. If I want realize the idea, should I change the NVIDIA spi controller driver?
  3. Do you have any other idea about my requestment?

Thanks a lot.

Could you try polling mode by add below to device tree. Also boos the system by

sudo nvpmodel -m 0
sudo jetson_clocks

Have detail information from …/kernel/kernel-4.9/Documentation/devicetree/bindings/spi/nvidia%2Ctegra114-spi.txt

nvidia,polling-mode, nvidia,disable-runtime-pm

Hi, Shane
This is my dt config

spi@7000d400 {
		compatible = "nvidia,tegra210-spi";
		reg = <0x0 0x7000d400 0x0 0x200>;
		interrupts = <0x0 0x3b 0x4>;
		iommus = <0x30 0xe>;
		#address-cells = <0x1>;
		#size-cells = <0x0>;
		dmas = <0x51 0xf 0x51 0xf>;
		dma-names = "rx", "tx";
		nvidia,clk-parents = "pll_p", "clk_m";
		clocks = <0x26 0x29 0x26 0xf3 0x26 0xe9>;
		clock-names = "spi", "pll_p", "clk_m";
		resets = <0x26 0x29>;
		reset-names = "spi";
		status = "okay";
		linux,phandle = <0xf8>;
		phandle = <0xf8>;

		prod-settings {
			#prod-cells = <0x3>;

			prod {
				prod = <0x4 0xfff 0x0>;
			};

			prod_c_flash {
				status = "disabled";
				prod = <0x4 0x3f 0x7>;
			};

			prod_c_loop {
				status = "disabled";
				prod = <0x4 0xfff 0x44b>;
			};
		};

		ads1299@0 {
			compatible = "ads1299";
			reg = <0x0>;
			spi-max-frequency = <0x1f78a40>;

			controller-data {
				nvidia,polling-mode;
				nvidia,disable-runtime-pm;
				nvidia,enable-hw-based-cs;
				nvidia,cs-setup-clk-count = <0>;
				nvidia,cs-hold-clk-count = <0>;
				nvidia,rx-clk-tap-delay = <0>;
				nvidia,tx-clk-tap-delay = <0>;
			};
		};

It seems not change the spi transfer ability.

@Gaosiy
Here is response from NV internal.

  1. Can I reduce the time cost when I just use the system api (spi_sync, spi_async).
    Yes the time cost can be reduced.
  2. How the SPI work with DMA? Can DMA control the SPI transfer directly?That is to say, the interrupt trigger the DMA, DMA read data use SPI, and when the data is enough, DMA trigger a callback to let CPU handle the data. If I want realize the idea, should I change the NVIDIA spi controller driver?
    SPI DMA gets triggered when the BS is greater than 256B and it will control the transfer. If you wish to use PIO mode you need to limit to BS of 256B. If your planning to use just the PIO I can provide you a change which would disable the DMA and just run the transfers using PIO.

Thanks, Shane.

  1. How can I reduce the time cost, I add the items you give it seems not to work.
  2. For me, SPI transfer 27 Byte once, maybe I can try your method.

Best wishes!

Hi Shane, any suggestion about PIO?