Skip to content

SPI0 with DMA transfer occurs **TIMEOUT** error on raspbery pi 4B #4219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jiulongshan opened this issue Mar 17, 2021 · 5 comments
Closed

SPI0 with DMA transfer occurs **TIMEOUT** error on raspbery pi 4B #4219

jiulongshan opened this issue Mar 17, 2021 · 5 comments

Comments

@jiulongshan
Copy link

spi0 dma occur TIMEOUT error
We use the spi0 with DMA transfer pathway on raspberrypi pi 4b, the peripheral device is FTF LCD st7789v.
1,it occurs transfer TIMOUT error when display RGB565 data to the LCD divice which log messages ars at follow.
2,when this error happens, it can not restore by reboot the system.
3,Looks like this error is concern about the SPI0-DMA , and this error is similar with #3570

System

  • Which model of Raspberry Pi?
    --> Pi4B 2G DDR

  • Which OS and version (cat /etc/rpi-issue)?
    --> Raspberry Pi reference 2020-12-02
    Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, cce27bd6f44a3b2e83855645986b3e21f771e852, stage4

  • Which firmware version (vcgencmd version)?
    -->Jan 8 2021 14:31:16
    Copyright (c) 2012 Broadcom
    version 194a85abd768c7334bbadc3f1911c10a7d18ed14 (clean) (release) (start)

  • Which kernel version (uname -a)?
    Linux raspberrypi 5.4.79-v7l+ su without password via /proc/pid/mem write #2 SMP Fri Mar 12 13:06:56 CST 2021 armv7l GNU/Linux

Logs
[ 101.276092] st7789v_spi_transfer success
[ 101.276146] st7789v_spi_transfer success
[ 101.276162] lcd cs lcd_a
[ 101.501462] st7789v spi0.0: SPI transfer timed out
[ 101.501515] spi_master spi0: failed to transfer one message from queue
[ 101.501534] st7789v_spi_transfer failed, status=-110
[ 101.731408] st7789v spi0.0: SPI transfer timed out
[ 101.731456] spi_master spi0: failed to transfer one message from queue
[ 101.731475] st7789v_spi_transfer failed, status=-110
[ 101.961396] st7789v spi0.0: SPI transfer timed out
[ 101.961442] spi_master spi0: failed to transfer one message from queue
[ 101.961460] st7789v_spi_transfer failed, status=-110
[ 102.181403] st7789v spi0.0: SPI transfer timed out
[ 102.181452] spi_master spi0: failed to transfer one message from queue
[ 102.181470] st7789v_spi_transfer failed, status=-110
[ 102.181483] write data end
[ 102.207565] write data size = 115201
[ 102.207659] mode = 2, buf data a7 41 3d f7 32 ac
[ 102.207727] st7789v_spi_transfer success
[ 102.207784] st7789v_spi_transfer success
[ 102.207837] st7789v_spi_transfer success

Additional context
Action List for now:
1, put dtparam=spi_dma4 in /boot/config.txt
effection: this can make system back to normal, but it can not hold longer than 15mins for transfer timeout error.
2, annotate the dtparam=i2s=on in /boot/config.txt
3, modify the spi clk struct spi_transfer speed_clk from 42Mhz to 41Mhz
t = {
.tx_buf = buff,
.len = len,
.speed_hz = 41000000, //42000000
};
2 and 3affection: this tests on specified raspberry pi board ok by testing more than 24 hours.
But can not work ok in another raspberry pi 4 board.

Does anyone know something about this, especially for raspberry linux kernel contirbute on spi with DMA module.

@pelwell
Copy link
Contributor

pelwell commented Mar 17, 2021

  1. That's a custom build of a 5.4 kernel. What happens with an official build of rpi-5.10.y?
  2. Which driver are you using?
  3. What is the application driving the interface?

@jiulongshan
Copy link
Author

  1. That's a custom build of a 5.4 kernel. What happens with an official build of rpi-5.10.y?
  2. Which driver are you using?
  3. What is the application driving the interface?

Thank you for reply :
1, we are testing the linux-raspberrypi-kernel_1.20210303-1 tag version , kernel version is 5.10.17.
When I take the modifies on 5.10.17, include enable dtparam=spi_dma4, the system will holt nearly in 1 to 2 hours.
This means the affection of config paramester can not work on 5.10.17, so I must change config.txt and driver clk to default
value.
looks like must disable dtparam=spi_dma4 , and test list is following:
(a) disable spi_dma4 and TFT LCD st7789v driver clk speed_hz is 41Mhz, one device works ok but another device occurs 2 tims timeout error which is system is just on.
(b) disable spi_dma4 and LCD clk is 42Mhz, 2 devices workw fine until now, and the test is going on...

