Re: Issues with i.MX SPI DMA transfers

Igor Plyatov
2019-04-02T12:15:34Z

[-- Attachment #1: Type: text/plain, Size: 2659 bytes --]

Dear Robin,

>> now I have reverted patch ad0d92d7ba6a.
>> Patches 0001-dma-engine-imx-sdma-add-mcu_2_ecspi-script.patch and
>> 0002-spi-spi-imx-fix-ERR009165.patch are applied.
>>
>>
>> Kernel log show messages
>>
>> [   29.202639] imx-sdma 20ec000.sdma: loaded firmware 3.3
>> [   29.238595] spi_imx 2008000.spi: probed
>> [   29.242802] spi_imx 200c000.spi: probed
>> [   29.245217] spi_imx 2018000.spi: probed
>>
>> SPI DMA transfers still not work.
>>
>> If I test 32 byte transfers, then they work fine. But 64 byte transfers
>> fails always and I see error messages
>>
>> root@cr7:~# spidev_test -D /dev/spidev4.1 -s 1200000 -b 8 -S 64 -I 1 -l
>> spi mode: 0x20
>> bits per word: 8
>> max speed: 1200000 Hz (1200 KHz)
>> [  423.686736] spi_master spi4: I/O Error in DMA RX
>> [  423.691392] spidev spi4.1: SPI transfer failed: -110
>> [  423.696382] spi_master spi4: failed to transfer one message from queue
>> can't send spi message: Connection timed out
>> Aborted (core dumped)
>>
>> I suppose, transfers shorter then 64 bytes made with help of PIO.
>>
>> Robin, is there any chance for you to find some time and look at this
>> issue again?
> I have quick test with spidev_test loopback, but didn't meet your error,
> Is your code the almost latest code in linux-next as mine?
>
> root@imx6qpdlsolox:~# cat /proc/interrupts | grep sdma
> 48: 37 GPC 2 Level sdma
> -lt@imx6qpdlsolox:~# ./spidev_test -D /dev/spidev0.0 -s 1200000 -b 8 -S 64 -I 1 -l
> spi mode: 0x20
> bits per word: 8
> max speed: 1200000 Hz (1200 KHz)
> root@imx6qpdlsolox:~# cat /proc/interrupts | grep sdma
> 48: 43 GPC 2 Level sdma
> ./spidev_test -D /dev/spidev0.0 -s 1200000 -b 8 -S 512 -I 1 -l
> spi mode: 0x20
> bits per word: 8
> max speed: 1200000 Hz (1200 KHz)
> total: tx 0.5KB, rx 0.5KB

My previous test results based on kernel from "main" branch of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git.

Now I have tested kernel from "main" branch of
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git.

Its latest commit is 05d08e2995cbe6efdb993482ee0d38a77040861a.

Additionally, I have reverted patch ad0d92d7ba6a and apply yours patches
0001-dma-engine-imx-sdma-add-mcu_2_ecspi-script.patch and
0002-spi-spi-imx-fix-ERR009165.patch.

Difference between 05d08e2995cbe6efdb993482ee0d38a77040861a and current
state of drivers attached as spi-and-sdma-drivers.diff.

SPI driver still not work. It has same result as from my previous email.

Looks as you use either different GIT branch of kernel or you have
forget to say me about some patch.

Best wishes.

--

Igor Plyatov

[-- Attachment #2: spi-and-sdma-drivers.diff --]
[-- Type: text/x-patch, Size: 2768 bytes --]

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 5f3c1378b90e..908507fa9526 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -377,7 +377,6 @@ struct sdma_channel {
unsigned long watermark_level;
u32 shp_addr, per_addr;
enum dma_status status;
- bool context_loaded;
struct imx_dma_data data;
struct work_struct terminate_worker;
};
@@ -913,6 +912,9 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
emi_2_per = sdma->script_addrs->mcu_2_ata_addr;
break;
case IMX_DMATYPE_CSPI:
+ per_2_emi = sdma->script_addrs->app_2_mcu_addr;
+ emi_2_per = sdma->script_addrs->mcu_2_ecspi_addr;
+ break;
case IMX_DMATYPE_EXT:
case IMX_DMATYPE_SSI:
case IMX_DMATYPE_SAI:
@@ -976,9 +978,6 @@ static int sdma_load_context(struct sdma_channel *sdmac)
int ret;
unsigned long flags;

- if (sdmac->context_loaded)
- return 0;
-
if (sdmac->direction == DMA_DEV_TO_MEM)
load_address = sdmac->pc_from_device;
else if (sdmac->direction == DMA_DEV_TO_DEV)
@@ -1021,8 +1020,6 @@ static int sdma_load_context(struct sdma_channel *sdmac)

spin_unlock_irqrestore(&sdma->channel_0_lock, flags);

- sdmac->context_loaded = true;
-
return ret;
}

@@ -1062,7 +1059,6 @@ static void sdma_channel_terminate_work(struct work_struct *work)
sdmac->desc = NULL;
spin_unlock_irqrestore(&sdmac->vc.lock, flags);
vchan_dma_desc_free_list(&sdmac->vc, &head);
- sdmac->context_loaded = false;
}

static int sdma_disable_channel_async(struct dma_chan *chan)
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 09c9a1edb2c6..27578158d922 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -585,8 +585,9 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk);
spi_imx->spi_bus_clk = clk;

+ /* ERR009165: work in XHC mode as PIO */
if (spi_imx->usedma)
- ctrl |= MX51_ECSPI_CTRL_SMC;
+ ctrl &= ~MX51_ECSPI_CTRL_SMC;

writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);

@@ -1265,10 +1266,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
{
int ret;

- /* use pio mode for i.mx6dl chip TKT238285 */
- if (of_machine_is_compatible("fsl,imx6dl"))
- return 0;
-
spi_imx->wml = spi_imx->devtype_data->fifo_size / 2;

/* Prepare for TX DMA: */
diff --git a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma-imx-sdma.h
index 6eaa53cef0bd..f794fee8fc0f 100644
--- a/include/linux/platform_data/dma-imx-sdma.h
+++ b/include/linux/platform_data/dma-imx-sdma.h
@@ -51,6 +51,7 @@ struct sdma_script_start_addrs {
/* End of v2 array */
s32 zcanfd_2_mcu_addr;
s32 zqspi_2_mcu_addr;
+ s32 mcu_2_ecspi_addr;
/* End of v3 array */
};