Jerry Johns wrote:
> Hey Troy,
> 
>               Thanks for the patches, and you're most probably correct
> in the DDR latencies being the cause of the sample drops - the patches
> look like their fixing the alsa code in the git tree - do you have an
> equivalent patch for the 1.30 DVSDK? (the davinci-audio-aic33.c,
> -dma-intfc.c and davinci-audio.c files)
> 
>  
> 
> Thanks a ton,
> 
>  
> 
> Jerry Johns
You might try replacing with these routines in dma-intfc.c
No warranties implied.

#define IRAM_RESERVED 32
#define IRAM_SIZE 0x4000        //16k in ram0/1 combination
#define IRAM_LEFT (IRAM_SIZE-IRAM_RESERVED)

char *          iram_dmabuf;
dma_addr_t      iram_dmaphys;
int                     iram_dmasize;
extern char* g_DavinciIRam;

int audio_setup_buf(audio_stream_t * s)
{
        int max;
        int frag;
        int dmasize = 0;
        char *dmabuf = NULL;
        dma_addr_t dmaphys = 0;
        audio_buf_t *b;
        FN_IN;

        if (s->buffers) {
                FN_OUT(1);
                return -EBUSY;
        }

        /* Allocate memory for all buffer fragments */
        s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
        if (!s->buffers)
                goto err;
        /* Initialise all the memory to 0 */
        memset(s->buffers, 0, sizeof(audio_buf_t) * s->nbfrags);

        if (iram_dmabuf==NULL) {
                /* For allocating the IRAM memory */
                iram_dmabuf = (char*)(g_DavinciIRam+IRAM_RESERVED);
                iram_dmaphys = (dma_addr_t)(DAVINCI_IRAM_BASE+IRAM_RESERVED);
                iram_dmasize = (IRAM_LEFT);
        }
        max = (s->nbfrags*s->fragsize);
        dmaphys = iram_dmaphys;
        dmabuf = iram_dmabuf;
        dmasize = (iram_dmasize) - (iram_dmasize % s->fragsize);
        if (dmasize > max) dmasize = max;
        iram_dmabuf += dmasize;
        iram_dmaphys += dmasize;
        iram_dmasize -= dmasize;

        b = &s->buffers[0];
        b->master = dmasize;
        if (dmasize) memzero(dmabuf, dmasize);


        for (frag = 0; frag < s->nbfrags; frag++) {
                b = &s->buffers[frag];

                /*
                 * Let's allocate non-cached memory for DMA buffers.
                 * We try to allocate all memory at once.
                 * If this fails (a common reason is memory fragmentation),
                 * then we allocate more smaller buffers.
                 */
                if (!dmasize) {
                        dmasize = (s->nbfrags - frag) * s->fragsize;
                        do {
                                /* allocate consistent memory for DMA
                                   dmaphys(handle)= device viewed address.
                                   dmabuf = CPU-viewed address */
                                dmabuf = dma_alloc_coherent(NULL, dmasize, 
&dmaphys,0);
                                if (!dmabuf) dmasize -= s->fragsize;
                        } while (!dmabuf && dmasize);

                        if (!dmabuf)
                                goto err;

                        b->master = dmasize;
                        memzero(dmabuf, dmasize);
                }
                b->data = dmabuf;
                b->dma_addr = dmaphys;
                dmabuf += s->fragsize;
                dmaphys += s->fragsize;
                dmasize -= s->fragsize;
        }
        s->usr_head = s->dma_head = s->dma_tail = 0;
        AUDIO_QUEUE_INIT(s);
        s->started = 0;

        s->dma_started = 0;
        s->bytecount = 0;
        s->doneByteCnt = 0;
        s->lastDoneByteCnt = 0;
        s->fragcount = 0;
        s->prevbuf = 0;

        init_completion(&s->wfc);
        s->wfc.done = s->nbfrags;

        FN_OUT(0);
        return 0;
      err:
        audio_discard_buf(s);
        FN_OUT(1);
        return -ENOMEM;
}

void audio_discard_buf(audio_stream_t * s)
{
        FN_IN;
        /* ensure DMA isn't using those buffers */
        audio_reset(s);
        if (s->buffers) {
                int frag;
                for (frag = 0; frag < s->nbfrags; frag++) {
                        char *dmabuf;
                        int dmasize = s->buffers[frag].master;
                        if (!dmasize) continue;
                        dmabuf = s->buffers[frag].data;
                        if ( (dmabuf >= ((char*)(g_DavinciIRam+IRAM_RESERVED))) 
&&
                                 (dmabuf <  ((char*)(g_DavinciIRam+IRAM_SIZE))) 
) {
                                //fixme, this should work as long as things are 
freed in reserve order
                                //or all of iram is freed before reallocating 
any
                                iram_dmabuf -= dmasize;
                                iram_dmaphys -= dmasize;
                                iram_dmasize += dmasize;
                        } else {
                                
dma_free_coherent(NULL,dmasize,dmabuf,s->buffers[frag].dma_addr);
                        }
                }
                kfree(s->buffers);
                s->buffers = NULL;
        }
        FN_OUT(0);
}




_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to