2, the driver is my colleague's output, and the device is ST7789V2.
a part of source code:
static int st7789v_spi_transfer1(struct spi_device *spi, uint8_t * buff, unsigned int len)
{
int status;
struct spi_transfer t = {
.tx_buf = buff,
.len = len,
.speed_hz = 42000000,
};
status = spi_sync_transfer(spi, &t, 1);
if(status < 0){
printk("st7789v_spi_transfer failed, status=%d\n",status);
}else{
printk("st7789v_spi_transfer success\n");
}
return status;
}
#define DMA_DATA_LEN 65532

3, application is decode a gif map to RGB565 to /dev/st7789 device node.
the performance is display rate is 23 ms , corresponding 230 ms or 460 ms with timeout.

@jiulongshan
Copy link
Author

@pelwell update:
Here is up to date brief, my device has spi0 LCD device and i2s audio input/output device.
1,I use 5.10.y kernel, when I disabe i2s, spi0 LCD can work 3 more days alone, and audio device work ok disabe spi0 LCD device.
looks like dma conflicts in the the kernel.

i2s LCD device dts is :
// Overlay to enable brcm SPI controller device and disable virtual SPIDEV device at chip select 0 on Raspberry Pi Platform
// in RPI 1 Model B, microsemi vproc devices uses SPI BUS 0 and CHIP SELECT 0 however current kernel hools a virtual SPIDEV device at both 0 and 1.
// we need to disable that to hook microsemi vproc device at SPI bus 0
/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,bcm2835";
	fragment@0 {
		target = <&soc>;
		__overlay__ {
			spi0: spi@7e204000{
				status = "okay";
			};
		};
	};
	fragment@1 {
		target = <&spi0>;
		__overlay__ {
			spidev@0{
				status = "disabled";
			};
			spidev@1{
				status = "disabled";
			};
		};
	};
	fragment@2 {
		target = <&spi0>;
		__overlay__ {
			#size-cells = <0>;
			#address-cells = <1>;
			st7789v@0 {				
				compatible = "sitronix,st7789v";
				reg = <0>;
				spi-max-frequency = <54000000>;
				status = "okay";
			};
		};
	};	
};

spi0 LCD device dts is :
// Definitions for Microsemi ZL380 Codec and Echo Canceller Device for Raspberry Pi Platform
/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,bcm2835";
	
	fragment@0 {
		target = <&sound>;
		__overlay__ {
			compatible = "microsemi,microsemi-dac";
			i2s-controller = <&i2s>;
			status = "okay";
		};
	};

	fragment@1 {
		target = <&soc>;
		__overlay__ {
			i2s@7e203000{
				status = "okay";
			};
		};
	};

	fragment@2 {
		target = <&soc>;
		__overlay__ {
			zl380-codec {
				compatible = "ms,zl38040", "ms,zl38050", "ms,zl38060", "ms,zl38080";
				status = "okay";
			};
		};
	};
};

2, I add printk info in bcm2835-dma.c, initialized 8 DMA channels and 2 DMA4 channels, but the datasheet describe up-to 16 DMA channels。

3,Do you have any suggestion about this circumstances?

@jiulongshan
Copy link
Author

update:
we have solved this problem. In our st7789v spi driver, struct spi_transfer variable only has this content, and our hard
struct spi_transfer t = {
.tx_buf = buff,
.len = len,
.speed_hz = 42000000,
};
when added .rx_buf = buff, the problem of timeout which is spi tansfers tansmit function info disappear.

@ersincengiz
Copy link

@jiulongshan
I have the same problem but my problem is not solved yet. Can you help with this issue?
I am using Petalinux 2020.2 version. I correctly added it to the device tree.
Device Tree :
`
&spi0 {

is-decoded-cs = <0>;

num-cs = <4>;
status = "okay";
ad7476@0 {
compatible = "adi,ad7476a";
reg = <0>;// 0 yapmayınca görünmüyor
spi-cpha;
spi-cpol;
spi-max-frequency = <10000000>;

};

spidev@0 {
compatible="spidev";
reg = <1>; //chipselect
spi-max-frequency = <1000000>; //5 Mhz

      };

};`

I did as you suggested in the code.

Code :
int ret; uint8_t tx[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D, }; uint8_t rx[ARRAY_SIZE(tx)] = {0, }; struct spi_ioc_transfer tr = { .tx_buf =tx, // or (unsigned long)tx ı tried .rx_buf =0, .len = ARRAY_SIZE(tx), .delay_usecs = delay, .speed_hz = 0, .bits_per_word = 0, };
Error :
`spi mode: 3
bits per word: 8
max speed: 1000000 Hz (1000 KHz)
spidev spi1.1: SPI transfer timed out
spi_master spi1: failed to transfer one message from queue

00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants