msperl / linux-rpi

Other
22 stars 26 forks source link

SPI on BCM2708 with DMA improved and fixed #1

Closed josefpavlik closed 5 years ago

josefpavlik commented 11 years ago

chip select handling on combined DMA and interrupt driven transfers handling flag xfer->cs_change interrupt driver transfer slightly improved DMA transfer longer than 36 bytes bug fixed DMA allows transfers up to 64KB (caller must garantee contignous buffer) DMA should work with LITE channels too

josefpavlik commented 11 years ago

hi Martin Thank you for your great work on DMA driven SPI. I found some problem using it with Raspberry Pi. I found, that transfers longer than 36 bytes does not work because of missing flag in CS register.

I fixed problem with chip select that was deselected between two dma transfers and between combined int and dma transfers. After a lot of desperade tryings I make it via GPIO handling. I don't found a manner to make it by SPI interface. Also, I'm checking the flag 'xfer->cs_change' to allow deselect between certain transfer in one message (my display request it).

I found, that the DMA transfer can begin on any address (does not require any alignment), so I moved the scratch area to the first CB block. I found, that the LITE channels of the BCM does not support 'ignore source' and 'ignore destination', so we need the source or destination address valid, now points to the CB[0]. But I dont test it with one of LITE channels.

I modify the max length of dma transfer too, because I need to transfer about 150KiB 20 times per second and splitting to 4KiB block was slow. I think that the caller should guarantee the continuity of the memory block. If it could not guarantee the contignuos block, it can split it. But if the caller can guarantee it, should have the possibility to transmit the block up to the capability of the hardware (that is 65535 bytes).

One of the last thing that I made was the redesign of the interrupt driven transfer. Sorry, your original version does not worked for me for another reason, so I rewrite it and only after I found the origin of the problem. However I think that this redesigned version is slightly faster, so I leave it. If you want to maintain your version, you must modify it to deselect TA flag after every partial transfer or the sequent DMA transfer will not work.

This version of spi driver works very well on my Raspberry Pi 2 with mio283qt display connected through SPI. Goes at 30MHz (the limit of display is 50MHz, hopelessly the next step of clock is 60MHz) without any clock miss between the bytes. The transfer combines 1 byte (command) sent through interrupt driven transfer and the rest goes through DMA. You can found some latency only between the 64KiB blocks. With the interrupt driven transfer it eats about 60% of CPU time. With DMA about 0% :-). So, thank you one more time :-)

If you have any question about this patch, don't hesitate to contact me. best regards Josef Pavlik

msperl commented 5 years ago

kernel 3.6 is not really supported any longer - the foundation has moved to 4.19.y already. please see if the issues have been fixed there and if not then please upstream those patches yourself. Please note that upstream does not accept a single patch that fixes multiple problems - there should be a separate patch for each separate issue/improvement