Hi,
I am working on SPI slave mode on iMX6q with the Linux kernel 3.0.35_4.1.0 and have already applied the patch from i.MX6 ESPI slave mode support patch based on rel_imx_3.0.35_4.1.0
The burst length is set to 31.
A single SPI transfer is 2kB of a test pattern from 0x00 to 0xff repeatedly is used to test the SPI transfer.
If SPI clock is 18MHz, iMX6 receives incorrect data starting from 256bytes, or 64x32bits (the fifo size). Starting from 257th bytes, it should repeat 0x00 to 0xff. The received data may be of the following patterns,
256: 14 15 16 17 18 19 1a 1b
256: 0c 0d 0e 0f 10 11 12 13
256: 08 09 0a 0b 0c 0d 0e 0f
If SPI clock is ~1MHz, the error starts at a later position,
776: 00 03 77 2c a1 49 88 92
776: bf 3f c0 40 c1 41 c2 42
1036: c1 41 c2 42 36 60 e0 89
Does It mean that iMX6 is not fast enough to handle the incoming SPI data due to OS latency? Can anyone share experience how fast the SPI clock iMX6q can support? Or Do I need to modify the configuration?
I also refer to the below link to add DMA support
Linux Kernel - [PATCH V1] spi: imx: add dma support for ecspi
Below are debug messages to show the workflow of the DMA.
sdma_control
sdma_config_channel
sdma_disable_channel
sdma_config_ownership
sdma_get_pc
peripheral_type=7
IMX_DMATYPE_CSPI
sdma_set_chan_private_data
sdma_load_context
imx-sdma imx-sdma: load_address = 683
imx-sdma imx-sdma: wml = 0x00000001
imx-sdma imx-sdma: shp_addr = 0x02008000
imx-sdma imx-sdma: per_addr = 0x00000000
imx-sdma imx-sdma: event_mask0 = 0x00000001
imx-sdma imx-sdma: event_mask1 = 0x00000000
sdma_set_context_reg
sdma_run_channel
RX dma config OK
sdma_control
sdma_config_channel
sdma_disable_channel
sdma_config_ownership
sdma_get_pc
peripheral_type=7
IMX_DMATYPE_CSPI
sdma_set_chan_private_data
sdma_load_context
imx-sdma imx-sdma: load_address = 747
imx-sdma imx-sdma: wml = 0x00000020
imx-sdma imx-sdma: shp_addr = 0x02008004
imx-sdma imx-sdma: per_addr = 0x00000000
imx-sdma imx-sdma: event_mask0 = 0x00000001
imx-sdma imx-sdma: event_mask1 = 0x00000000
sdma_set_context_reg
sdma_run_channel
TX dma config OK
spi_imx_transfer
sdma_prep_slave_sg chan_id=1 sg_len=1, dir=2 flags=3
imx-sdma imx-sdma: setting up 1 entries for channel 2.
setting up 1 entries for channel 2.
sdma_load_context
imx-sdma imx-sdma: load_address = 683
imx-sdma imx-sdma: wml = 0x00000001
imx-sdma imx-sdma: shp_addr = 0x02008000
imx-sdma imx-sdma: per_addr = 0x00000000
imx-sdma imx-sdma: event_mask0 = 0x00000001
imx-sdma imx-sdma: event_mask1 = 0x00000000
sdma_set_context_reg
sdma_run_channel
imx-sdma imx-sdma: entry 0: count: 8 dma: 0x00000000 intr
sdma_prep_slave_sg chan_id=0 sg_len=1, dir=1 flags=3
imx-sdma imx-sdma: setting up 1 entries for channel 1.
setting up 1 entries for channel 1.
sdma_load_context
imx-sdma imx-sdma: load_address = 747
imx-sdma imx-sdma: wml = 0x00000020
imx-sdma imx-sdma: shp_addr = 0x02008004
imx-sdma imx-sdma: per_addr = 0x00000000
imx-sdma imx-sdma: event_mask0 = 0x00000001
imx-sdma imx-sdma: event_mask1 = 0x00000000
sdma_set_context_reg
sdma_run_channel
imx-sdma imx-sdma: entry 0: count: 8 dma: 0x00000000 intr
sdma_tx_submit
sdma_assign_cookie
sdma_enable_channel channel=1
sdma_tx_submit
sdma_assign_cookie
sdma_enable_channel channel=2
sdma_issue_pending
sdma_issue_pending
spidev spi0.0: DMA transfer timeout
sdma_control
sdma_disable_channel
sdma_control
sdma_disable_channel
Transfer end
07 65 55 13 50 29 05 c4 spidev_message
It seems DMA cannot receive any interrupt.
I can run mxc_sdma_test from Freescale which does memory-to-memory DMA transfer successfully. During the process, sdma_int_handler() is called.
Can anyone advise what's wrong with the DMA of my case? How can I check if SDMA can support the DMA transfer from/to ECSPI? In imx-sdma.c, I can see the following line to get the firmware name. Where is this firmware stored? I am using Yocto/Dora root filesystem image downloaded from https://boundarydevices.com/yocto-dora-release-mx6/
If the firmware is not correct, where can I download the one supporting ECSPI DMA?
fwname = kasprintf(GFP_KERNEL, "imx/sdma/sdma-%s-to%d.bin", | ||||
cpu_name, to_version); |
Additional information:
Try 2 sets of configuration
1)
ECSPI1_CONREG= 0x01f000e1
ECSPI1_CONFREG= 0x00000000
ECSPI1_DMAREG= 0x81020020
2)
ECSPI1_CONREG= 0x01F10001
ECSPI1_CONFREG= 0x00000000
ECSPI1_DMAREG= 0x008300A0;
While booting up the system, I can see sdma_int_handler() is called.
sdma_request_channel
sdma_set_channel_priority
sdma_config_ownership
sdma_set_channel_priority
sdma_add_scripts
sdma_get_firmware
sdma_load_script
sdma_run_channel
sdma_int_handler
sdma_add_scripts
imx-sdma imx-sdma: loaded firmware 1.1
imx-sdma imx-sdma: initialized
Thanks a lot!
Hi,
In this link Linux-Kernel Archive: [PATCH v2 8/8] spi: imx: Add support for SPI Slave mode for imx53 and imx6 chi...
It mentions that
2. Due to Freescale errata ERR003775 "eCSPI: Burst completion by Chip
Select (SS) signal in Slave mode is not functional" burst size must
be set exactly to the size of the transfer. This limit SPI transaction
with maximum 2^12 bits.
Is it true that I can only transfer 512bytes in a single transaction?
Thanks a lot!
Hi raymond
this is right:
slave mode with unspecified burst length cannot be supported due to this issue.
The burst length should always be specified with the BURST_LENGTH parameter.
Also it may be useful to look at
Re: imx6 SPI in DMA mode sometime throws "I/O Error in DMA RX"
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi igor,
Thanks for your reply.
That means I may send 16kb or more if imx6 is used as spi master like the author in the thread. But as slave mode, I can transmit or receive 512kbytes (the maximum burst lenght) in a single transfer, right?
The sdma firmware 1.1 should be working for spi slave mode using DMA, right?
Many thanks!
Hi igor,
I set the packet size to 256Bytes (the fifo size) and burst_legnth to 7FF. It seems sometimes DMA can work but the received data is not correct. There are still chances that DMA timeout.
If using PIO, the data can be received correctly. Do you have more hints?
Many thanks!