SPI error: I/O Error in DMA RX

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

SPI error: I/O Error in DMA RX

ソリューションへジャンプ
5,262件の閲覧回数
jotes
Contributor IV

Hello, 

In our system we are using ECSPI to transfer a big portion of data to the device. One chunk of data is sended in this way:

spi_xfer.tx_buf = ptr;

spi_xfer.bits_per_word = 32;

spi_xfer.len = 0x10000;

spi_message_init(&msg);

spi_message_add_tail(&spi_xfer, &msg);

status = spi_sync(spidev, &msg);

Everything was fine, until we have changed the kernel version from 3.14.38 to 4.9.88 (from Boundary Devices). Now the kernel shows an error after transmiting first chunk of data (the following chunks are transmiting just fine):

spi_master spi4: I/O Error in DMA RX

spi4.0: SPI transfer failed: -110

spi_master spi4: failed to transfer one message from queue

It looks like after transmiting the first chunk, SDMA is still waiting for data, so it doesn't generate an interrupt. But we don't understand why, and why it works in older kernel.

We are using IMX6Q and linux-imx6-boundary-imx_4.9.x_1.0.0_ga.

ラベル(2)
0 件の賞賛
返信
1 解決策
4,119件の閲覧回数
jotes
Contributor IV

Problem solved. The following code was missing in imx-sdma.c (MLK-15305-2: dma: imx-sdma: force to load context in sdma_config · boundarydevices/linux-imx6@d802d8...):

@@ -1168,6 +1168,8 @@ static int sdma_config_channel(struct dma_chan *chan)
sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
}

+ sdmac->context_loaded = false;
+
ret = sdma_load_context(sdmac);

return ret;

元の投稿で解決策を見る

2 返答(返信)
1,982件の閲覧回数
GuLiang
Contributor I

I got the same problem in i.MX 6ULL in kernel version v4.1.15
It shows:
spi_master spi2: I/O Error in DMA RX:20d00
spi_master spi2: failed to transfer one message from queue
When I adjust the bits_per_word to 32 at the first SPI transmit

0 件の賞賛
返信
4,120件の閲覧回数
jotes
Contributor IV

Problem solved. The following code was missing in imx-sdma.c (MLK-15305-2: dma: imx-sdma: force to load context in sdma_config · boundarydevices/linux-imx6@d802d8...):

@@ -1168,6 +1168,8 @@ static int sdma_config_channel(struct dma_chan *chan)
sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
}

+ sdmac->context_loaded = false;
+
ret = sdma_load_context(sdmac);

return ret;