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.

VDCE driver hangs, ISR sometimes not executed on dm6467

Hi there,

We are having a problem with the VDCE driver that may be the same, or similar, to that described in the post called "vdce/display driver hang on DM6467T":

http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/p/30631/106797.aspx#106797

In our case the "hang" happens after a few minutes converting frames from 422 to 420. We use separate buffers for source and destination. Our system includes VPIF capture, VDCE color conversion, DSP encoding processing and TSIF output data transmission. After some research, we have seen that the problem –at least in our case- is that VDCE IRQ is sometimes not triggered, or at least the vdce_isr() routine is not reached, and the system stalls in:

 

ret = wait_for_completion_interruptible(&(device_config.sem_isr));

 

inside vdce_start() function in davinci_vdce.c.

 

We have traced the following registers trying to get some insight of the behavior of the VDCE hardware and the ARM interruptions architecture:

 

VDCE registers:

-CTRL (VDCE_GO bit)

-INTEN

-INTEN_SET

-INTSTAT

 

ARM registers:

-EINT0 (VDCEINT = 12)

-IRQ0

 

Let’s assume an initial state in which all interrupts are enabled and INTSTAT has just been “manually” cleared (writing “1” to INTEN_CLR).

 

 

Initial state

After

vdce_hw_setup()

After vdce_enable()

After wait_for_completion_interruptible_timeout()

VDCE_GO

0

0

1

0

INTEN

1

1

1

1

INTEN_SET

1

1

1

1

INTSTAT

0

0

0

1

EINT0

0x31c03

0x31c03

0x31c03

0x31c03

IRQ0

0xFFFFFFFF

0xFFFFFFFF

0xFFFFFFFF

0xFFFFFFFF

We used wait_for_completion_interruptible_timeout() to avoid the system to stall inside the completion function, and we traced wether the program has passed through vdce_isr() or not after a timeout exit. In “normal exit” the values of the registers are as in the chart above, and the program goes through vdce_isr(). But when the system gets stalled (or in our case, when the completion is left by timeout) we observe exactly the same values for the registers in the chart above, and the only difference is that the ISR has never been reached. In fact, it is possible to “escape” from the stall (if the timeout is very long) by setting again the “GO” bit to 1 in the CTRL register and start the proccess once more.

 

At this point, we have some questions:

 

-INTSTAT seems not to be cleared anywhere in the original driver, and despite of that, it seems to work in general. Therefore, it seems the VDCE interrupt is edge triggered. But is the VDCEINT (ARM interrupt number 12 in IRQ0) “physically” connected to the INTSTAT bit? Or what exactly is the relationship between INTSTAT and the GO bit in the VDCE driver and the VDCEINT in the ARM? The behavior of INTSTAT seems to be ok (if we clear it to 0 before enabling the GO bit, it becomes 1 again after a frame is processed), but the interruption is not always triggered –or attended-. What can be causing this behavior, either in the VDCE hardware/driver or the Kernel side?

Thanks in advance,

César

  • Hi,

     

    Good catch, driver is not clearing the interrupt and it might create this kind of issue. Can you add it and see if it works?

     

    Thanks,

    Brijesh Jadav

  • On the high level, VDCE IP acts independently of the Interrupt infrastructure, but triggering the interrupt at the completion of the VDCE operation. If the INTSTAT is not cleared, the ISR is not getting triggered , but the operation using the VDCE_GO can still be carried out independently. As Brijesh pointed out, the non-clearing of the INTSTAT might cause driver not getting the ISR.

  • Thanks for your responses,

    Just to clarify a bit: the original driver without any modification works most of the time (even if it does not clear INTSTAT). The problem is that sometimes (say once every few minutes) the ISR is not executed. Either because the "edge" of the interruption is not detected by the operative system, or maybe because it is not even generated. This last option seems to be less probable, beacuse the behavior of INTSTAT and the rest of the registers seems to be ok. But anyway, I would like to know which is the exact signal that the VDCE hardware uses to trigger the IRQ12 in the ARM. Is it the INTSTAT itself? Is it the rising edge of INTSTAT? is it something different, as it appears to be,  since clearing INTSTAT or not does not seem to affect the behavior?

    @Brijesh: if "clearing the interrupt" means writing 1 to INTEN_CLR to clear INTSTAT before activating the GO bit, I already tried it (you can see it in the chart). It is "0" until the VDCE finishes processing, and then it becomes "1". Then I clear it for next frame and so on. But the behavior is the same as if I do not clean it.

    @Manjunath: "If the INTSTAT is not cleared, the ISR is not getting triggered " -> actually, this is not the behavior: in the original driver INTSTAT is not cleared and even so, it works most of the time. In the driver with my modifications the INTSTAT is properly cleared but the behavior seems to be the same (or at least it still fails to execute the ISR from time to time).

    What I am trying to do now is to make the VDCE interruption (number 12) be triggered by level, instead of edge, because maybe the problem is that for some reason (overload or whatever) the system is not detecting the edge of the interruption signal.

    I have modified: arch/arm/mach-davinci/irq.c

    with "set_irq_handler(12, handle_level_irq);"

    and recompiled the kernel, but the behavior of the IRQ is the same as before...

    Any clue how to make this VDCE IRQ line level triggered?

    Thanks,

    César

  • Hello, is there somebody at TI who can help me with those questions about the VDCE in my previous post, or can redirect me to the proper person?

    Thank you,

    César