USB isochronous traffic with Rasberry Pi [WAS: Re: USB audio device on Raspberry Pi]
Hans Petter Selasky
hps at selasky.org
Sat May 10 13:50:01 UTC 2014
On 05/10/14 14:24, Ian Lepore wrote:
> On Sat, 2014-05-10 at 09:51 +0200, Hans Petter Selasky wrote:
>> Hi,
>>
>> I've made one more patch to the DWC OTG driver. Nice if you can test
>> that too.
>>
>> http://svnweb.freebsd.org/changeset/base/265806
>>
>> BTW: I think I've found what is causing the glitches when using USB
>> audio devices:
>>
>> diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
>> index 0490be7..de7f015 100644
>> --- a/sys/arm/arm/machdep.c
>> +++ b/sys/arm/arm/machdep.c
>> @@ -423,7 +423,7 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
>> void
>> cpu_idle(int busy)
>> {
>> -
>> +#if 0
>> CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
>> busy, curcpu);
>> #ifndef NO_EVENTTIMERS
>> @@ -442,6 +442,7 @@ cpu_idle(int busy)
>> #endif
>> CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",
>> busy, curcpu);
>> +#endif
>> }
>>
>> int
>>
>>
>> It appears that cpu_idle() is going to sleep when there are pending
>> interrupts, and then waking up on the next timer IRQ! Can someone
>> familiar with these parts of the kernel comment?
>>
>> Please try for yourself, with and without the patch above, using an USB
>> audio device with the RPI-B!
>>
>> Still when the console is printing, there are significant glitches too
>> :-) That's because the TTY layer is synchronously writing data to the
>> serial line. That's OK for now.
>>
>> --HPS
>
> If there's an interrupt pending when the WaitForInterrupt instruction is
> executed, the cpu doesn't go to sleep -- it acts like a nop. I think
> the problem might be that the device write that re-enables the interrupt
> hasn't yet made it to the device when the cpu clock stops.
>
> I don't have any usb audio gear to test with, could you please test the
> attached patch and see if it fixes the glitches?
>
> -- Ian
>
Hi,
That code is not used with RPI so it makes no difference. I think we
need to do something like they are doing on x86, that the interrupts are
enabled the instruction before the sleep instruction. Else we can loose
interrupts. Can you write me a correct patch which implements that?
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 0490be7..5e43c14 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -423,6 +423,7 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
void
cpu_idle(int busy)
{
+ register_t s;
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
busy, curcpu);
@@ -432,8 +433,11 @@ cpu_idle(int busy)
cpu_idleclock();
}
#endif
- if (!sched_runnable())
- cpu_sleep(0);
+ s = intr_disable();
+ if (sched_runnable())
+ intr_restore(s);
+ else
+ cpu_sleep(0, s);
#ifndef NO_EVENTTIMERS
if (!busy) {
cpu_activeclock();
--- a/sys/arm/arm/cpufunc_asm_arm11x6.S
+++ b/sys/arm/arm/cpufunc_asm_arm11x6.S
@@ -207,16 +207,21 @@ END(arm11x6_idcache_wbinv_range)
ENTRY_NP(arm11x6_sleep)
mov r0, #0
- mov r1, #2
-1:
- subs r1, #1
+// mov r1, #2
+//1:
+// subs r1, #1
nop
mcreq p15, 0, r0, c7, c10, 4 /* data sync barrier */
+ mrs r1, cpsr
+// mov r1, #2
+//1:
+// subs r1, #1
nop
mcreq p15, 0, r0, c7, c10, 4 /* data sync barrier */
+ mrs r1, cpsr
+ orr r1, r1, #(I32_bit|F32_bit)
+ eor r1, r1, #(I32_bit|F32_bit)
+ msr cpsr_c, r1 /* enable interrupts right before waiting */
+
mcreq p15, 0, r0, c7, c0, 4 /* wait for interrupt */
nop
nop
nop
- bne 1b
+// bne 1b
RET
END(arm11x6_sleep)
--HPS
More information about the freebsd-arm
mailing list