Subject: Assabet UDA1341/DMA patch

From: Tak-Shing Chan <[email-masked]>
Date: Mon, 19 Jun 2000 19:42:27 +0800 (CST)

Hi Nicolas,

     I found that your UDA1341 output is shaking at a steady
frequency (it's been there since 2.3.99pre-kernels).  Here's
the patch:

Tak-Shing Chan

--- /usr/src/linux-2.4.0-test1-ac19-rmk1-np1/arch/arm/kernel/dma-sa1100.c.orig	Mon Jun 19 10:44:21 2000
+++ /usr/src/linux-2.4.0-test1-ac19-rmk1-np1/arch/arm/kernel/dma-sa1100.c	Mon Jun 19 17:33:07 2000
@@ -110,13 +110,13 @@
 	if( use_bufa ){
 		DMA->ClrDCSR = DCSR_DONEA|DCSR_STRTA;
 		DMA->DBSA = dma_ptr;
-		DMA->DBTA = size-1;
+		DMA->DBTA = size;
 		DMA->SetDCSR = DCSR_STRTA|DCSR_IE|DCSR_RUN;
 		DPRINTK(" with a\n");
 	}else{
 		DMA->ClrDCSR = DCSR_DONEB|DCSR_STRTB;
 		DMA->DBSB = dma_ptr;
-		DMA->DBTB = size-1;
+		DMA->DBTB = size;
 		DMA->SetDCSR = DCSR_STRTB|DCSR_IE|DCSR_RUN;
 		DPRINTK(" with b\n");
 	}

--- /usr/src/linux-2.4.0-test1-ac19-rmk1-np1/drivers/sound/sa1100-uda1341.c.orig	Mon Jun 19 10:44:21 2000
+++ /usr/src/linux-2.4.0-test1-ac19-rmk1-np1/drivers/sound/sa1100-uda1341.c	Mon Jun 19 19:40:09 2000
@@ -272,7 +272,8 @@
 #define AUDIO_CHANNELS_DEFAULT	2
 #define AUDIO_RATE_DEFAULT	44100
 #define AUDIO_NBFRAGS_DEFAULT	8
-#define AUDIO_FRAGSIZE_DEFAULT	8192
+#define AUDIO_FRAGSIZE_DEFAULT	4096
+#define AUDIO_DMA_OVERSHOOT	64

 /* 
@@ -546,7 +547,7 @@
 			output_stream.dma_spin = 0;
 		}
 		if( s->dma_spin ){
-			while( sa1100_start_dma(s->DMA, (void*)FLUSH_BASE_PHYS, MAX_DMA_SIZE) == 0 )
+			while( sa1100_start_dma(s->DMA, (void*)FLUSH_BASE_PHYS, MAX_DMA_SIZE-AUDIO_DMA_OVERSHOOT) == 0 )
 				s->dma_spin_ref++;
 		}
 		break;
@@ -556,7 +557,7 @@
 	 * Let's try to start DMA on the current buffer.  
 	 * If no DMA is available then we stop here.
 	 */
-	chunksize = (b->size < MAX_DMA_SIZE) ? b->size : MAX_DMA_SIZE;
+	chunksize = (b->size < MAX_DMA_SIZE-AUDIO_DMA_OVERSHOOT) ? b->size : MAX_DMA_SIZE-AUDIO_DMA_OVERSHOOT;
 	DPRINTK("DMA buf %d (%d) chnk %d\n", s->dma_head_idx, b->ref, chunksize);
 	if( sa1100_start_dma( s->DMA, b->ptr, chunksize ) != 0 ){
 		DPRINTK("DMA busy\n");
@@ -1091,7 +1092,7 @@
 static inline void audio_ssp_init( void )
 {
 	/* Setup the uarts */
-	PPAR |= PPC_TXD4;
+	PPAR |= PPAR_SPR;
 	GAFR |= (GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | 
 		 GPIO_SSP_SFRM | GPIO_SSP_CLK);
 	GPDR |= (GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM );

unsubscribe: body of `unsubscribe linux-arm-kernel' to [email-masked]

---

From: Nicolas Pitre <[email-masked]>
Date: Mon, 19 Jun 2000 10:01:42 -0400 (EDT)

> frequency (it's been there since 2.3.99pre-kernels).  Here's

However you're limitting the DMA buffer to 4096 bytes which might be quite
small, especially if the system is under heavy load.

The SA1100 manual explictly says that the DMA count register is 13 bit
wide for a maximal DMA size of 8192 bytes, which is highly adviseable for
audio.  However 13 bits can represent a max value of 0x1fff i.e. 8191.
Since most registers on the SA1100 are defined as reg = value - 1, I
though it was the case for the DMA too, although it is not strictly
mentionned for the DMA count reg.  What I've noticed though is that even
if you specify 0 for the DMA count reg, you'll get at least one datum
through the DMA engine which tend to confirm the -1 guess.

Anybody can confirm this?

Nicolas

---

From: Tak-Shing Chan <[email-masked]>
Date: Tue, 20 Jun 2000 11:44:08 +0800 (CST)

Nicolas,

     I think that involves two things.  First, regarding the
meaning of DBTA--from repeated listening experiments (from 4096
to 8176) I'm positive that it's value and not value-1.  The
result of missing samples in digital recordings are just too
obvious...  [by the way 11.6.1.4 says TCA is in bytes.]

     Second, isn't the extra datum you detected caused by DMA
overshoot (and the value is supposed to be fetched and ignored)?
My patch explicitly takes DMA overshoot into account.

     It seems like it's safe to specify AUDIO_DMA_OVERSHOOT as 16
and AUDIO_FRAGSIZE_DEFAULT as 8176.  Any confirmations?  IMHO
8176 is big enough for most purposes.  Meanwhile 64 and 4096 are
``failsafe'' values but not optimal.

Tak-Shing Chan

---

From: Tak-Shing Chan <[email-masked]>
Date: Tue, 20 Jun 2000 16:19:00 +0800 (CST)

Hi Nicolas,

     AUDIO_DMA_OVERSHOOT=2 and AUDIO_FRAGSIZE_DEFAULT=8190 works
fine.  Another observation: odd fragsizes break things (the last
16-bit sample became 8-bit).  It looks like DMA overshoot is not
a problem at all because 8190 is the biggest possible even number.
Maybe renaming AUDIO_DMA_OVERSHOOT to AUDIO_EVEN_HACK is a better
idea.  ;)

     Results so far:
     * Odd fragsizes with tca=size-1 : failed
     * Even fragsizes with tca=size-1: failed
     * Odd fragsizes with tca=size   : failed
     * Even fragsizes with tca=size  : passed
     * Valid fragsize range          : 4096-8190

Tak-Shing Chan

---

From: Nicolas Pitre <[email-masked]>
Date: Tue, 20 Jun 2000 10:09:48 -0400 (EDT)

> 16-bit sample became 8-bit).  It looks like DMA overshoot is not

That one is easy since audio fragment sizes should always be a power of 2
for buffering efficiency.  Sometimes a fragment might not be full, but
samples are always 16-bit so no odd-size fragments should happen.

Nicolas