int mailbox_send_audiodsp(int overwrite,int num,int cmd,const char *data,int len) { int res = -1; int time_out = 0; if(DSP_RD(DSP_STATUS) != DSP_STATUS_RUNING){ printk("fatal error,dsp must be running before mailbox sent\n"); return -1; } DSP_WD(DSP_GET_EXTRA_INFO_FINISH, 0); while(time_out++ < 10){ if((num == M2B_IRQ0_DSP_AUDIO_EFFECT) && (cmd == DSP_CMD_SET_HDMI_SR)){ hdmi_sr = *(unsigned int *)data; DSP_PRNT("<hdmi to dsp mailbox> sr changed to %d\n",hdmi_sr); DSP_WD(DSP_HDMI_SR,hdmi_sr); res = dsp_mailbox_send(audiodsp_privdata(),overwrite,num,cmd,(char*)&hdmi_sr,sizeof(unsigned int)); return res; } else{ res = dsp_mailbox_send(audiodsp_privdata(),overwrite,num,cmd,data,len); msleep(10); } if(DSP_RD(DSP_GET_EXTRA_INFO_FINISH) == 0x12345678) break; } if(time_out == 10){ printk("error,dsp transfer mailbox time out\n"); return -1; } return res; }
void reset_dsp( struct audiodsp_priv *priv) { halt_dsp(priv); //flush_and_inv_dcache_all(); /* map DSP 0 address so that reset vector points to same vector table as ARC1 */ CLEAR_MPEG_REG_MASK(AUD_ARC_CTL, (0xfff << 4)); // SET_MPEG_REG_MASK(SDRAM_CTL0,1);//arc mapping to ddr memory SET_MPEG_REG_MASK(AUD_ARC_CTL, ((AUDIO_DSP_START_PHY_ADDR)>> 20) << 4); // decode option if(IEC958_mode_codec){ if(IEC958_mode_codec == 4){//dd+ DSP_WD(DSP_DECODE_OPTION, decopt|(3<<30)); }else{ DSP_WD(DSP_DECODE_OPTION, decopt|(1<<31));//dd,dts } } else{ DSP_WD(DSP_DECODE_OPTION, decopt&(~(1<<31))); } printk("reset dsp : dec opt=%x\n", DSP_RD(DSP_DECODE_OPTION)); if(!priv->dsp_is_started){ DSP_PRNT("dsp reset now\n"); enable_dsp(1); } else{ dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_WAKEUP,0,0,0); DSP_WD(DSP_STATUS, DSP_STATUS_WAKEUP); msleep(1);/*waiting arc625 run again */ } return; }
int dsp_start( struct audiodsp_priv *priv, struct audiodsp_microcode *mcode) { int i; int res; mutex_lock(&priv->dsp_mutex); halt_dsp(priv); if(priv->stream_fmt!=priv->last_stream_fmt) // remove the trick, bug fixed on dsp side { if(audiodsp_microcode_load(audiodsp_privdata(),mcode)!=0) { printk("load microcode error\n"); res=-1; goto exit; } priv->last_stream_fmt=priv->stream_fmt; } if((res=dsp_set_stack(priv))) goto exit; if((res=dsp_set_heap(priv))) goto exit; if((res=dsp_set_stream_buffer(priv))) goto exit; if(!priv->dsp_is_started) reset_dsp(priv); else{ dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_WAKEUP,0,0,0); msleep(1);/*waiting arc625 run again */ } priv->dsp_start_time=jiffies; for(i=0;i<1000;i++) { if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING) break; msleep(1); } if(i>=1000) { DSP_PRNT("dsp not running \n"); res=-1; } else { DSP_PRNT("dsp status=%lx\n",DSP_RD(DSP_STATUS)); priv->dsp_is_started=1; res=0; } exit: mutex_unlock(&priv->dsp_mutex); return res; }
void halt_dsp( struct audiodsp_priv *priv) { int i; if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING) { #ifndef AUDIODSP_RESET dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_SLEEP,0,0,0); for(i = 0; i< 100;i++) { if(DSP_RD(DSP_STATUS)== DSP_STATUS_SLEEP) break; msleep(1);/*waiting arc2 sleep*/ } if(i == 100) DSP_PRNT("warning: dsp is not sleeping when call dsp_stop\n"); #else dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_HALT,0,0,0); msleep(1);/*waiting arc2 sleep*/ #endif } #ifdef AUDIODSP_RESET if(DSP_RD(DSP_STATUS)!=DSP_STATUS_RUNING) { DSP_WD(DSP_STATUS, DSP_STATUS_HALT); return ; } #endif if(!priv->dsp_is_started){ enable_dsp(0);/*hardware halt the cpu*/ DSP_WD(DSP_STATUS, DSP_STATUS_HALT); priv->last_stream_fmt=-1;/*mask the stream format is not valid*/ } else DSP_WD(DSP_STATUS, DSP_STATUS_SLEEP); }
int audiodsp_start(void) { struct audiodsp_priv *priv=audiodsp_privdata(); struct audiodsp_microcode *pmcode; struct audio_info *audio_info; int ret,i; priv->frame_format.valid=0; priv->decode_error_count=0; priv->last_valid_pts=0; priv->out_len_after_last_valid_pts = 0; priv->decode_fatal_err = 0; priv->first_lookup_over = 0; pmcode=audiodsp_find_supoort_mcode(priv,priv->stream_fmt); if(pmcode==NULL) { DSP_PRNT("have not find a valid mcode for fmt(0x%x)\n",priv->stream_fmt); return -1; } stop_audiodsp_monitor(priv); dsp_stop(priv); ret=dsp_start(priv,pmcode); if(ret==0){ start_audiodsp_monitor(priv); #ifdef CONFIG_AM_VDEC_REAL if((pmcode->fmt == MCODEC_FMT_COOK) || (pmcode->fmt == MCODEC_FMT_RAAC) || (pmcode->fmt == MCODEC_FMT_AMR) || (pmcode->fmt == MCODEC_FMT_WMA) || (pmcode->fmt == MCODEC_FMT_ADPCM)|| (pmcode->fmt == MCODEC_FMT_PCM) || (pmcode->fmt == MCODEC_FMT_WMAPRO)|| (pmcode->fmt == MCODEC_FMT_ALAC)|| (pmcode->fmt & MCODEC_FMT_AC3) || (pmcode->fmt & MCODEC_FMT_EAC3) || (pmcode->fmt == MCODEC_FMT_APE) || (pmcode->fmt == MCODEC_FMT_FLAC)) { DSP_PRNT("dsp send audio info\n"); for(i = 0; i< 2000;i++){ if(DSP_RD(DSP_AUDIOINFO_STATUS) == DSP_AUDIOINFO_READY)//maybe at audiodsp side,INT not enabled yet,so wait a while break; msleep(1); } if(i == 2000) DSP_PRNT("audiodsp not ready for info \n"); DSP_WD(DSP_AUDIOINFO_STATUS,0); audio_info = get_audio_info(); DSP_PRNT("kernel sent info first 4 byte[0x%x],[0x%x],[0x%x],[0x%x]\n\t",audio_info->extradata[0],\ audio_info->extradata[1],audio_info->extradata[2],audio_info->extradata[3]); DSP_WD(DSP_GET_EXTRA_INFO_FINISH, 0); while(1){ dsp_mailbox_send(priv, 1, M2B_IRQ4_AUDIO_INFO, 0, (const char*)audio_info, sizeof(struct audio_info)); msleep(100); if(DSP_RD(DSP_GET_EXTRA_INFO_FINISH) == 0x12345678) break; } } #endif } return ret; }
int dsp_codec_stop(struct audiodsp_priv *priv) { return dsp_mailbox_send(priv, 1, M2B_IRQ3_DECODE_STOP, 0, 0, 0); }
int dsp_codec_start(struct audiodsp_priv *priv) { return dsp_mailbox_send(priv, 1, M2B_IRQ2_DECODE_START, 0, 0, 0); }