raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.03k stars 4.96k forks source link

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

Closed jiulongshan closed 3 years ago

jiulongshan commented 3 years ago

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 https://github.com/raspberrypi/linux/issues/3570

System

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 commented 3 years ago
  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 commented 3 years ago
  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 commented 3 years ago

@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 commented 3 years ago

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 commented 2 years ago

@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 `