David Brownell wrote:
On Monday 26 January 2009, Brian G Rhodes wrote:
I think someone forgot an 'I' in edma_stop. Writing to ECR seems
pointless to me. I am assuming they meant to do SH_IECR instead of
SH_ECR. This also happens to fix the problem I was having with audio
stalls on dm6446.
ECR == Event Clear Register, scrubbing out pending events
IECR == Interrupt Enable Clear Register, disabling completion IRQs
Wouldn't it make sense to clear *both*?
I guess the theory here is that an IRQ would sometimes trigger
because the TC was busy with a transfer when edma_stop() was
called, so the audio driver got called and then updated the
reload slot ... causing the "stall". Yes?
However, you're then relying on something to release the
channel and then re-acquire it after edma_stop(), since
IESR (Interrupt Enable Set Register) is only written in
edma_alloc_channel(). That seems likely to break any
EDMA user (say, MMC) that doesn't constantly re-alloc
the channels but still relies on completion IRQs (unlike
MMC).
I see what you are saying here now, and the ASoC driver is calling
edma_free_channel which should clear the interrupt enable for ASP, so
that is being toggled correctly on free and the subsequent alloc. I do
suspect that something is _pending_ when stop is being called. When the
condition occurs ESR is not set, while EER is. Writing 0x4 to ESR
(which is the current value in EER) does start audio playback. I'm
trying to understand the relation between these two registers. There is
some information in the EDMA datasheet regarding the ESR register, but
nothing which directly points to the problem here. I would expect
something in EMR when this occurs based on that information.
Thanks
edma.patch
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 898eb02..557da31 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -1077,10 +1077,11 @@ void edma_stop(unsigned channel)
unsigned int mask = (1 << (channel & 0x1f));
edma_shadow0_write_array(SH_EECR, j, mask);
- edma_shadow0_write_array(SH_ECR, j, mask);
+ edma_shadow0_write_array(SH_IECR, j, mask);
edma_shadow0_write_array(SH_SECR, j, mask);
edma_write_array(EDMA_EMCR, j, mask);
-
+ edma_write_array(EDMA_EEVAL, j, mask);
This EEVAL write looks wrong. Only BIT(0) is valid,
and zeroing it is a NOP. What were you trying to do?
I believe I was looking at setting IEVAL here initially and through
different tests that code leaked through. Or I just completely
misinterpreted something. Jumping back between 2 datasheets becomes
quite tedious, and I'm horribly prone to making stupid mistakes.
_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source