This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

spi-omap2-mcspi hangs when DMA and PIO are used simultaneously

This is a question that I posted on linux-spi and I am posting here to see if I can get some help or direction to try to fix by myself.

I am using spi-omap2-mcspi to drive a network card based on enc28j60 and everything works perfect if I define
DMA_MIN_BYTES = 0 (force to use DMA only) or DMA_MIN_BYTES = 99999 (force to use PIO only).
But if I use the original value of 160, the board can send out 10 to 20 pings approximately
and if any time the drive switch from PIO to DMA what will be decided by the size of data,
some workqueue tasks hung and the card stops.

I am using the kernel 3.13.6 patched to beaglebone and did test also with the mainline 3.14.0 and the problem is exactly the same.

I am running with "lockdep" and "detect hung tasks" and I can see that four tasks are stopped,
three from enc28j60 and one from spi-omap2-mcspi.

The mcspi is stopped in spi-omap2.mcspi.c:480 to wait the completion of omap2_mcspi_rx_callback
that it never happens.

 

   468                 if (tx) {
   469                         tx->callback = omap2_mcspi_rx_callback;
   470                         tx->callback_param = spi;
   471                         dmaengine_submit(tx);
   472                 } else {
   473                                 /* FIXME: fall back to PIO? */
   474                 }
   475         }
   476
   477         dma_async_issue_pending(mcspi_dma->dma_rx);
   478         omap2_mcspi_set_dma_req(spi, 1, 1);
   479
   480         wait_for_completion(&mcspi_dma->dma_rx_completion);
   481         dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
   482                          DMA_FROM_DEVICE);

Any help/suggestion is welcome. Need more information, please let me know, I have more details.

Thank you.


  • Hi Jorge,

    This forum supports only the TI distributed Linux SDK, which currently is based on kernel v3.12. For all other versions please turn to the community on http://beagleboard.org/Community/Forums

  • Hi Biser

    Thank you for your reply, I will repeat my tests using the TI distribution v3.12 to check if I don't get the same.

    Thank you.

  • I got more inconsistency with the version 3.12. The driver spi_omap2_mcspi it's not reading the device tree configuration node for enc28j60; not doing that the module doesn't get the GPIO1_15 interrupt mapped and of course nothing works.

    Unfortunately I can't do any contribution to this problem.

  • For your SPI problem, read this:

    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/321533.aspx

  • Hi Wolfgang,

    Thank you very much to give me that direction. I am definitively convinced that has relation with the problem I am experimenting. I have to read several times very carefully to try to figure out the effect I am observing. Maybe my case can put some light into this problem.

    One interesting point is that; I am not observing any problem when I use DMA only or PIO only but the transmission stops when the drive switches from PIO to DMA.


    I think that maybe a good idea to post my information at the tail of that thread... Maybe that gives some clue to the guys.

  • Hi Wolfgang,

    This message is just to give a conclusion in my original post. Since your last pointer I decided to go deep to figure out if there was a problems with the drive spi_omap2_mcspi and here is the results.

    I connected one beaglebone as the spi master to an Arduino uno as slave; doing that I can have serial terminals at both sides so that I can see everything. In the middle I have a logic analyzer to confirm that what I am reading at the terminals is exactly what I can see in the display of logic analyzer for both directions. I didn't find anything wrong!

    There is only one detail that I supposed has to be handled by the application: The first byte I received back from a block transfer was always the last byte from the block received before. This is at least consistent with the way that the Arduino SPI works and maybe it's not something general but from the perspective of beaglebone everything was correct.

    Another check that I did was a stress test making transitions from PIO to DMA and from DMA to PIO sending blocks of two different sizes and again everything works perfectly. This eliminates completely the drive spi_opmp2_mcspi as the originator of the problem I am having with the network card enc28j60. The problem has to be in the enc28j60 driver itself.

    Ventura

  • Hi ,

    I am using 3.12 TI linux Kernel,and want to use DMA in SPI . I saw this post and I realized that I am exactly in the situation that you guys where . When I try to use spi_sync from my driver with len=200 and word len = 24 , my mcspi driver hangs at wait_for_completion(&mcspi_dma->dma_rx_completion); .It is not not even calling static void omap2_mcspi_rx_callback(void *data) function . I know you guys had a good discussion regarding this some times back. So I wanted to know how did this get resolved ? . Is it a bug in spi-omap2-mcspi.c file or its some configuration issue from my driver side ?

    Thanks
    rahul