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.

McBSP freeze on TX enable?

Other Parts Discussed in Thread: OMAP3530

Hi,

I'm writing a device driver for the OMAP3530 (LogicPD Torpedo board) that uses the Linux 2.6.32 McBSP platform driver.  Whenever I bring a transmitter (either McBSP2 or McBSP3) out of reset by writing 1 to SPCR2[0] (XRST), the system appears to hang.  This occurs within the omap_mcbsp_start() function defined in the Linux kernel file arch/arm/plat-omap/mcbsp.c.  It appears that the other registers are configured and the sample rate generator (but not the frame sync generator) has been started; no data has been submitted.  Starting a receiver appears to work, although I don't yet have a way to verify that it is working properly.  What might cause this problem?

Thanks

Michael

 

  • Michael

    I'm not a Linux person but it sounds like the software is in a never ending loop waiting on some event or bit to set/reset?

    Removing the McBSP transmitter from reset should not hang the system. However, normally I do not remove the transmitter reset until I'm ready to send data (master mode).

    Any other clues?

      Paul

  • That's the interesting thing: As far as I can tell, it's not waiting on an event.  This is the code in the platform driver that starts the TX and (as far as I can tell by debugging with printk's) causes the system to hang

        w = OMAP_MCBSP_READ(io_base, SPCR2);
        OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);

    where OMAP_MCBSP_READ and OMAP_MCBSP_WRITE are macros that call __raw_readl and __raw_writel respectively.  It should be noted that the system is not completely dead at that point; I get messages of the form "RCU detected CPU 0 stall (1280 jiffies)" and it's otherwise unresponsive.

    It looks like the platform driver is honoring the programming model set forth in the TRM, which is why this problem confuses me.  Is it possible that I mis-configured the registers in a manner that causes this freeze?  (It still happens if I don't write to the registers in my driver at all, which presumably reveals the default behavior of the platform driver.)  Would this be caused by contention with other drivers trying to use the same underlying device?

    Michael

     

     

  • Michael

    I've not encountered any McBSP programming configurations that would cause a freeze, not at the low level setup anyway.

    Are all the McBSP clocks configured correctly? Can you provide a dump of McBSP regesters prior to removing the reset?

      Paul 

  • Paul,

    Thanks for dropping in.  I may have misunderstood the way the built-in driver (and/or the hardware) was supposed to work.  By putting in some debug print statements I found that the CPU was getting swamped with interrupts.  The platform driver in the kernel uses the legacy TX and RX interrupt lines and I had set RINTM = XINTM = 0b00, so the transmit interrupt is asserted on RRDY (when space was available in the transmit buffer).  I'm not sure why this happens repeatedly, because the TRM says the interrupt is generated when RRDY changes from 0 to 1, not all the time when it is 1.  If I'm observing the latter behavior, this would indicate that the transmitter needs to be started in a separate thread after the buffer is populated with data, and stopped in the interrupt service routine.

    I'm debating whether to write an "overlay" over the existing platform driver that disables the legacy interrupts and uses the "L4-compliant" interrupt line for the types of transfers I need to do.  However, this shouldn't be necessary if I've simply made a mistake in using the existing driver.  What do you think?

    Michael

    PS: Register dump and some debug print output from my attempted omap_mcbsp_start() follows.  This is for McBSP3 (ID = 2) with virtual memory addresses shown (with an integer page offset, so SPCR2 = 0xfb024010 for example).

    Register contents before omap_mcbsp_start() is entered:
      SPCR2 = 0x0100
      SPCR1 = 0x0080
      RCR2 = 0x00a0
      RCR1 = 0x00a0
      XCR2 = 0x00a0
      XCR1 = 0x00a0
      SRGR2 = 0x3fff
      SRGR1 = 0x0001
      MCR2 = 0x0000
      MCR1 = 0x0000
      PCR0 = 0x4a80
      XCCR = 0x0008
      RCCR = 0x0008

    Debug print output:

    Entering omap_mcbsp_start (ID 2 = McBSP3)
    omap_mcbsp_read: READ addr=fb02401c data=0x000000a0
    omap_mcbsp_read: READ addr=fb024024 data=0x000000a0
    omap_mcbsp_read: READ addr=fb024010 data=0x00000100
    omap_mcbsp_read: READ addr=fb024014 data=0x00000080
      Detected idle state 1
    omap_mcbsp_read: READ addr=fb024010 data=0x00000100
    omap_mcbsp_write: WRITE addr=fb024010 data=0x00000140
      Started SRG
      About to read SPCR1
    omap_mcbsp_read: READ addr=fb024014 data=0x00000080
      Read SPCR1 = 0x0080
      Writing SPCR1 = 0x0080
    omap_mcbsp_write: WRITE addr=fb024014 data=0x00000080
      Didn't enable RX
    omap_mcbsp_read: READ addr=fb024010 data=0x00000140
    omap_mcbsp_write: WRITE addr=fb024010 data=0x00000141
    Entering omap_mcbsp_tx_irq_handler
    omap_mcbsp_read: READ addr=fb024010 data=0x00000143
    Entering omap_mcbsp_tx_irq_handler
    omap_mcbsp_read: READ addr=fb024010 data=0x00000143
    Entering omap_mcbsp_tx_irq_handler
    omap_mcbsp_read: READ addr=fb024010 data=0x00000143
    Entering omap_mcbsp_tx_irq_handler
    omap_mcbsp_read: READ addr=fb024010 data=0x00000143
    Entering omap_mcbsp_tx_irq_handler
    omap_mcbsp_read: READ addr=fb024010 data=0x00000143

    [this continues repeatedly even though no data is being sent...]

  • Also, to answer your question about the clocks: I don't know, I'm relying on the platform driver to set up the clocks and don't have the ability to probe internal signals.  In my experiments the CLKX pin remains high at all times... is the pin is only driven when the transmitter is active?

    Michael

     

     

  • I tried writing some of my own functions yesterday to use the "new" interrupt line instead of the "legacy" interrupt lines.  I found basically the same behavior: the XRDY interrupt is fired repeatedly, even though I'm writing back to the status register and there doesn't seem to be a change of state.   I was able to prevent the lockups and transmit individual words by disabling the interrupt at the end of the interrupt handler, but I'm guessing this isn't the desired behavior.

    Michael

  • Another oddity to point while I'm thinking of it: The CLKX, FSX and DX lines on the transmitting McBSP appear logically correct, but the frame sync pulses have lower amplitude (0.8 V instead of 1.8 V).  What might cause this?  I wonder if it might have something to do with the inability of another McBSP to receive the data I'm sending.

    Michael

  • Michael

    Sounds like there is contention on the FSX signal, Check for an incorrect connection, a short to another signal, or if the target device is also driving the signal. This will definitely affect the ability of other devices to see valid frame syncs.

      Paul

  • Michael Hello,

     

    I have same problem with omap_mcbsp_start() that stack the kernel

    Do you have any solution to this problem?

     

    Thanks

    David O