int dsp_mailbox_send(struct audiodsp_priv *priv,int overwrite,int num,int cmd,const char *data,int len) { unsigned long flags; int res=-1; struct mail_msg *m; dma_addr_t buf_map; m=&priv->mailbox_reg2[num]; local_irq_save_nort(flags); if(overwrite || m->status==0) { m->cmd=cmd; m->data=(char *)ARM_2_ARC_ADDR_SWAP((unsigned)data); m->len=len; m->status=1; after_change_mailbox(m); if(data!=NULL && len >0) { buf_map = dma_map_single(NULL, (void *)data, len, DMA_TO_DEVICE); dma_unmap_single(NULL, buf_map, len, DMA_TO_DEVICE); } MAIBOX2_IRQ_ENABLE(num); DSP_TRIGGER_IRQ(num); res=0; } local_irq_restore_nort(flags); return res; }
static inline int dsp_set_stream_buffer( struct audiodsp_priv *priv) { dma_addr_t buf_map; if(priv->stream_buffer_mem_size==0) { DSP_WD(DSP_DECODE_OUT_START_ADDR,0); DSP_WD(DSP_DECODE_OUT_END_ADDR,0); DSP_WD(DSP_DECODE_OUT_RD_ADDR,0); DSP_WD(DSP_DECODE_OUT_WD_ADDR,0); return 0; } if(priv->stream_buffer_mem==NULL) priv->stream_buffer_mem=(void*)kmalloc(priv->stream_buffer_mem_size,GFP_KERNEL); if(priv->stream_buffer_mem==NULL) { DSP_PRNT("kmalloc error,no memory for audio dsp stream buffer\n"); return -ENOMEM; } memset((void *)priv->stream_buffer_mem,0,priv->stream_buffer_mem_size); buf_map = dma_map_single(NULL, (void *)priv->stream_buffer_mem, priv->stream_buffer_mem_size, DMA_FROM_DEVICE); dma_unmap_single(NULL, buf_map, priv->stream_buffer_mem_size, DMA_FROM_DEVICE); priv->stream_buffer_start=MAX_CACHE_ALIGN((unsigned long)priv->stream_buffer_mem); priv->stream_buffer_end=MIN_CACHE_ALIGN((unsigned long)priv->stream_buffer_mem+priv->stream_buffer_mem_size); priv->stream_buffer_size=priv->stream_buffer_end-priv->stream_buffer_start; if(priv->stream_buffer_size<0) { DSP_PRNT("Stream buffer set error,must more larger,mensize=%d,buffer size=%ld\n", priv->stream_buffer_mem_size,priv->stream_buffer_size ); kfree(priv->stream_buffer_mem); priv->stream_buffer_mem=NULL; return -2; } DSP_WD(DSP_DECODE_OUT_START_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start)); DSP_WD(DSP_DECODE_OUT_END_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_end)); DSP_WD(DSP_DECODE_OUT_RD_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start)); DSP_WD(DSP_DECODE_OUT_WD_ADDR,ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start)); DSP_PRNT("DSP stream buffer to [%#lx-%#lx]\n",ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_start),ARM_2_ARC_ADDR_SWAP(priv->stream_buffer_end)); return 0; }
static inline int dsp_set_heap( struct audiodsp_priv *priv) { dma_addr_t buf_map; if(priv->dsp_heap_size==0) return 0; if(priv->dsp_heap_start==0) priv->dsp_heap_start=(unsigned long)kmalloc(priv->dsp_heap_size,GFP_KERNEL); if(priv->dsp_heap_start==0) { DSP_PRNT("kmalloc error,no memory for audio dsp dsp_set_heap\n"); return -ENOMEM; } memset((void *)priv->dsp_heap_start,0,priv->dsp_heap_size); buf_map = dma_map_single(NULL, (void *)priv->dsp_heap_start, priv->dsp_heap_size, DMA_FROM_DEVICE); dma_unmap_single(NULL, buf_map, priv->dsp_heap_size, DMA_FROM_DEVICE); DSP_WD(DSP_MEM_START,MAX_CACHE_ALIGN(ARM_2_ARC_ADDR_SWAP(priv->dsp_heap_start))); DSP_WD(DSP_MEM_END,MIN_CACHE_ALIGN(ARM_2_ARC_ADDR_SWAP(priv->dsp_heap_start)+priv->dsp_heap_size)); DSP_PRNT("DSP heap start =%#lx,size=%#lx\n",ARM_2_ARC_ADDR_SWAP(priv->dsp_heap_start),priv->dsp_heap_size); return 0; }
unsigned long dsp_codec_inc_rd_addr(struct audiodsp_priv *priv, int size) { unsigned long rd, flags; local_irq_save(flags); rd = dsp_codec_get_rd_addr(priv); rd = rd + size; if (rd >= priv->stream_buffer_end) { rd = rd - priv->stream_buffer_size; } DSP_WD(DSP_DECODE_OUT_RD_ADDR, ARM_2_ARC_ADDR_SWAP((void*)rd)); local_irq_restore(flags); return rd; }