AnsweredAssumed Answered

iMX6q SPI slave problem

Question asked by raymond man on Feb 5, 2016
Latest reply on Feb 8, 2016 by raymond man

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!

Outcomes