Monday, September 16, 2013

DWC USB interrupt spam in Rockchip SoCs

Some time ago, when looking for answers to some USB 1.1 problems on the RK chips, like:
- USB 1.1 to Ethernet dongle not working
- Repeated or missing key presses
I stumbled upon some Raspberry Pi forums complaining about the same things.

This is logical since both the Rasp. Pi SoC and the RK3066/3188 are using the same USB HW IP cores (from DesignWare, that is DWC).

One of the problems they were reporting was an excessive number of interrupts per second coming from the USB while the system was idle (I've confirmed it, even with just a USB 1.1 keyboard attached).

One way to check this is with the console command:
vmstat 1
Looking below label "in" will tell you how many interrupts are there per second. In my case, Linux3188 kernel ( ) on a RK3188 Cozyswan S400 (kindly donated by KSK Electrics) the result is some 10600 interrupts per second.

And a way to see who is interrupting is simply to type:
cat /proc/interrupts
In my case, the "dwc_otg_hcd:usb1, dwc_otg_pcd" is the root cause for some more than 8000 interrupts per second, just as it happens to RPi guys.

The problem seems to stem from the DWC driver, as explained here:
"the Synopsys driver relies on the start of frame interrupt for scheduling transfers if "descriptor DMA" is not implemented (which it isn't, on BCM2835).  8000 is one interrupt per microframe."
and propose the use of a FIQ (ARM fast interrupt handler) for USB IRQs to discard USB microframes that contain no data. More info here...

And the FIQ enabled code lies in this repo (see commits starting in April 2013 by Gordon Hollingworth):


  1. RK3066, cat /proc/interrupts
    49: 1440806 GIC dwc_otg, host20_hcd:usb2
    1440806 interrupts per second !!!

    1. hehe, do the cat, wait 10 secs, and do it again, substract and divide by 10, that's your ints/sec.

      The RPi fixes didn't seem to be conclusive and 8K ints per second is not that terrible in total system performance.