HiKey 960 SPI Transfer Speed Issue

I am trying to transfer data over SPI3 on HS at 20Mbps rate. I am testing the speed by writing and reading 1MB of data at 32K bursts. SPI transfer rate I am seeing is about 7Mbps. Each 32K burst takes about 37ms to transfer. I connected Saleae SPI analyzer and captured the transfers. What I am seeing is, during the 32K burst transfer, there is time gap of about 2 micro secs between each byte transferred. I can’t explain where this time gap is coming from. I bumped up the SPI master’s thread priority to real-time and still it didn’t make any difference. Is this wait time coming from SSP pl022? Is there any special settings/mode for higher SPI speed? If anyone has tried SPI at higher speed, please comment.

I appreciate any suggestions.

Thank you!

SPI3? Please clarify the pin names. I didn’t see such a port in Hikey960 schematics. @sv2018

Hi Guodong,

Thanks for the reply! I am referring to the SPI output from High-Speed connector. The pin names are GPIO_148_SPI3_DO, GPIO_149_SPI3_CS0_N, GPIO_146_SPI3_CLK and GPIO_147_SPI3_DI. In the schematics it is shown in Page-20 IO_CONN and in Page-9 SOC GPIO. In the device tree it is mapped by spi3: spi@ff3b3000 (in hi3660.dtsi).

Thank you!

After I changed the bits per word setting I am able to get ~14Mbps. I am running 20MHz at SPI clock frequency. I was expecting around 20Mbps transfer rate.

The HiKey 3660 Soc manual says with SPI we can get up to 30Mbps transfer rate. Does that assume running max SPI clock of 40MHz?

Any inputs on getting better transfer rate with 20MHz would be greatly appreciated!

HiSilicon engineers checked your captured picture. Can you confirm:

  1. are you working in SPI3 DMA mode?
  2. In SPI_CLK, is the clock frequency is 20MHz? (50ns width each cycle?)?
  3. Because in DMA mode, SPI controller will insert 2~3 cycle of delay in between each byte’s transfer. So,
    if you answer ‘yes’ to Q1 and Q2, then 2us delay in between is not right. HiSilicon wants to ananlyze more together with you.

Let us know your email address.

-Guodong

Hi Guodong,

Thanks for helping with this issue!

Here are my answers:

  1. No I am not setting DMA mode for SPI3. I am using only default POLLING mode.
  2. Yes, SPI_CLK is 20 MHz.

I have sent my email address on a separate message.

The picture I posted above was captured with a setting of 8 bits per word. With this I see a gap of 2us delay between each byte transferred. I am seeing transfer rate of 7 Mbps.

But if I use 16 bits per word setting, I am seeing double the performance(14 Mbps). And the in that case there is 1us gap between every three 16-bit words transferred. I am still on Polling mode.

I was thinking DMA mode could improve the performance and take it closer to 20 Mbps. But from what you are saying DMA mode inserts delay between each byte’s transfer. If that’s the case, will DMA mode help improve transfer speed or not?

Hi @guodong

Attached is the analyzer capture with 25MHz clock speed and 16wps setting. There is 1us gap between three 16-bit words.


Were you eventually able to increase the speed and decrease the gaps with DMA?

您好,我这边也遇到类似的问题了,我发现pl022驱动使用中断和polling方式,每两个字节之间有很大的延迟。我通过设置使用DMA的方式,但是spi_sync直接阻塞了,请问是否需要更新pl022的DMA?

spi_sync will remain blocked after DMA is enabled

[ 242.810186] Call trace:
[ 242.812658] [] __switch_to+0x8c/0xb0
[ 242.817823] [] __schedule+0x28c/0x68c
[ 242.823062] [] schedule+0x3c/0xa0
[ 242.827981] [] schedule_timeout+0x17c/0x2f0
[ 242.833738] [] wait_for_common+0xbc/0x174
[ 242.839321] [] wait_for_completion+0x14/0x1c
[ 242.845171] [] __spi_sync+0x128/0x218
[ 242.850420] [] spi_sync+0x2c/0x4c
[ 242.855316] [] thp_spi_sync+0xc/0x14
[ 242.860461] [] eph_comms_read.part.8+0xa4/0x13c
[ 242.866629] [] touch_driver_power_reset+0xac/0x188
[ 242.873022] [] touch_driver_chip_detect+0x58/0x140
[ 242.879447] [] thp_register_dev+0x410/0xd7c
[ 242.885205] [] touch_driver_module_init+0x134/0x1a4
[ 242.891659] [] do_one_initcall+0x48/0x150
[ 242.897238] [] kernel_init_freeable+0x1b8/0x26c
[ 242.903339] [] kernel_init+0x18/0x138
[ 242.908567] [] ret_from_fork+0x10/0x20

1 Like